# HG changeset patch # User Lost Wizard (lost@starbug3) # Date 1296940974 25200 # Node ID cdb0175e106331aa2cb6e034941e591fdeac3a18 # Parent bfea77812e64243d0783b6a4c0b57103606dc7e3 More work on expressions diff -r bfea77812e64 -r cdb0175e1063 lwbasic/lexer.c --- a/lwbasic/lexer.c Fri Feb 04 21:27:03 2011 -0700 +++ b/lwbasic/lexer.c Sat Feb 05 14:22:54 2011 -0700 @@ -46,6 +46,7 @@ int token; }; +/* keywords that appear as part of normal expressions */ static struct token_list lexer_global_tokens[] = { { "function", token_kw_function }, @@ -59,7 +60,18 @@ { "endsub", token_kw_endsub }, { "endfunction", token_kw_endfunction }, { "dim", token_kw_dim }, - { "=", token_op_assignment }, + { NULL } +}; + +/* contains "built in" function names */ +static struct token_list lexer_expr_tokens[] = +{ + { "and", token_op_and }, + { "or", token_op_or }, + { "band", token_op_band }, + { "bor", token_op_bor }, + { "bxor", token_op_bxor }, + { "xor", token_op_xor }, { NULL } }; @@ -77,6 +89,23 @@ "ENDFUNCTION", "DIM", "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", "", "", "", @@ -171,6 +200,11 @@ tok = lexer_global_tokens; } + if (state -> expression) + { + tok = lexer_expr_tokens; + } + /* check for tokens if appropriate */ /* force uppercase */ if (tok) @@ -194,6 +228,39 @@ state -> lexer_token = token_identifier; } +static void lexer_parse_number(cstate *state, int neg) +{ + unsigned long tint = 0; + int c; + + for (;;) + { + c = lexer_curchar(state); + if (c >= '0' && c <= '9') + { + tint *= 10 + (c - '0'); + } + else + { + /* end of the number here */ + if (neg) + { + if (tint > 0x80000000) + lwb_error("Integer overflow\n"); + state -> lexer_token_number.integer = -tint; + state -> lexer_token = token_int; + } + else + { + state -> lexer_token = token_uint; + state -> lexer_token_number.uinteger = tint; + } + return; + } + lexer_nextchar(state); + } +} + static void lexer_empty_token(cstate *state) { lw_free(state -> lexer_token_string); @@ -239,13 +306,101 @@ lexer_word(state); return; } + + if (state -> expression && c >= '0' && c <= '9') + { + /* we have a number */ + lexer_parse_number(state, 0); + return; + } + + lexer_nextchar(state); + if (state -> expression) + { + if (c == '-' && lexer_curchar(state) >= '0' && lexer_curchar(state) <= '9') + { + /* we have a negative number here */ + lexer_parse_number(state, 1); + return; + } + if (c == '=') + { + state -> lexer_token = token_op_equality; + return; + } + if (c == '<') + { + if (lexer_curchar(state) == '=') + { + lexer_nextchar(state); + state -> lexer_token = token_op_lessequal; + return; + } + if (lexer_curchar(state) == '>') + { + lexer_nextchar(state); + state -> lexer_token = token_op_notequal; + return; + } + state -> lexer_token = token_op_less; + return; + } + if (c == '>') + { + if (lexer_curchar(state) == '>') + { + lexer_nextchar(state); + state -> lexer_token = token_op_greaterequal; + return; + } + if (lexer_curchar(state) == '<') + { + state -> lexer_token = token_op_notequal; + lexer_nextchar(state); + return; + } + state -> lexer_token = token_op_greater; + return; + } + switch(c) + { + case '+': + state -> lexer_token = token_op_plus; + return; + + case '-': + state -> lexer_token = token_op_minus; + return; + + case '/': + state -> lexer_token = token_op_divide; + return; + + case '*': + state -> lexer_token = token_op_times; + return; + + case '%': + state -> lexer_token = token_op_modulus; + return; + + + } + } + else + { + if (c == '=') + { + state -> lexer_token = token_op_assignment; + return; + } + } /* return the character if all else fails */ + state -> lexer_token = token_char; state -> lexer_token_string = lw_realloc(state -> lexer_token_string, 2); state -> lexer_token_string[0] = c; state -> lexer_token_string[1] = 0; - lexer_nextchar(state); - state -> lexer_token = token_char; return; } diff -r bfea77812e64 -r cdb0175e1063 lwbasic/lwbasic.h --- a/lwbasic/lwbasic.h Fri Feb 04 21:27:03 2011 -0700 +++ b/lwbasic/lwbasic.h Sat Feb 05 14:22:54 2011 -0700 @@ -53,7 +53,7 @@ int lexer_token; int lexer_curchar; int lexer_ignorechar; - + int expression; int parser_state; void *input_state; @@ -87,6 +87,23 @@ token_kw_endfunction, /* ENDFUNCTION keyword */ token_kw_dim, /* DIM keyword */ token_op_assignment, /* assignment operator */ + token_op_equality, /* equality test */ + token_op_greater, /* greater than */ + token_op_less, /* less than */ + token_op_greaterequal, /* greater or equal */ + token_op_lessequal, /* less or equal */ + token_op_notequal, /* not equal */ + token_op_and, /* boolean and */ + token_op_or, /* boolean or */ + token_op_xor, /* boolean exlusive or */ + token_op_band, /* bitwise and */ + token_op_bor, /* bitwise or */ + token_op_bxor, /* bitwise xor */ + token_op_plus, /* plus */ + token_op_minus, /* minus */ + token_op_times, /* times */ + token_op_divide, /* divide */ + token_op_modulus, /* modulus */ token_identifier, /* an identifier (variable, function, etc. */ token_char, /* single character; fallback */ token_uint, /* unsigned integer up to 32 bits */ diff -r bfea77812e64 -r cdb0175e1063 lwbasic/parser.c --- a/lwbasic/parser.c Fri Feb 04 21:27:03 2011 -0700 +++ b/lwbasic/parser.c Sat Feb 05 14:22:54 2011 -0700 @@ -66,6 +66,14 @@ return pt; } +static int parse_expression(cstate *state) +{ + state -> expression = 1; + + state -> expression = 0; + return 1; +} + static void parse_decls(cstate *state) { /* declarations */ @@ -122,6 +130,7 @@ static void parse_statements(cstate *state) { symtab_entry_t *se; + int et; for (;;) { @@ -141,10 +150,14 @@ if (!se) lwb_error("Unknown variable %s\n", state -> lexer_token_string); lexer(state); + /* ensure the first token of the expression will be parsed correctly */ + state -> expression = 1; expect(state, token_op_assignment); /* parse the expression */ - /* parse_expression(state); */ + et = parse_expression(state); + + /* check type compatibility */ /* actually do the assignment */