changeset 26:26aa76da75ad

Additional parsing in function/sub; emission of prolog/epilog code
author lost@l-w.ca
date Thu, 27 Jan 2011 20:44:57 -0700
parents 87590f43e76d
children 77626fc37af2
files lwbasic/compiler.c lwbasic/emit.c lwbasic/lexer.c lwbasic/lwbasic.h lwbasic/rules.make
diffstat 5 files changed, 111 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- 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 <stdio.h>
 
+#include <lw_alloc.h>
+#include <lw_string.h>
+
 #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("<name> = %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("<type> = %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 <param> = %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)
--- /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 <http://www.gnu.org/licenses/>.
+*/
+
+/*
+This is the actual compiler bit; it drives the parser and code generation
+*/
+
+#include <stdio.h>
+
+#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");
+}
--- 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)
--- 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__ */
--- 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)