# HG changeset patch # User lost@l-w.ca # Date 1296793151 25200 # Node ID bcd532a90e538a1f88975243b9caa373d226d647 # Parent bc96cd02fbf4fb729a4547bce5a3f10f1746fbf3 Renamed "compiler" to "parser" for more consistent terminology diff -r bc96cd02fbf4 -r bcd532a90e53 lwbasic/compiler.c --- a/lwbasic/compiler.c Fri Jan 28 22:35:04 2011 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,212 +0,0 @@ -/* -compiler.c - -Copyright © 2011 William Astle - -This file is part of LWTOOLS. - -LWTOOLS is free software: you can redistribute it and/or modify it under the -terms of the GNU General Public License as published by the Free Software -Foundation, either version 3 of the License, or (at your option) any later -version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program. If not, see . -*/ - -/* -This is the actual compiler bit; it drives the parser and code generation -*/ - -#include - -#include -#include - -#include "lwbasic.h" - -/* parse a type; the next token will be acquired as a result */ -/* the token advancement is to provide consistency */ -static int parse_type(cstate *state) -{ - int pt = -1; - - switch (state -> lexer_token) - { - case token_kw_integer: - pt = 1; - break; - - default: - lwb_error("Invalid type specification"); - } - lexer(state); - /* look for "unsigned" modifier for integer types */ - return pt; -} - - -/* issub means RETURNS is not allowed; !issub means RETURNS is required */ -static void parse_subfunc(cstate *state, int issub) -{ - int pt; - char *subname; - int vis = 0; - - lexer(state); - if (state -> lexer_token != token_identifier) - { - lwb_error("Invalid sub name '%s'", state -> lexer_token_string); - } - - subname = lw_strdup(state -> lexer_token_string); - - lexer(state); - if (state -> lexer_token == token_kw_public || state -> lexer_token == token_kw_private) - { - if (state -> lexer_token == token_kw_public) - vis = 1; - lexer(state); - } - - /* ignore the "PARAMS" keyword if present */ - if (state -> lexer_token == token_kw_params) - lexer(state); - - if (state -> lexer_token == token_eol || state -> lexer_token == token_kw_returns) - goto noparms; - -paramagain: - if (state -> lexer_token != token_identifier) - { - lwb_error("Parameter name expected, got %d, %s\n", state -> lexer_token, state -> lexer_token_string); - } - printf("Got = %s\n", state -> lexer_token_string); - lexer(state); - - if (state -> lexer_token != token_kw_as) - lwb_error("Expecting AS\n"); - lexer(state); - - pt = parse_type(state); - printf("Got = %d\n", pt); - - if (state -> lexer_token == token_char && state -> lexer_token_string[0] == ',') - { - lexer(state); - goto paramagain; - } - -noparms: - if (!issub) - { - int rt; - - if (state -> lexer_token != token_kw_returns) - { - lwb_error("FUNCTION must have RETURNS\n"); - } - lexer(state); - if (state -> lexer_token == token_identifier) - { - printf("Return value named: %s\n", state -> lexer_token_string); - lexer(state); - if (state -> lexer_token != token_kw_as) - lwb_error("Execting AS after RETURNS"); - lexer(state); - } - rt = parse_type(state); - printf("Return type: %d\n", rt); - } - else - { - if (state -> lexer_token == token_kw_returns) - { - lwb_error("SUB cannot specify RETURNS\n"); - } - } - - - if (state -> lexer_token != token_eol) - { - lwb_error("EOL expected; found %d, %s\n", state -> lexer_token, state -> lexer_token_string); - } - - - printf("Sub/Func %s, vis %s\n", subname, vis ? "public" : "private"); - - state -> currentsub = subname; - - /* consume EOL */ - lexer(state); - - /* variable declarations */ - /* parse_decls(state); */ - - /* output function/sub prolog */ - emit_prolog(state, vis, 0); - - /* parse statement block */ - /* parse_statemetns(state); */ - - if (issub) - { - if (state -> lexer_token != token_kw_endsub) - { - lwb_error("Expecting ENDSUB, got %d (%s)\n", state -> lexer_token, state -> lexer_token_string); - } - } - else - { - if (state -> lexer_token != token_kw_endfunction) - { - lwb_error("Expecting ENDFUNCTION, got %d (%s)\n", state -> lexer_token, state -> lexer_token_string); - } - } - /* output function/sub epilog */ - emit_epilog(state, 0); - - lw_free(state -> currentsub); - state -> currentsub = NULL; - -} - -void compiler(cstate *state) -{ - state -> lexer_curchar = -1; - - /* now look for a global declaration */ - for (;;) - { - state -> parser_state = parser_state_global; - lexer(state); - switch (state -> lexer_token) - { - case token_kw_function: - printf("Function\n"); - parse_subfunc(state, 0); - break; - - case token_kw_sub: - printf("Sub\n"); - parse_subfunc(state, 1); - break; - - /* blank lines are allowed */ - case token_eol: - continue; - - /* EOF is allowed - end of parsing */ - case token_eof: - return; - - default: - lwb_error("Invalid token %d, %s in global state\n", state -> lexer_token, state -> lexer_token_string); - } - } -} diff -r bc96cd02fbf4 -r bcd532a90e53 lwbasic/main.c --- a/lwbasic/main.c Fri Jan 28 22:35:04 2011 -0700 +++ b/lwbasic/main.c Thu Feb 03 21:19:11 2011 -0700 @@ -92,7 +92,7 @@ PROGVER }; -extern void compiler(cstate *state); +extern void parser(cstate *state); int main(int argc, char **argv) { @@ -100,7 +100,7 @@ lw_cmdline_parse(&cmdline_parser, argc, argv, 0, 0, &state); - compiler(&state); + parser(&state); exit(0); } diff -r bc96cd02fbf4 -r bcd532a90e53 lwbasic/parser.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lwbasic/parser.c Thu Feb 03 21:19:11 2011 -0700 @@ -0,0 +1,212 @@ +/* +compiler.c + +Copyright © 2011 William Astle + +This file is part of LWTOOLS. + +LWTOOLS is free software: you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the Free Software +Foundation, either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +more details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . +*/ + +/* +This is the actual compiler bit; it drives the parser and code generation +*/ + +#include + +#include +#include + +#include "lwbasic.h" + +/* parse a type; the next token will be acquired as a result */ +/* the token advancement is to provide consistency */ +static int parse_type(cstate *state) +{ + int pt = -1; + + switch (state -> lexer_token) + { + case token_kw_integer: + pt = 1; + break; + + default: + lwb_error("Invalid type specification"); + } + lexer(state); + /* look for "unsigned" modifier for integer types */ + return pt; +} + + +/* issub means RETURNS is not allowed; !issub means RETURNS is required */ +static void parse_subfunc(cstate *state, int issub) +{ + int pt; + char *subname; + int vis = 0; + + lexer(state); + if (state -> lexer_token != token_identifier) + { + lwb_error("Invalid sub name '%s'", state -> lexer_token_string); + } + + subname = lw_strdup(state -> lexer_token_string); + + lexer(state); + if (state -> lexer_token == token_kw_public || state -> lexer_token == token_kw_private) + { + if (state -> lexer_token == token_kw_public) + vis = 1; + lexer(state); + } + + /* ignore the "PARAMS" keyword if present */ + if (state -> lexer_token == token_kw_params) + lexer(state); + + if (state -> lexer_token == token_eol || state -> lexer_token == token_kw_returns) + goto noparms; + +paramagain: + if (state -> lexer_token != token_identifier) + { + lwb_error("Parameter name expected, got %d, %s\n", state -> lexer_token, state -> lexer_token_string); + } + printf("Got = %s\n", state -> lexer_token_string); + lexer(state); + + if (state -> lexer_token != token_kw_as) + lwb_error("Expecting AS\n"); + lexer(state); + + pt = parse_type(state); + printf("Got = %d\n", pt); + + if (state -> lexer_token == token_char && state -> lexer_token_string[0] == ',') + { + lexer(state); + goto paramagain; + } + +noparms: + if (!issub) + { + int rt; + + if (state -> lexer_token != token_kw_returns) + { + lwb_error("FUNCTION must have RETURNS\n"); + } + lexer(state); + if (state -> lexer_token == token_identifier) + { + printf("Return value named: %s\n", state -> lexer_token_string); + lexer(state); + if (state -> lexer_token != token_kw_as) + lwb_error("Execting AS after RETURNS"); + lexer(state); + } + rt = parse_type(state); + printf("Return type: %d\n", rt); + } + else + { + if (state -> lexer_token == token_kw_returns) + { + lwb_error("SUB cannot specify RETURNS\n"); + } + } + + + if (state -> lexer_token != token_eol) + { + lwb_error("EOL expected; found %d, %s\n", state -> lexer_token, state -> lexer_token_string); + } + + + printf("Sub/Func %s, vis %s\n", subname, vis ? "public" : "private"); + + state -> currentsub = subname; + + /* consume EOL */ + lexer(state); + + /* variable declarations */ + /* parse_decls(state); */ + + /* output function/sub prolog */ + emit_prolog(state, vis, 0); + + /* parse statement block */ + /* parse_statemetns(state); */ + + if (issub) + { + if (state -> lexer_token != token_kw_endsub) + { + lwb_error("Expecting ENDSUB, got %d (%s)\n", state -> lexer_token, state -> lexer_token_string); + } + } + else + { + if (state -> lexer_token != token_kw_endfunction) + { + lwb_error("Expecting ENDFUNCTION, got %d (%s)\n", state -> lexer_token, state -> lexer_token_string); + } + } + /* output function/sub epilog */ + emit_epilog(state, 0); + + lw_free(state -> currentsub); + state -> currentsub = NULL; + +} + +void parser(cstate *state) +{ + state -> lexer_curchar = -1; + + /* now look for a global declaration */ + for (;;) + { + state -> parser_state = parser_state_global; + lexer(state); + switch (state -> lexer_token) + { + case token_kw_function: + printf("Function\n"); + parse_subfunc(state, 0); + break; + + case token_kw_sub: + printf("Sub\n"); + parse_subfunc(state, 1); + break; + + /* blank lines are allowed */ + case token_eol: + continue; + + /* EOF is allowed - end of parsing */ + case token_eof: + return; + + default: + lwb_error("Invalid token %d, %s in global state\n", state -> lexer_token, state -> lexer_token_string); + } + } +} diff -r bc96cd02fbf4 -r bcd532a90e53 lwbasic/rules.make --- a/lwbasic/rules.make Fri Jan 28 22:35:04 2011 -0700 +++ b/lwbasic/rules.make Thu Feb 03 21:19:11 2011 -0700 @@ -1,7 +1,7 @@ dirname := $(dir $(lastword $(MAKEFILE_LIST))) lwbasic_dir := $(dirname) -lwbasic_lsrcs := main.c input.c compiler.c lexer.c emit.c symtab.c +lwbasic_lsrcs := main.c input.c parser.c lexer.c emit.c symtab.c lwbasic_srcs := $(addprefix $(dirname),$(lwbasic_lsrcs)) lwbasic_objs := $(lwbasic_srcs:.c=.o)