changeset 32:49d608aecc4d

Framework for handling local stack frame and/or variables
author lost@l-w.ca
date Thu, 03 Feb 2011 22:00:47 -0700
parents 574931d87abd
children 890a8f688889
files lwbasic/emit.c lwbasic/lwbasic.h lwbasic/parser.c lwbasic/symtab.c lwbasic/symtab.h
diffstat 5 files changed, 87 insertions(+), 29 deletions(-) [+]
line wrap: on
line diff
--- a/lwbasic/emit.c	Thu Feb 03 21:28:24 2011 -0700
+++ b/lwbasic/emit.c	Thu Feb 03 22:00:47 2011 -0700
@@ -28,24 +28,24 @@
 #define __emit_c_seen__
 #include "lwbasic.h"
 
-void emit_prolog(cstate *state, int vis, int framesize)
+void emit_prolog(cstate *state, int vis)
 {
 	if (vis)
 	{
 		printf("\texport _%s\n", state -> currentsub);
 	}
 	printf("_%s\n", state -> currentsub);
-	if (framesize > 0)
+	if (state -> framesize > 0)
 	{
-		printf("\tleas %d,s\n", -framesize);
+		printf("\tleas %d,s\n", -(state -> framesize));
 	}
 }
 
-void emit_epilog(cstate *state, int framesize)
+void emit_epilog(cstate *state)
 {
-	if (framesize > 0)
+	if (state -> framesize > 0)
 	{
-		printf("\tleas %d,s\n", framesize);
+		printf("\tleas %d,s\n", state -> framesize);
 	}
 	printf("\trts\n");
 }
--- a/lwbasic/lwbasic.h	Thu Feb 03 21:28:24 2011 -0700
+++ b/lwbasic/lwbasic.h	Thu Feb 03 22:00:47 2011 -0700
@@ -28,6 +28,8 @@
 
 #include <stdint.h>
 
+#include "symtab.h"
+
 /* note: integer and uinteger will be the same for positive values from 0
 through 0x7FFFFFFF; the unsigned type should be used for doing ascii
 conversions and then if a negative value was discovered, it should be
@@ -57,6 +59,10 @@
 	void *input_state;
 	
 	char *currentsub;
+	symtab_t *global_syms;
+	symtab_t *local_syms;
+	int returntype;
+	int framesize;
 } cstate;
 
 /* parser states */
@@ -87,6 +93,15 @@
 	token_eof					/* end of file */
 };
 
+/* symbol types */
+enum
+{
+	symtype_sub,				/* "sub" (void function) */
+	symtype_func,				/* function (nonvoid) */
+	symtype_param,				/* function parameter */
+	symtype_var					/* variable */
+};
+
 #ifndef __input_c_seen__
 extern int input_getchar(cstate *state);
 #endif
@@ -101,8 +116,8 @@
 #endif
 
 #ifndef __emit_c_seen__
-extern void emit_prolog(cstate *state, int vis, int framesize);
-extern void emit_epilog(cstate *state, int framesize);
+extern void emit_prolog(cstate *state, int vis);
+extern void emit_epilog(cstate *state);
 #endif
 
 
--- a/lwbasic/parser.c	Thu Feb 03 21:28:24 2011 -0700
+++ b/lwbasic/parser.c	Thu Feb 03 22:00:47 2011 -0700
@@ -29,6 +29,15 @@
 #include <lw_string.h>
 
 #include "lwbasic.h"
+#include "symtab.h"
+
+
+/* size of a type */
+static int sizeof_type(int type)
+{
+	/* everything is an "int" right now; 2 bytes */
+	return 2;
+}
 
 /* parse a type; the next token will be acquired as a result */
 /* the token advancement is to provide consistency */
@@ -50,14 +59,30 @@
 	return pt;
 }
 
+static void parse_decls(cstate *state)
+{
+	/* declarations */
+	switch (state -> lexer_token)
+	{
+	default:
+		return;
+	}
+}
+
 
 /* issub means RETURNS is not allowed; !issub means RETURNS is required */
+
 static void parse_subfunc(cstate *state, int issub)
 {
-	int pt;
-	char *subname;
+	int pt, rt;
+	char *subname, *pn;
 	int vis = 0;
-			
+	symtab_entry_t *se;
+	int paramsize = 0;
+	
+	state -> local_syms = symtab_init();
+	state -> framesize = 0;
+	
 	lexer(state);
 	if (state -> lexer_token != token_identifier)
 	{
@@ -86,7 +111,7 @@
 	{
 		lwb_error("Parameter name expected, got %s\n", lexer_return_token(state));
 	}
-	printf("Got <param> = %s\n", state -> lexer_token_string);
+	pn = lw_strdup(state -> lexer_token_string);
 	lexer(state);
 	
 	if (state -> lexer_token != token_kw_as)
@@ -94,7 +119,15 @@
 	lexer(state);
 	
 	pt = parse_type(state);
-	printf("Got <type> = %d\n", pt);
+
+	se = symtab_find(state -> local_syms, pn);
+	if (se)
+	{
+		lwb_error("Duplicate parameter name %s\n", pn);
+	}
+	symtab_register(state -> local_syms, pn, paramsize, symtype_param, NULL);
+	paramsize += sizeof_type(pt);
+	lw_free(pn);
 	
 	if (state -> lexer_token == token_char && state -> lexer_token_string[0] == ',')
 	{
@@ -102,26 +135,26 @@
 		goto paramagain;
 	}
 
-noparms:	
+noparms:
+	rt = -1;
 	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)
+/*		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
 	{
@@ -138,21 +171,27 @@
 	}
 
 	
-	printf("Sub/Func %s, vis %s\n", subname, vis ? "public" : "private");
+	se = symtab_find(state -> global_syms, subname);
+	if (se)
+	{
+		lwb_error("Multiply defined symbol %s\n", subname);
+	}
+
+	symtab_register(state -> global_syms, subname, -1, issub ? symtype_sub : symtype_func, NULL);
 
 	state -> currentsub = subname;
-
+	state -> returntype = rt;
 	/* consume EOL */
 	lexer(state);
 	
 	/* variable declarations */
-	/* parse_decls(state); */
+	parse_decls(state);
 	
 	/* output function/sub prolog */
-	emit_prolog(state, vis, 0);
+	emit_prolog(state, vis);
 	
 	/* parse statement block  */
-	/* parse_statemetns(state); */
+	/* parse_statements(state); */
 	
 	if (issub)
 	{
@@ -169,17 +208,19 @@
 		}
 	}
 	/* output function/sub epilog */
-	emit_epilog(state, 0);
+	emit_epilog(state);
 	
 	lw_free(state -> currentsub);
 	state -> currentsub = NULL;
-	
+	symtab_destroy(state -> local_syms);
+	state -> local_syms = NULL;
 }
 
 void parser(cstate *state)
 {
 	state -> lexer_curchar = -1;
-	
+	state -> global_syms = symtab_init();
+		
 	/* now look for a global declaration */
 	for (;;)
 	{
--- a/lwbasic/symtab.c	Thu Feb 03 21:28:24 2011 -0700
+++ b/lwbasic/symtab.c	Thu Feb 03 22:00:47 2011 -0700
@@ -50,6 +50,7 @@
 		se = st -> head;
 		st -> head = se -> next;
 		lw_free(se -> name);
+		lw_free(se -> privdata);
 		lw_free(se);
 	}
 	lw_free(st);
@@ -67,7 +68,7 @@
 	return NULL;
 }
 
-void symtab_register(symtab_t *st, char *name, int addr, int symtype)
+void symtab_register(symtab_t *st, char *name, int addr, int symtype, void *privdata)
 {
 	symtab_entry_t *se;
 	
@@ -75,6 +76,7 @@
 	se -> name = lw_strdup(name);
 	se -> addr = addr;
 	se -> symtype = symtype;
+	se -> privdata = privdata;
 	se -> next = st -> head;
 	st -> head = se;
 }
--- a/lwbasic/symtab.h	Thu Feb 03 21:28:24 2011 -0700
+++ b/lwbasic/symtab.h	Thu Feb 03 22:00:47 2011 -0700
@@ -42,7 +42,7 @@
 	char *name;				/* name of the symbol */
 	int addr;				/* address of symbol */
 	int symtype;			/* type of symbol */
-	
+	void *privdata;			/* random data associated with symbol */	
 	symtab_entry_t *next;	/* next in the list */
 };
 
@@ -54,7 +54,7 @@
 __E symtab_t *symtab_init(void);
 __E void symtab_destroy(symtab_t *st);
 __E symtab_entry_t *symtab_find(symtab_t *st, char *name);
-__E void symtab_register(symtab_t *st, char *name, int addr, int symtype);
+__E void symtab_register(symtab_t *st, char *name, int addr, int symtype, void *data);
 
 #undef __E