Mercurial > hg > index.cgi
view lwbasic/compiler.c @ 25:87590f43e76d
Started lwbasic parser; checkpoint
author | lost@l-w.ca |
---|---|
date | Mon, 24 Jan 2011 20:08:09 -0700 |
parents | |
children | 26aa76da75ad |
line wrap: on
line source
/* 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 <http://www.gnu.org/licenses/>. */ /* This is the actual compiler bit; it drives the parser and code generation */ #include <stdio.h> #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; lexer(state); if (state -> lexer_token != token_identifier) { lwb_error("Invalid sub name '%s'", state -> lexer_token_string); } printf("<name> = %s\n", state -> lexer_token_string); lexer(state); if (state -> lexer_token == token_kw_public || state -> lexer_token == token_kw_private) { printf("<type> = %s\n", state -> lexer_token_string); lexer(state); } /* ignore the "PARAMS" keyword if present */ if (state -> lexer_token == token_kw_params) lexer(state); if (state -> lexer_token == token_eol) 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); } printf("Got <param> = %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 <type> = %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); } } 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); } } }