From 64fe1b2e70cac965bf4ae89f24237f6e28cc196e Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Wed, 2 Aug 2017 16:05:14 -0700 Subject: [PATCH] Lambda functions working except double parsed in function list ??? --- src/samplesrc/test.pla | 14 ++++++++-- src/toolsrc/codegen.c | 56 ++++++++++++++++++++++++++++++++------- src/toolsrc/codegen.h | 1 + src/toolsrc/parse.c | 59 ++++++++++++++++++++++++++++-------------- src/toolsrc/symbols.h | 2 ++ 5 files changed, 100 insertions(+), 32 deletions(-) diff --git a/src/samplesrc/test.pla b/src/samplesrc/test.pla index 01b94d5..2db9607 100755 --- a/src/samplesrc/test.pla +++ b/src/samplesrc/test.pla @@ -37,7 +37,7 @@ word ptr // def tens(start) word i, pptr - + i = start pptr = @print repeat @@ -76,10 +76,16 @@ def nums(range) puti(array[0]);putln puti(array[1]);putln end +def printfunc(a, b, lambda)#0 + puts("func(a,b)=") + puti(lambda(a,b)) + putln +end export def main(range) byte a + word lambda + a = 10 - nums(*range) tens(*range*10) ascii @@ -110,6 +116,10 @@ export def main(range) putc('?') wend putln + printfunc(1, 2, &(a,b)a+b) + printfunc(1, 2, &(a,b)(a-b)) + lambda = &(x,y) x * y + puti(lambda(2,3));putln end puti(array[0]);putc(' ') puti(array[1]);putc(' ') diff --git a/src/toolsrc/codegen.c b/src/toolsrc/codegen.c index 0949de2..3b342cb 100755 --- a/src/toolsrc/codegen.c +++ b/src/toolsrc/codegen.c @@ -1,32 +1,38 @@ #include #include +#include #include #include "plasm.h" /* * Symbol table and fixup information. */ #define ID_LEN 32 -static int consts = 0; -static int externs = 0; -static int globals = 0; -static int locals = 0; -static int predefs = 0; -static int defs = 0; -static int asmdefs = 0; -static int codetags = 1; // Fix check for break_tag and cont_tag -static int fixups = 0; +static int consts = 0; +static int externs = 0; +static int globals = 0; +static int locals = 0; +static int localsize = 0; +static int predefs = 0; +static int defs = 0; +static int asmdefs = 0; +static int codetags = 1; // Fix check for break_tag and cont_tag +static int fixups = 0; static char idconst_name[1024][ID_LEN+1]; static int idconst_value[1024]; static char idglobal_name[1024][ID_LEN+1]; static int idglobal_type[1024]; static int idglobal_tag[1024]; -static int localsize = 0; static char idlocal_name[128][ID_LEN+1]; static int idlocal_type[128]; static int idlocal_offset[128]; static char fixup_size[2048]; static int fixup_type[2048]; static int fixup_tag[2048]; +static int savelocalsize = 0; +static int savelocals = 0; +static char savelocal_name[128][ID_LEN+1]; +static int savelocal_type[128]; +static int savelocal_offset[128]; static t_opseq optbl[2048]; static t_opseq *freeop_lst = &optbl[0]; static t_opseq *pending_seq = 0; @@ -167,6 +173,24 @@ void idlocal_reset(void) locals = 0; localsize = 0; } +void idlocal_save(void) +{ + savelocals = locals; + savelocalsize = localsize; + memcpy(savelocal_name, idlocal_name, locals*(ID_LEN+1)); + memcpy(savelocal_type, idlocal_type, locals*sizeof(int)); + memcpy(savelocal_offset, idlocal_offset, locals*sizeof(int)); + locals = 0; + localsize = 0; +} +void idlocal_restore(void) +{ + locals = savelocals; + localsize = savelocalsize; + memcpy(idlocal_name, savelocal_name, locals*(ID_LEN+1)); + memcpy(idlocal_type, savelocal_type, locals*sizeof(int)); + memcpy(idlocal_offset, savelocal_offset, locals*sizeof(int)); +} int idfunc_add(char *name, int len, int type, int tag) { if (globals > 1024) @@ -467,6 +491,18 @@ void emit_idfunc(int tag, int type, char *name, int is_bytecode) printf("\tJSR\tINTERP\n"); } } +void emit_lambdafunc(int tag, char *name, int cparams, t_opseq *lambda_seq) +{ + emit_idfunc(tag, DEF_TYPE, name, 1); + if (cparams) + printf("\t%s\t$58,$%02X,$%02X\t\t; ENTER\t%d,%d\n", DB, 0, cparams, 0, cparams); + emit_seq(lambda_seq); + emit_pending_seq(); + if (cparams) + printf("\t%s\t$5A\t\t\t; LEAVE\n", DB); + else + printf("\t%s\t$5C\t\t\t; RET\n", DB); +} void emit_idconst(char *name, int value) { printf("\t\t\t\t\t; %s = %d\n", name, value); diff --git a/src/toolsrc/codegen.h b/src/toolsrc/codegen.h index 9cb750b..e7c1247 100755 --- a/src/toolsrc/codegen.h +++ b/src/toolsrc/codegen.h @@ -95,6 +95,7 @@ void emit_asm(char *s); void emit_idlocal(char *name, int value); void emit_idglobal(int value, int size, char *name); void emit_idfunc(int tag, int type, char *name, int is_bytecode); +void emit_lambdafunc(int tag, char *name, int cparams, t_opseq *lambda_seq); void emit_idconst(char *name, int value); int emit_data(int vartype, int consttype, long constval, int constsize); void emit_codetag(int tag); diff --git a/src/toolsrc/parse.c b/src/toolsrc/parse.c index eb694ed..62a2d60 100755 --- a/src/toolsrc/parse.c +++ b/src/toolsrc/parse.c @@ -1,16 +1,19 @@ #include +#include #include "plasm.h" #define LVALUE 0 #define RVALUE 1 -#define LAMBDA_CNT 256 +#define MAX_LAMBDA 64 int infunc = 0, break_tag = 0, cont_tag = 0, stack_loop = 0; long infuncvals = 0; t_token prevstmnt; -int lambda_num = 0; -int lambda_cnt = 0; -*opseq lambda_seq[MAX_LAMBDA]; - +static int lambda_num = 0; +static int lambda_cnt = 0; +static t_opseq *lambda_seq[MAX_LAMBDA]; +static char lambda_id[MAX_LAMBDA][16]; +static int lambda_tag[MAX_LAMBDA]; +static int lambda_cparams[MAX_LAMBDA]; t_token binary_ops_table[] = { /* Highest precedence */ MUL_TOKEN, DIV_TOKEN, MOD_TOKEN, @@ -454,9 +457,9 @@ t_opseq *parse_value(t_opseq *codeseq, int rvalue, int *stackdepth) } else if (scantoken == LAMBDA_TOKEN) { - type |= WPTR_TYPE; + type |= CONST_TYPE; value = parse_lambda(); - valseq = gen_gbladr(NULL, value, type); + valseq = gen_gbladr(NULL, value, FUNC_TYPE); } else if (scantoken == OPEN_PAREN_TOKEN) { @@ -486,7 +489,7 @@ t_opseq *parse_value(t_opseq *codeseq, int rvalue, int *stackdepth) valseq = cat_seq(parse_list(NULL, &value), valseq); if (scantoken != CLOSE_PAREN_TOKEN) { - parse_error("Missing closing parenthesis"); + parse_error("Missing function call closing parenthesis"); return (NULL); } if (scan() == POUND_TOKEN) @@ -1461,16 +1464,21 @@ int parse_mods(void) } int parse_lambda(void) { - char lambda_id[16]; + int func_tag; + int cfnparms; + char *expr; if (!infunc) { - parse_error("Lambda functions only allowed in definitions"); + parse_error("Lambda functions only allowed inside definitions"); return (0); } + idlocal_save(); /* * Parse parameters and return value count */ + cfnparms = 0; + func_tag = tag_new(DEF_TYPE); if (scan() == OPEN_PAREN_TOKEN) { do @@ -1487,28 +1495,37 @@ int parse_lambda(void) parse_error("Bad function parameter list"); return (0); } - scan(); } - if (scantoken == OPEN_PAREN_TOKEN) + else + { + parse_error("Missing parameter list in lambda function"); + return (0); + } + expr = scanpos; + if (scan_lookahead() == OPEN_PAREN_TOKEN) { /* * Function call - parameters generate before call address */ - valseq = parse_list(NULL, NULL); + scan(); + lambda_seq[lambda_cnt] = parse_list(NULL, NULL); if (scantoken != CLOSE_PAREN_TOKEN) { - parse_error("Missing closing parenthesis"); - return (NULL); + parse_error("Missing closing lambda function parenthesis"); + return (0); } } else { - valseq = parse_expr(NULL, NULL); + lambda_seq[lambda_cnt] = parse_expr(NULL, NULL); + scan_rewind(tokenstr); } - lambda_seq[lambda_cnt++] = valseq; - func_tag = tag_new(DEF_TYPE); - sprintf(lambda_id, "_LAMBDA%04d", lambda_num++); - idfunc_add(idstr, strlen(idstr), DEF_TYPE | funcparms_type(cfnparms), func_tag); + lambda_cparams[lambda_cnt] = cfnparms; + lambda_tag[lambda_cnt] = func_tag; + sprintf(lambda_id[lambda_cnt], "_LAMBDA%04d", lambda_num++); + idfunc_add(lambda_id[lambda_cnt], strlen(lambda_id[lambda_cnt]), DEF_TYPE | funcparms_type(cfnparms), func_tag); + lambda_cnt++; + idlocal_restore(); return (func_tag); } int parse_defs(void) @@ -1622,6 +1639,8 @@ int parse_defs(void) emit_const(0); emit_leave(); } + while (lambda_cnt--) + emit_lambdafunc(lambda_tag[lambda_cnt], lambda_id[lambda_cnt], lambda_cparams[lambda_cnt], lambda_seq[lambda_cnt]); return (1); } else if (scantoken == ASM_TOKEN) diff --git a/src/toolsrc/symbols.h b/src/toolsrc/symbols.h index 5828901..c69b6d0 100755 --- a/src/toolsrc/symbols.h +++ b/src/toolsrc/symbols.h @@ -36,6 +36,8 @@ int idlocal_add(char *name, int len, int type, int size); int idglobal_add(char *name, int len, int type, int size); int id_add(char *name, int len, int type, int size); void idlocal_reset(void); +void idlocal_save(void); +void idlocal_restore(void); int idfunc_set(char *name, int len, int type, int tag); int idfunc_add(char *name, int len, int type, int tag); int idconst_add(char *name, int len, int value);