diff options
Diffstat (limited to 'uscript')
| -rw-r--r-- | uscript/lex.c | 54 | ||||
| -rw-r--r-- | uscript/lex.h | 2 | ||||
| -rw-r--r-- | uscript/parser.c | 26 |
3 files changed, 57 insertions, 25 deletions
diff --git a/uscript/lex.c b/uscript/lex.c index a25bb86..c8218fa 100644 --- a/uscript/lex.c +++ b/uscript/lex.c @@ -165,40 +165,46 @@ struct token ident_token(struct lexer *lex) u16 kind = TOKEN_IDENT; - if (match_kw(lex, "if")) - kind = TOKEN_IF; - else if (match_kw(lex, "elseif")) - kind = TOKEN_ELSEIF; + if (match_kw(lex, "and")) + kind = TOKEN_AND; + else if (match_kw(lex, "break")) + kind = TOKEN_BREAK; + else if (match_kw(lex, "do")) + kind = TOKEN_DO; else if (match_kw(lex, "else")) kind = TOKEN_ELSE; - else if (match_kw(lex, "loop")) - kind = TOKEN_LOOP; - else if (match_kw(lex, "true")) - kind = TOKEN_TRUE; + else if (match_kw(lex, "elseif")) + kind = TOKEN_ELSEIF; + else if (match_kw(lex, "end")) + kind = TOKEN_END; else if (match_kw(lex, "false")) kind = TOKEN_FALSE; - else if (match_kw(lex, "zilch")) - kind = TOKEN_ZILCH; + else if (match_kw(lex, "fun")) + kind = TOKEN_FUN; + else if (match_kw(lex, "global")) + kind = TOKEN_GLOBAL; + else if (match_kw(lex, "if")) + kind = TOKEN_IF; + else if (match_kw(lex, "in")) + kind = TOKEN_IN; + else if (match_kw(lex, "let")) + kind = TOKEN_LET; + else if (match_kw(lex, "loop")) + kind = TOKEN_LOOP; else if (match_kw(lex, "nada")) kind = TOKEN_ZILCH; - else if (match_kw(lex, "do")) - kind = TOKEN_DO; - else if (match_kw(lex, "break")) - kind = TOKEN_BREAK; else if (match_kw(lex, "next")) kind = TOKEN_NEXT; - else if (match_kw(lex, "in")) - kind = TOKEN_IN; - else if (match_kw(lex, "fun")) - kind = TOKEN_FUN; + else if (match_kw(lex, "not")) + kind = TOKEN_NOT; + else if (match_kw(lex, "or")) + kind = TOKEN_OR; else if (match_kw(lex, "ret")) kind = TOKEN_RET; - else if (match_kw(lex, "let")) - kind = TOKEN_LET; - else if (match_kw(lex, "end")) - kind = TOKEN_END; - else if (match_kw(lex, "global")) - kind = TOKEN_GLOBAL; + else if (match_kw(lex, "true")) + kind = TOKEN_TRUE; + else if (match_kw(lex, "zilch")) + kind = TOKEN_ZILCH; return create_token(lex, kind); } diff --git a/uscript/lex.h b/uscript/lex.h index 4e448ed..2d5035e 100644 --- a/uscript/lex.h +++ b/uscript/lex.h @@ -5,6 +5,7 @@ #include "val.h" #define XTOKENS(_) \ + _(AND) \ _(BREAK) \ _(DIV_EQL) \ _(DO) \ @@ -30,6 +31,7 @@ _(NEQL) \ _(NEXT) \ _(NUM) \ + _(OR) \ _(PLUS_EQL) \ _(RET) \ _(STR) \ diff --git a/uscript/parser.c b/uscript/parser.c index 9fd4e27..7909f98 100644 --- a/uscript/parser.c +++ b/uscript/parser.c @@ -15,6 +15,8 @@ enum precedence { PREC_NONE, PREC_ASSIGN, // = + PREC_OR, // or + PREC_AND, // and PREC_EQL, // == != PREC_COMP, // < <= > >= PREC_CONCAT, @@ -463,6 +465,26 @@ void parse_ident(struct parser *p) } static +void parse_and(struct parser *p) +{ + int jmp = begin_jump(p, BC_FALSEY_JMP); + parser_add_byte(p, BC_POP); + parse_expr(p, PREC_AND + 1); + end_jump(p, jmp); +} + +static +void parse_or(struct parser *p) +{ + int jmp = begin_jump(p, BC_FALSEY_JMP); + int else_jmp = begin_jump(p, BC_JMP); + end_jump(p, jmp); + parser_add_byte(p, BC_POP); + parse_expr(p, PREC_OR + 1); + end_jump(p, else_jmp); +} + +static void parse_binary(struct parser *p) { struct token op = p->prev; @@ -580,13 +602,14 @@ struct expr expressions[] = { ['>'] = {NULL, parse_binary, PREC_COMP}, ['='] = {NULL, NULL, PREC_NONE}, ['!'] = {parse_unary, NULL, PREC_NONE}, - [TOKEN_EOF] = {NULL, NULL, PREC_NONE}, + [TOKEN_AND] = {NULL, parse_and, PREC_AND}, [TOKEN_BREAK] = {NULL, NULL, PREC_NONE}, [TOKEN_DIV_EQL] = {NULL, NULL, PREC_NONE}, [TOKEN_DOT_DOT] = {NULL, parse_binary, PREC_CONCAT}, [TOKEN_DO] = {NULL, NULL, PREC_NONE}, [TOKEN_ELSE] = {NULL, NULL, PREC_NONE}, [TOKEN_END] = {NULL, NULL, PREC_NONE}, + [TOKEN_EOF] = {NULL, NULL, PREC_NONE}, [TOKEN_EQL] = {NULL, parse_binary, PREC_EQL}, [TOKEN_ERR] = {NULL, NULL, PREC_NONE}, [TOKEN_FALSE] = {parse_literal, NULL, PREC_NONE}, @@ -605,6 +628,7 @@ struct expr expressions[] = { [TOKEN_NEQL] = {NULL, parse_binary, PREC_EQL}, [TOKEN_NEXT] = {NULL, NULL, PREC_NONE}, [TOKEN_NUM] = {parse_number, NULL, PREC_NONE}, + [TOKEN_OR] = {NULL, parse_or, PREC_OR}, [TOKEN_PLUS_EQL] = {NULL, NULL, PREC_NONE}, [TOKEN_RET] = {NULL, NULL, PREC_NONE}, [TOKEN_STR] = {parse_string, NULL, PREC_NONE}, |
