# HG changeset patch # User lost@l-w.ca # Date 1296186297 25200 # Node ID 26aa76da75ad37bf9c1256eb6ba91c252b0ab8cb # Parent 87590f43e76d3fce609c64621e255734b0428e97 Additional parsing in function/sub; emission of prolog/epilog code diff -r 87590f43e76d -r 26aa76da75ad lwbasic/compiler.c --- a/lwbasic/compiler.c Mon Jan 24 20:08:09 2011 -0700 +++ b/lwbasic/compiler.c Thu Jan 27 20:44:57 2011 -0700 @@ -25,6 +25,9 @@ #include +#include +#include + #include "lwbasic.h" /* parse a type; the next token will be acquired as a result */ @@ -52,19 +55,22 @@ 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); } - printf(" = %s\n", 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) { - printf(" = %s\n", state -> lexer_token_string); + if (state -> lexer_token == token_kw_public) + vis = 1; lexer(state); } @@ -72,13 +78,13 @@ if (state -> lexer_token == token_kw_params) lexer(state); - if (state -> lexer_token == token_eol) + 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, get %d, %s\n", state -> lexer_token, state -> lexer_token_string); + 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); @@ -130,6 +136,44 @@ { 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); + + lw_free(state -> currentsub); + state -> currentsub = NULL; + } void compiler(cstate *state) diff -r 87590f43e76d -r 26aa76da75ad lwbasic/emit.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lwbasic/emit.c Thu Jan 27 20:44:57 2011 -0700 @@ -0,0 +1,47 @@ +/* +emit.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 + +#define __emit_c_seen__ +#include "lwbasic.h" + +void emit_prolog(cstate *state, int vis, int framesize) +{ + if (vis) + { + printf("\texport _%s\n", state -> currentsub); + } + printf("_%s\n", state -> currentsub); + if (framesize > 0) + { + printf("\tleas %d,s\n", -framesize); + } +} + +void emit_epilog(cstate *state) +{ + printf("\trts\n"); +} diff -r 87590f43e76d -r 26aa76da75ad lwbasic/lexer.c --- a/lwbasic/lexer.c Mon Jan 24 20:08:09 2011 -0700 +++ b/lwbasic/lexer.c Thu Jan 27 20:44:57 2011 -0700 @@ -55,6 +55,9 @@ { "as", token_kw_as }, { "params", token_kw_params }, { "returns", token_kw_returns }, + { "integer", token_kw_integer }, + { "endsub", token_kw_endsub }, + { "endfunction", token_kw_endfunction }, { NULL } }; @@ -111,7 +114,7 @@ for (;;) { c = lexer_curchar(state); - if (c == '_' || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c >= 0x80) + if (c == '_' || (c >= '0' && c <= '9' ) || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c >= 0x80) { /* character is part of word */ if (wordpos >= wordlen) diff -r 87590f43e76d -r 26aa76da75ad lwbasic/lwbasic.h --- a/lwbasic/lwbasic.h Mon Jan 24 20:08:09 2011 -0700 +++ b/lwbasic/lwbasic.h Thu Jan 27 20:44:57 2011 -0700 @@ -55,6 +55,8 @@ int parser_state; void *input_state; + + char *currentsub; } cstate; /* parser states */ @@ -75,6 +77,8 @@ token_kw_params, /* PARAMS keyword */ token_kw_returns, /* RETURNS keyword */ token_kw_integer, /* INTEGER keyword */ + token_kw_endsub, /* ENDSUB keyword */ + token_kw_endfunction, /* ENDFUNCTION keyword */ token_identifier, /* an identifier (variable, function, etc. */ token_char, /* single character; fallback */ token_uint, /* unsigned integer up to 32 bits */ @@ -95,4 +99,10 @@ extern void lexer(cstate *state); #endif +#ifndef __emit_c_seen__ +extern void emit_prolog(cstate *state, int vis, int framesize); +extern void emit_epilog(cstate *state); +#endif + + #endif /* __lwbasic_h_seen__ */ diff -r 87590f43e76d -r 26aa76da75ad lwbasic/rules.make --- a/lwbasic/rules.make Mon Jan 24 20:08:09 2011 -0700 +++ b/lwbasic/rules.make Thu Jan 27 20:44:57 2011 -0700 @@ -1,7 +1,7 @@ dirname := $(dir $(lastword $(MAKEFILE_LIST))) lwbasic_dir := $(dirname) -lwbasic_lsrcs := main.c input.c compiler.c lexer.c +lwbasic_lsrcs := main.c input.c compiler.c lexer.c emit.c lwbasic_srcs := $(addprefix $(dirname),$(lwbasic_lsrcs)) lwbasic_objs := $(lwbasic_srcs:.c=.o)