Browse Source

Add "let name = value, ... ;" to create local variables.

master
Ian Piumarta 1 year ago
parent
commit
ddff3e48e8
1 changed files with 51 additions and 5 deletions
  1. +51
    -5
      minproto.leg

+ 51
- 5
minproto.leg View File

@ -1,6 +1,6 @@
# minproto.leg -- minimal prototype langauge for semantic experiments
#
# last edited: 2024-05-09 10:17:11 by piumarta on zora-1034.local
# last edited: 2024-05-09 11:30:35 by piumarta on zora-1034.local
%{
;
@ -85,9 +85,9 @@ typedef oop (*prim_t)(oop func, oop self, oop args, oop env);
#endif
#if PRIMCLOSURE
#define doProtos(_) _(Object) _(GetVar) _(SetVar) _(GetProp) _(SetProp) _(GetArray) _(SetArray) _(Call) _(Invoke) _(Binop) _(Unyop) _(If) _(While) _(Block) _(For) _(ForIn) _(ForFromTo) _(Literal)
#define doProtos(_) _(Object) _(GetVar) _(SetVar) _(GetProp) _(SetProp) _(GetArray) _(SetArray) _(Call) _(Invoke) _(Binop) _(Unyop) _(Let) _(If) _(While) _(Block) _(For) _(ForIn) _(ForFromTo) _(Literal)
#else
#define doProtos(_) _(Object) _(GetVar) _(SetVar) _(GetProp) _(SetProp) _(GetArray) _(SetArray) _(Call) _(Invoke) _(Binop) _(Unyop) _(If) _(While) _(Block) _(For) _(ForIn) _(ForFromTo) _(Literal) _(Lambda) _(Closure)
#define doProtos(_) _(Object) _(GetVar) _(SetVar) _(GetProp) _(SetProp) _(GetArray) _(SetArray) _(Call) _(Invoke) _(Binop) _(Unyop) _(Let) _(If) _(While) _(Block) _(For) _(ForIn) _(ForFromTo) _(Literal) _(Lambda) _(Closure)
#endif
#define declareProto(NAME) oop p##NAME = 0;
@ -114,7 +114,7 @@ doTypes(makeProto);
doProperties(declareProp);
#undef declareProp
#define doSymbols(_) _(t) _(name) _(expr) _(function) _(arguments) _(object) _(index) _(key) _(value) _(self) _(method) _(parameters) _(body) _(lambda) _(environment) _(operation) _(full) _(condition) _(consequent) _(alternate) _(expression) _(identifier) _(initialise) _(update) _(first) _(last) _(fixed)
#define doSymbols(_) _(t) _(name) _(expr) _(function) _(arguments) _(object) _(index) _(key) _(value) _(self) _(method) _(parameters) _(body) _(lambda) _(environment) _(operation) _(full) _(condition) _(consequent) _(alternate) _(expression) _(identifier) _(initialise) _(update) _(first) _(last) _(fixed) _(keyvals)
#define declareSym(NAME) oop sym_##NAME = 0;
doSymbols(declareSym);
@ -1564,6 +1564,46 @@ void Unyop_codeOn(oop exp, oop str, oop env)
codeOn(str, value, 0);
}
oop newLet(void)
{
oop o = new(pLet);
Object_put(o, sym_keyvals, new(pObject));
return o;
}
oop Let_append(oop let, oop key, oop value)
{
oop keyvals = Object_getLocal(let, sym_keyvals);
Object_push(keyvals, key);
Object_push(keyvals, value);
return let;
}
oop Let_eval(oop exp, oop env)
{
oop keyvals = Object_getLocal(exp, sym_keyvals);
oop *indexed = get(keyvals, Object,indexed);
int isize = _get(keyvals, Object,isize);
oop result = nil;
for (int i = 0; i < isize - 1; i += 2)
Object_put(env, indexed[i], (result = eval(indexed[i+1], env)));
return result;
}
void Let_codeOn(oop exp, oop str, oop env)
{
oop keyvals = Object_getLocal(exp, sym_keyvals);
oop *indexed = get(keyvals, Object,indexed);
int isize = _get(keyvals, Object,isize);
String_appendAll(str, "let ");
for (int i = 0; i < isize - 1; i += 2) {
if (i) String_appendAll(str, ", ");
codeOn(str, indexed[i], 0);
String_appendAll(str, " = ");
codeOn(str, indexed[i+1], 0);
}
}
oop newIf(oop condition, oop consequent, oop alternate)
{
oop o = new(pIf);
@ -1871,7 +1911,10 @@ start = - ( s:stmt { yysval = s }
| < (!EOL .)* > { fatal("syntax error near: %s", yytext) }
)
stmt = WHILE LPAREN c:expr RPAREN s:stmt { $$ = newWhile(c, s) }
stmt = LET l:mklet k:id ASSIGN v:expr { Let_append(l, k, v) }
( COMMA k:id ASSIGN v:expr { Let_append(l, k, v) }
)* SEMI { $$ = l }
| WHILE LPAREN c:expr RPAREN s:stmt { $$ = newWhile(c, s) }
| IF LPAREN c:expr RPAREN s:stmt
( ELSE t:stmt { $$ = newIf(c, s, t ) }
| { $$ = newIf(c, s, nil) }
@ -1887,6 +1930,8 @@ stmt = WHILE LPAREN c:expr RPAREN s:stmt { $$ = newWhile(c, s) }
| b:block { $$ = newBlock(b) }
| e:expr EOS { $$ = e }
mklet = { $$ = newLet() }
proto = v:var ( DOT j:id !LPAREN { v = newGetProp(v, j) }
)* { $$ = v }
@ -2028,6 +2073,7 @@ FOR = "for" !ALNUM -
IN = "in" !ALNUM -
FROM = "from" !ALNUM -
TO = "to" !ALNUM -
LET = "let" !ALNUM -
BQUOTE = "`" -
COMMAT = "@" -

Loading…
Cancel
Save