> 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 <regex.h>
|
||||||
|
|
||||||
|
#include <memory/vaddr.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
TK_NOTYPE = 256, TK_EQ,
|
TK_NOTYPE = 256,
|
||||||
TK_DEC,
|
TK_EQ,
|
||||||
|
TK_NEQ,
|
||||||
|
TK_AND,
|
||||||
|
|
||||||
TK_NEG,
|
TK_NEG,
|
||||||
|
TK_DEC,
|
||||||
/* TODO: Add more token types */
|
|
||||||
|
TK_HEX,
|
||||||
|
TK_REG,
|
||||||
|
TK_DEREF,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct rule {
|
static struct rule {
|
||||||
@ -36,13 +42,11 @@ static struct rule {
|
|||||||
int token_type;
|
int token_type;
|
||||||
} rules[] = {
|
} rules[] = {
|
||||||
|
|
||||||
/* TODO: Add more rules.
|
|
||||||
* Pay attention to the precedence level of different rules.
|
|
||||||
*/
|
|
||||||
|
|
||||||
{" +", TK_NOTYPE}, // spaces
|
{" +", TK_NOTYPE}, // spaces
|
||||||
{"\\+", '+'}, // plus
|
{"\\+", '+'}, // plus
|
||||||
{"==", TK_EQ}, // equal
|
{"==", TK_EQ}, // equal
|
||||||
|
{"!=", TK_NEQ}, // not equal
|
||||||
|
{"&&", TK_AND}, // and
|
||||||
|
|
||||||
{"-", '-'}, // sub
|
{"-", '-'}, // sub
|
||||||
{"\\*", '*'}, // mul
|
{"\\*", '*'}, // mul
|
||||||
@ -50,6 +54,9 @@ static struct rule {
|
|||||||
{"\\(", '('}, // (
|
{"\\(", '('}, // (
|
||||||
{"\\)", ')'}, // )
|
{"\\)", ')'}, // )
|
||||||
{"[0-9]+", TK_DEC}, // dec number
|
{"[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)
|
#define NR_REGEX ARRLEN(rules)
|
||||||
@ -113,9 +120,14 @@ static bool make_token(char *e) {
|
|||||||
case '/':
|
case '/':
|
||||||
case '(':
|
case '(':
|
||||||
case ')':
|
case ')':
|
||||||
|
case TK_EQ:
|
||||||
|
case TK_NEQ:
|
||||||
|
case TK_AND:
|
||||||
nr_token ++;
|
nr_token ++;
|
||||||
break;
|
break;
|
||||||
case TK_DEC:
|
case TK_DEC:
|
||||||
|
case TK_HEX:
|
||||||
|
case TK_REG:
|
||||||
if (substr_len + 1 > sizeof(((Token*)0)->str)) {
|
if (substr_len + 1 > sizeof(((Token*)0)->str)) {
|
||||||
printf("token string is too long");
|
printf("token string is too long");
|
||||||
return false;
|
return false;
|
||||||
@ -124,7 +136,6 @@ static bool make_token(char *e) {
|
|||||||
tokens[nr_token].str[substr_len] = '\0';
|
tokens[nr_token].str[substr_len] = '\0';
|
||||||
nr_token ++;
|
nr_token ++;
|
||||||
break;
|
break;
|
||||||
case TK_EQ:
|
|
||||||
case TK_NOTYPE:
|
case TK_NOTYPE:
|
||||||
break;
|
break;
|
||||||
default: TODO();
|
default: TODO();
|
||||||
@ -164,10 +175,14 @@ int check_parentheses(const Token* arr, size_t p, size_t q) {
|
|||||||
|
|
||||||
int get_level(int type) {
|
int get_level(int type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
case TK_AND: return 1;
|
||||||
|
case TK_EQ:
|
||||||
|
case TK_NEQ: return 2;
|
||||||
case '+':
|
case '+':
|
||||||
case '-': return 1;
|
case '-': return 4;
|
||||||
case '*':
|
case '*':
|
||||||
case '/': return 2;
|
case '/': return 5;
|
||||||
|
case TK_DEREF: return 7;
|
||||||
case TK_NEG: return 8;
|
case TK_NEG: return 8;
|
||||||
case '(': return 9;
|
case '(': return 9;
|
||||||
default: return INT_MAX;
|
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.
|
* For now this token should be a number.
|
||||||
* Return the value of the 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. */
|
/* We should do more things here. */
|
||||||
int op = 0;
|
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) {
|
if (type == TK_NEG && type_level == op_type_level) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (type == TK_DEREF && type_level == op_type_level) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
op = i;
|
op = i;
|
||||||
op_type_level = type_level;
|
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) {
|
switch (arr[op].type) {
|
||||||
case TK_NEG: return - val_r;
|
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;
|
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) {
|
word_t expr(char *e, bool *success) {
|
||||||
if (!make_token(e)) {
|
if (!make_token(e)) {
|
||||||
*success = false;
|
*success = false;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: Insert codes to evaluate the expression. */
|
|
||||||
// TODO();
|
|
||||||
*success = true;
|
*success = true;
|
||||||
for (int i = 0; i < nr_token; i ++) {
|
for (int i = 0; i < nr_token; i ++) {
|
||||||
int type = tokens[i].type;
|
int type = tokens[i].type;
|
||||||
if (type == '-' && (i == 0 || \
|
if (type == '-' && prev_not_number(i)) {
|
||||||
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].type = TK_NEG;
|
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);
|
return eval(tokens, 0, nr_token - 1, success);
|
||||||
|
@ -17,9 +17,10 @@
|
|||||||
#include <cpu/cpu.h>
|
#include <cpu/cpu.h>
|
||||||
#include <readline/readline.h>
|
#include <readline/readline.h>
|
||||||
#include <readline/history.h>
|
#include <readline/history.h>
|
||||||
#include <memory/vaddr.h>
|
|
||||||
#include "sdb.h"
|
#include "sdb.h"
|
||||||
|
|
||||||
|
#include <memory/vaddr.h>
|
||||||
|
|
||||||
static int is_batch_mode = false;
|
static int is_batch_mode = false;
|
||||||
|
|
||||||
void init_regex();
|
void init_regex();
|
||||||
|
@ -91,7 +91,7 @@ int main(int argc, char *argv[]) {
|
|||||||
fputs(code_buf, fp);
|
fputs(code_buf, fp);
|
||||||
fclose(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) {
|
if (ret != 0) {
|
||||||
printf("failed to execute gcc\n");
|
printf("failed to execute gcc\n");
|
||||||
i ++;
|
i ++;
|
||||||
|
Reference in New Issue
Block a user