> compile NEMU
221220000 张三 Linux zzy 5.15.146.1-microsoft-standard-WSL2 #1 SMP Thu Jan 11 04:09:03 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux 21:39:11 up 20:29, 1 user, load average: 0.31, 0.25, 0.18
This commit is contained in:
@ -20,15 +20,21 @@
|
||||
*/
|
||||
#include <regex.h>
|
||||
|
||||
#include <memory/vaddr.h>
|
||||
#include <limits.h>
|
||||
|
||||
enum {
|
||||
TK_NOTYPE = 256, TK_EQ,
|
||||
TK_DEC,
|
||||
TK_NOTYPE = 256,
|
||||
TK_EQ,
|
||||
TK_NEQ,
|
||||
TK_AND,
|
||||
|
||||
TK_NEG,
|
||||
|
||||
/* TODO: Add more token types */
|
||||
|
||||
TK_DEC,
|
||||
|
||||
TK_HEX,
|
||||
TK_REG,
|
||||
TK_DEREF,
|
||||
};
|
||||
|
||||
static struct rule {
|
||||
@ -36,13 +42,11 @@ static struct rule {
|
||||
int token_type;
|
||||
} rules[] = {
|
||||
|
||||
/* TODO: Add more rules.
|
||||
* Pay attention to the precedence level of different rules.
|
||||
*/
|
||||
|
||||
{" +", TK_NOTYPE}, // spaces
|
||||
{"\\+", '+'}, // plus
|
||||
{"==", TK_EQ}, // equal
|
||||
{"!=", TK_NEQ}, // not equal
|
||||
{"&&", TK_AND}, // and
|
||||
|
||||
{"-", '-'}, // sub
|
||||
{"\\*", '*'}, // mul
|
||||
@ -50,6 +54,9 @@ static struct rule {
|
||||
{"\\(", '('}, // (
|
||||
{"\\)", ')'}, // )
|
||||
{"[0-9]+", TK_DEC}, // dec number
|
||||
|
||||
{"0x[0-9a-fA-F]+", TK_HEX}, // hex number
|
||||
{"$[0-9a-z]+", TK_REG}, // register
|
||||
};
|
||||
|
||||
#define NR_REGEX ARRLEN(rules)
|
||||
@ -113,9 +120,14 @@ static bool make_token(char *e) {
|
||||
case '/':
|
||||
case '(':
|
||||
case ')':
|
||||
case TK_EQ:
|
||||
case TK_NEQ:
|
||||
case TK_AND:
|
||||
nr_token ++;
|
||||
break;
|
||||
case TK_DEC:
|
||||
case TK_HEX:
|
||||
case TK_REG:
|
||||
if (substr_len + 1 > sizeof(((Token*)0)->str)) {
|
||||
printf("token string is too long");
|
||||
return false;
|
||||
@ -124,7 +136,6 @@ static bool make_token(char *e) {
|
||||
tokens[nr_token].str[substr_len] = '\0';
|
||||
nr_token ++;
|
||||
break;
|
||||
case TK_EQ:
|
||||
case TK_NOTYPE:
|
||||
break;
|
||||
default: TODO();
|
||||
@ -164,10 +175,14 @@ int check_parentheses(const Token* arr, size_t p, size_t q) {
|
||||
|
||||
int get_level(int type) {
|
||||
switch (type) {
|
||||
case TK_AND: return 1;
|
||||
case TK_EQ:
|
||||
case TK_NEQ: return 2;
|
||||
case '+':
|
||||
case '-': return 1;
|
||||
case '-': return 4;
|
||||
case '*':
|
||||
case '/': return 2;
|
||||
case '/': return 5;
|
||||
case TK_DEREF: return 7;
|
||||
case TK_NEG: return 8;
|
||||
case '(': return 9;
|
||||
default: return INT_MAX;
|
||||
@ -196,7 +211,15 @@ uint32_t eval(const Token* arr, int p, int q, bool* success) {
|
||||
* For now this token should be a number.
|
||||
* Return the value of the number.
|
||||
*/
|
||||
return atoi(arr[q].str);
|
||||
switch (arr[p].type)
|
||||
{
|
||||
case TK_DEC: return atoi(arr[q].str);
|
||||
case TK_HEX: return strtol(arr[q].str, NULL, 16);
|
||||
case TK_REG: return isa_reg_str2val(arr[q].str, success);
|
||||
default:
|
||||
*success = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* We should do more things here. */
|
||||
int op = 0;
|
||||
@ -220,6 +243,9 @@ uint32_t eval(const Token* arr, int p, int q, bool* success) {
|
||||
if (type == TK_NEG && type_level == op_type_level) {
|
||||
continue;
|
||||
}
|
||||
if (type == TK_DEREF && type_level == op_type_level) {
|
||||
continue;
|
||||
}
|
||||
op = i;
|
||||
op_type_level = type_level;
|
||||
}
|
||||
@ -236,6 +262,10 @@ uint32_t eval(const Token* arr, int p, int q, bool* success) {
|
||||
|
||||
switch (arr[op].type) {
|
||||
case TK_NEG: return - val_r;
|
||||
case TK_DEREF: return vaddr_read(val_r, sizeof(word_t));
|
||||
case TK_EQ: return val_l == val_r;
|
||||
case TK_NEQ: return val_l != val_r;
|
||||
case TK_AND: return val_l && val_r;
|
||||
case '+': return val_l + val_r;
|
||||
case '-': return val_l - val_r;
|
||||
case '*': return val_l * val_r;
|
||||
@ -244,25 +274,30 @@ uint32_t eval(const Token* arr, int p, int q, bool* success) {
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool prev_not_number(int i) {
|
||||
return (i == 0 || \
|
||||
tokens[i-1].type == '(' || \
|
||||
tokens[i-1].type == '+' || \
|
||||
tokens[i-1].type == '-' || \
|
||||
tokens[i-1].type == '*' || \
|
||||
tokens[i-1].type == '/' || \
|
||||
tokens[i-1].type == TK_NEG || \
|
||||
tokens[i-1].type == TK_DEREF);
|
||||
}
|
||||
|
||||
word_t expr(char *e, bool *success) {
|
||||
if (!make_token(e)) {
|
||||
*success = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* TODO: Insert codes to evaluate the expression. */
|
||||
// TODO();
|
||||
*success = true;
|
||||
for (int i = 0; i < nr_token; i ++) {
|
||||
int type = tokens[i].type;
|
||||
if (type == '-' && (i == 0 || \
|
||||
tokens[i-1].type == '(' || \
|
||||
tokens[i-1].type == '+' || \
|
||||
tokens[i-1].type == '-' || \
|
||||
tokens[i-1].type == '*' || \
|
||||
tokens[i-1].type == '/' || \
|
||||
tokens[i-1].type == TK_NEG)) {
|
||||
if (type == '-' && prev_not_number(i)) {
|
||||
tokens[i].type = TK_NEG;
|
||||
} else if (type == '*' && prev_not_number(i)) {
|
||||
tokens[i].type = TK_DEREF;
|
||||
}
|
||||
}
|
||||
return eval(tokens, 0, nr_token - 1, success);
|
||||
|
@ -17,9 +17,10 @@
|
||||
#include <cpu/cpu.h>
|
||||
#include <readline/readline.h>
|
||||
#include <readline/history.h>
|
||||
#include <memory/vaddr.h>
|
||||
#include "sdb.h"
|
||||
|
||||
#include <memory/vaddr.h>
|
||||
|
||||
static int is_batch_mode = false;
|
||||
|
||||
void init_regex();
|
||||
|
@ -91,7 +91,7 @@ int main(int argc, char *argv[]) {
|
||||
fputs(code_buf, fp);
|
||||
fclose(fp);
|
||||
|
||||
int ret = system("gcc /tmp/.code.c -o /tmp/.expr");
|
||||
int ret = system("gcc /tmp/.code.c -o /tmp/.expr -Wall -Werror");
|
||||
if (ret != 0) {
|
||||
printf("failed to execute gcc\n");
|
||||
i ++;
|
||||
|
Reference in New Issue
Block a user