浏览代码

Prefix 'local' constrins variables to be in current scope. Variable references, inrement operator l-values, and function definitions can all be qualified 'local' or 'global'.

master
Ian Piumarta 11 个月前
父节点
当前提交
e57242eb5d
共有 1 个文件被更改,包括 106 次插入27 次删除
  1. +106
    -27
      minproto.leg

+ 106
- 27
minproto.leg 查看文件

@ -1,6 +1,6 @@
# minproto.leg -- minimal prototype langauge for semantic experiments # minproto.leg -- minimal prototype langauge for semantic experiments
# #
# last edited: 2024-05-29 14:20:52 by piumarta on zora
# last edited: 2024-05-30 14:46:11 by piumarta on zora
%{ %{
; ;
@ -108,9 +108,9 @@ oop printOn(oop buf, oop obj, int indent);
#endif #endif
#if PRIMCLOSURE #if PRIMCLOSURE
#define doProtos(_) _(Object) _(RefSym) _(GetSym) _(SetSym) _(RefVar) _(GetVar) _(SetVar) _(RefProp) _(GetProp) _(SetProp) _(RefArray) _(GetArray) _(SetArray) _(Call) _(Invoke) _(Continue) _(Break) _(Return) _(TryCatch) _(TryEnsure)_(Raise)_(Binop) _(Unyop) _(If) _(While) _(Block) _(For) _(ForIn) _(ForFromTo) _(Literal)
#define doProtos(_) _(Object) _(RefLocal) _(GetLocal) _(SetLocal) _(RefGlobal) _(GetGlobal) _(SetGlobal) _(RefVar) _(GetVar) _(SetVar) _(RefProp) _(GetProp) _(SetProp) _(RefArray) _(GetArray) _(SetArray) _(Call) _(Invoke) _(Continue) _(Break) _(Return) _(TryCatch) _(TryEnsure)_(Raise)_(Binop) _(Unyop) _(If) _(While) _(Block) _(For) _(ForIn) _(ForFromTo) _(Literal)
#else #else
#define doProtos(_) _(Object) _(RefSym) _(GetSym) _(SetSym) _(RefVar) _(GetVar) _(SetVar) _(RefProp) _(GetProp) _(SetProp) _(RefArray) _(GetArray) _(SetArray) _(Call) _(Invoke) _(Continue) _(Break) _(Return) _(TryCatch) _(TryEnsure) _(Raise) _(Binop) _(Unyop) _(If) _(While) _(Block) _(For) _(ForIn) _(ForFromTo) _(Literal) _(Lambda) _(Closure)
#define doProtos(_) _(Object) _(RefLocal) _(GetLocal) _(SetLocal) _(RefGlobal) _(GetGlobal) _(SetGlobal) _(RefVar) _(GetVar) _(SetVar) _(RefProp) _(GetProp) _(SetProp) _(RefArray) _(GetArray) _(SetArray) _(Call) _(Invoke) _(Continue) _(Break) _(Return) _(TryCatch) _(TryEnsure) _(Raise) _(Binop) _(Unyop) _(If) _(While) _(Block) _(For) _(ForIn) _(ForFromTo) _(Literal) _(Lambda) _(Closure)
#endif #endif
#define declareProto(NAME) oop p##NAME = 0; #define declareProto(NAME) oop p##NAME = 0;
@ -824,9 +824,14 @@ oop setvar(oop obj, oop key, oop val)
if (ind >= 0) return _get(env, Object,properties)[ind].val = val; // set it if (ind >= 0) return _get(env, Object,properties)[ind].val = val; // set it
env = _getDelegate(env); env = _getDelegate(env);
} }
return (nil == obj) // are we at the top level?
? _get(key, Symbol,value) = val // set a global variable
: Object_put(obj, key, val); // create a new local variable
if (nil != obj) return Object_put(obj, key, val); // create a new local variable
int numspaces = _get(namespaces, Object,isize);
if (numspaces) {
oop *nss = _get(namespaces, Object,indexed);
oop ns = nss[numspaces - 1];
if (is(Object, ns)) return Object_put(ns, key, val); // define a namespace variable
}
return _get(key, Symbol,value) = val; // set a global variable
} }
oop Object_put(oop obj, oop key, oop val) oop Object_put(oop obj, oop key, oop val)
@ -1536,33 +1541,101 @@ extern inline oop mkptr(void *address)
return o; return o;
} }
oop newRefSym(oop name)
oop newRefLocal(oop name)
{
oop o = new(pRefLocal);
Object_put(o, sym_name, name);
return o;
}
oop RefLocal_eval(oop exp, oop env)
{
if (!is(Object, env)) valueError("local", "not in a local scope", exp);
oop sym = Object_get(exp, sym_name);
oop *ref = Object_refLocal(env, sym);
if (!ref) undefinedError(sym);
return mkptr(ref);
}
void RefLocal_codeOn(oop exp, oop str, oop env)
{
String_appendAll(str, "local ");
printOn(str, Object_get(exp, sym_name), 0);
}
oop newGetLocal(oop name)
{
oop o = new(pGetLocal);
Object_put(o, sym_name, name);
return o;
}
oop GetLocal_eval(oop exp, oop env)
{
if (!is(Object, env)) valueError("local", "not in a local scope", exp);
oop sym = Object_get(exp, sym_name);
oop *ref = Object_refLocal(env, sym);
if (!ref) undefinedError(sym);
return *ref;
}
void GetLocal_codeOn(oop exp, oop str, oop env)
{
String_appendAll(str, "local ");
printOn(str, Object_get(exp, sym_name), 0);
}
oop newSetLocal(oop name, oop value)
{
oop o = new(pSetLocal);
Object_put(o, sym_name, name);
Object_put(o, sym_value, value);
return o;
}
oop SetLocal_eval(oop exp, oop env)
{
if (!is(Object, env)) valueError("local", "not in a local scope", exp);
oop sym = Object_get(exp, sym_name );
oop val = eval(Object_get(exp, sym_value), env);
return Object_put(env, sym, val);
}
void SetLocal_codeOn(oop exp, oop str, oop env)
{
String_appendAll(str, "local ");
printOn(str, Object_get(exp, sym_name), 0);
String_appendAll(str, " = ");
codeOn(str, Object_get(exp, sym_value), 0);
}
oop newRefGlobal(oop name)
{ {
oop o = new(pRefSym);
oop o = new(pRefGlobal);
Object_put(o, sym_name, name); Object_put(o, sym_name, name);
return o; return o;
} }
oop RefSym_eval(oop exp, oop env)
oop RefGlobal_eval(oop exp, oop env)
{ {
oop sym = Object_get(exp, sym_name); oop sym = Object_get(exp, sym_name);
return mkptr(&_get(sym, Symbol,value)); return mkptr(&_get(sym, Symbol,value));
} }
void RefSym_codeOn(oop exp, oop str, oop env)
void RefGlobal_codeOn(oop exp, oop str, oop env)
{ {
String_appendAll(str, "global "); String_appendAll(str, "global ");
printOn(str, Object_get(exp, sym_name), 0); printOn(str, Object_get(exp, sym_name), 0);
} }
oop newGetSym(oop name)
oop newGetGlobal(oop name)
{ {
oop o = new(pGetSym);
oop o = new(pGetGlobal);
Object_put(o, sym_name, name); Object_put(o, sym_name, name);
return o; return o;
} }
oop GetSym_eval(oop exp, oop env)
oop GetGlobal_eval(oop exp, oop env)
{ {
oop sym = Object_get(exp, sym_name); oop sym = Object_get(exp, sym_name);
oop val = _get(sym, Symbol,value); oop val = _get(sym, Symbol,value);
@ -1570,28 +1643,28 @@ oop GetSym_eval(oop exp, oop env)
return val; return val;
} }
void GetSym_codeOn(oop exp, oop str, oop env)
void GetGlobal_codeOn(oop exp, oop str, oop env)
{ {
String_appendAll(str, "global "); String_appendAll(str, "global ");
printOn(str, Object_get(exp, sym_name), 0); printOn(str, Object_get(exp, sym_name), 0);
} }
oop newSetSym(oop name, oop value)
oop newSetGlobal(oop name, oop value)
{ {
oop o = new(pSetSym);
oop o = new(pSetGlobal);
Object_put(o, sym_name, name); Object_put(o, sym_name, name);
Object_put(o, sym_value, value); Object_put(o, sym_value, value);
return o; return o;
} }
oop SetSym_eval(oop exp, oop env)
oop SetGlobal_eval(oop exp, oop env)
{ {
oop sym = Object_get(exp, sym_name ) ; oop sym = Object_get(exp, sym_name ) ;
oop val = eval(Object_get(exp, sym_value), env); oop val = eval(Object_get(exp, sym_value), env);
return _set(sym, Symbol,value, val); return _set(sym, Symbol,value, val);
} }
void SetSym_codeOn(oop exp, oop str, oop env)
void SetGlobal_codeOn(oop exp, oop str, oop env)
{ {
String_appendAll(str, "global "); String_appendAll(str, "global ");
printOn(str, Object_get(exp, sym_name), 0); printOn(str, Object_get(exp, sym_name), 0);
@ -3067,10 +3140,11 @@ oop lvalue(oop rval)
{ {
if (!is(Object,rval)) valueError("=", "non-assignable value", rval); if (!is(Object,rval)) valueError("=", "non-assignable value", rval);
oop kind = _getDelegate(rval); oop kind = _getDelegate(rval);
if (kind == pGetVar ) kind = pRefVar;
else if (kind == pGetProp ) kind = pRefProp;
else if (kind == pGetArray) kind = pRefArray;
else if (kind == pGetSym ) kind = pRefSym;
if (kind == pGetVar ) kind = pRefVar;
else if (kind == pGetProp ) kind = pRefProp;
else if (kind == pGetArray ) kind = pRefArray;
else if (kind == pGetLocal ) kind = pRefLocal;
else if (kind == pGetGlobal) kind = pRefGlobal;
else valueError("=", "non-assignable value", rval); else valueError("=", "non-assignable value", rval);
_setDelegate(rval, kind); _setDelegate(rval, kind);
return rval; return rval;
@ -3083,7 +3157,6 @@ oop assign(oop rval, oop value)
if (kind == pGetVar ) kind = pSetVar; if (kind == pGetVar ) kind = pSetVar;
else if (kind == pGetProp ) kind = pSetProp; else if (kind == pGetProp ) kind = pSetProp;
else if (kind == pGetArray) kind = pSetArray; else if (kind == pGetArray) kind = pSetArray;
else if (kind == pGetSym ) kind = pSetSym;
else valueError("=", "non-assignable value", rval); else valueError("=", "non-assignable value", rval);
_setDelegate(rval, kind); _setDelegate(rval, kind);
Object_put(rval, sym_value, value); Object_put(rval, sym_value, value);
@ -3123,7 +3196,9 @@ stmt = WHILE LPAREN c:expr RPAREN s:stmt { $$ = newWhile(c, s) }
| ENSURE e:stmt { $$ = newTryEnsure(t, e) } | ENSURE e:stmt { $$ = newTryEnsure(t, e) }
) )
| RAISE e:expr EOS { $$ = newRaise(e) } | RAISE e:expr EOS { $$ = newRaise(e) }
| i:id p:params b:block { $$ = newSetVar(i, newLambda(p, b)) }
| LOCAL i:id p:params b:block { $$ = newSetLocal (i, newLambda(p, b)) }
| GLOBAL i:id p:params b:block { $$ = newSetGlobal(i, newLambda(p, b)) }
| i:id p:params b:block { $$ = newSetVar (i, newLambda(p, b)) }
| v:proto DOT i:id p:params b:block { $$ = newSetProp(v, i, newLambda(p, b)) } | v:proto DOT i:id p:params b:block { $$ = newSetProp(v, i, newLambda(p, b)) }
| b:block { $$ = newBlock(b) } | b:block { $$ = newBlock(b) }
| e:expr EOS { $$ = e } | e:expr EOS { $$ = e }
@ -3133,7 +3208,9 @@ proto = v:var ( DOT j:id !LPAREN { v = newGetProp(v, j) }
EOS = SEMI+ | &RBRACE | &ELSE | &CATCH EOS = SEMI+ | &RBRACE | &ELSE | &CATCH
expr = i:id ASSIGN e:expr { $$ = newSetVar(i, e) }
expr = LOCAL i:id ASSIGN e:expr { $$ = newSetLocal (i, e) }
| GLOBAL i:id ASSIGN e:expr { $$ = newSetGlobal(i, e) }
| i:id ASSIGN e:expr { $$ = newSetVar (i, e) }
| l:logor ( ASSIGN r:expr { l = assign(l, r) } | l:logor ( ASSIGN r:expr { l = assign(l, r) }
| PLUSEQ r:expr { l = newBinop(opPreAdd, lvalue(l), r) } | PLUSEQ r:expr { l = newBinop(opPreAdd, lvalue(l), r) }
| MINUSEQ r:expr { l = newBinop(opPreSub, lvalue(l), r) } | MINUSEQ r:expr { l = newBinop(opPreSub, lvalue(l), r) }
@ -3271,8 +3348,9 @@ char = "\\" ( ["'\\abfnrtv]
symbol = HASH i:id { $$ = i } symbol = HASH i:id { $$ = i }
var = GLOBAL i:id { $$ = newGetSym(i) }
| i:id { $$ = newGetVar(i) }
var = LOCAL i:id { $$ = newGetLocal (i) }
| GLOBAL i:id { $$ = newGetGlobal(i) }
| i:id { $$ = newGetVar (i) }
id = < LETTER ALNUM* > - { $$ = intern(yytext) } id = < LETTER ALNUM* > - { $$ = intern(yytext) }
@ -3308,6 +3386,7 @@ CATCH = "catch" !ALNUM -
ENSURE = "ensure" !ALNUM - ENSURE = "ensure" !ALNUM -
RAISE = "raise" !ALNUM - RAISE = "raise" !ALNUM -
GLOBAL = "global" !ALNUM - GLOBAL = "global" !ALNUM -
LOCAL = "local" !ALNUM -
BQUOTE = "`" - BQUOTE = "`" -
COMMAT = "@" - COMMAT = "@" -

正在加载...
取消
保存