|
|
@ -1,9 +1,11 @@ |
|
|
|
# minproto.leg -- minimal prototype langauge for semantic experiments |
|
|
|
# |
|
|
|
# last edited: 2024-05-14 12:14:06 by piumarta on zora |
|
|
|
# last edited: 2024-05-15 19:13:04 by piumarta on debian |
|
|
|
|
|
|
|
%{ |
|
|
|
; |
|
|
|
//#define YY_DEBUG 1 |
|
|
|
|
|
|
|
#ifndef GC |
|
|
|
# define GC 1 // do not fill memory with unreachable junk |
|
|
|
#endif |
|
|
@ -97,9 +99,9 @@ oop printOn(oop buf, oop obj, int indent); |
|
|
|
#endif |
|
|
|
|
|
|
|
#if PRIMCLOSURE |
|
|
|
#define doProtos(_) _(Object) _(RefVar) _(GetVar) _(SetVar) _(RefProp) _(GetProp) _(SetProp) _(RefArray) _(GetArray) _(SetArray) _(Call) _(Invoke) _(Continue) _(Break) _(Return) _(Binop) _(Unyop) _(Let) _(If) _(While) _(Block) _(For) _(ForIn) _(ForFromTo) _(Literal) |
|
|
|
#define doProtos(_) _(Object) _(RefVar) _(GetVar) _(SetVar) _(RefProp) _(GetProp) _(SetProp) _(RefArray) _(GetArray) _(SetArray) _(Call) _(Invoke) _(Continue) _(Break) _(Return) _(Binop) _(Unyop) _(Let) _(If) _(While) _(Block) _(For) _(ForIn) _(ForFromTo) _(Literal) _(Range) |
|
|
|
#else |
|
|
|
#define doProtos(_) _(Object) _(RefVar) _(GetVar) _(SetVar) _(RefProp) _(GetProp) _(SetProp) _(RefArray) _(GetArray) _(SetArray) _(Call) _(Invoke) _(Continue) _(Break) _(Return) _(Binop) _(Unyop) _(Let) _(If) _(While) _(Block) _(For) _(ForIn) _(ForFromTo) _(Literal) _(Lambda) _(Closure) |
|
|
|
#define doProtos(_) _(Object) _(RefVar) _(GetVar) _(SetVar) _(RefProp) _(GetProp) _(SetProp) _(RefArray) _(GetArray) _(SetArray) _(Call) _(Invoke) _(Continue) _(Break) _(Return) _(Binop) _(Unyop) _(Let) _(If) _(While) _(Block) _(For) _(ForIn) _(ForFromTo) _(Literal) _(Lambda) _(Closure) _(Range) |
|
|
|
#endif |
|
|
|
|
|
|
|
#define declareProto(NAME) oop p##NAME = 0; |
|
|
@ -127,7 +129,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) _(keyvals) _(__globals__) |
|
|
|
#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) _(__globals__) _(start) _(end) _(env) |
|
|
|
|
|
|
|
#define declareSym(NAME) oop sym_##NAME = 0; |
|
|
|
doSymbols(declareSym); |
|
|
@ -470,10 +472,10 @@ int stringLength(oop obj, char *who) |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
oop newPrimitive(prim_t function) |
|
|
|
oop newPrimitive(prim_t function, oop name) |
|
|
|
{ |
|
|
|
oop obj = make(Primitive); |
|
|
|
_set(obj, Primitive,name, 0); |
|
|
|
_set(obj, Primitive,name, name); |
|
|
|
_set(obj, Primitive,function, function); |
|
|
|
return obj; |
|
|
|
} |
|
|
@ -783,6 +785,119 @@ oop newObjectWith(int isize, oop *indexed, int psize, struct property *propertie |
|
|
|
return obj; |
|
|
|
} |
|
|
|
|
|
|
|
int isSpecial(oop key) |
|
|
|
{ |
|
|
|
return is(Symbol, key) && !strncmp("__", _get(key, Symbol,name), 2); |
|
|
|
} |
|
|
|
|
|
|
|
oop keys(oop self, int all) |
|
|
|
{ |
|
|
|
oop keys = new(pObject); |
|
|
|
# if DELOPT |
|
|
|
if (all && nil != _getDelegate(self)) Object_push(keys, prop_delegate); |
|
|
|
# endif |
|
|
|
switch (getType(self)) { |
|
|
|
case Undefined: case Integer: case Float: case String: case Symbol: case Primitive: |
|
|
|
break; |
|
|
|
# if PRIMCLOSURE |
|
|
|
case Lambda: { |
|
|
|
Object_push(keys, sym_parameters); |
|
|
|
Object_push(keys, sym_body); |
|
|
|
break; |
|
|
|
} |
|
|
|
case Closure: { |
|
|
|
Object_push(keys, sym_fixed); |
|
|
|
Object_push(keys, sym_lambda); |
|
|
|
Object_push(keys, sym_environment); |
|
|
|
break; |
|
|
|
} |
|
|
|
# endif |
|
|
|
case Object: { |
|
|
|
int size = _get(self, Object,psize); |
|
|
|
struct property *kvs = _get(self, Object,properties); |
|
|
|
for (int i = 0; i < size; ++i) { |
|
|
|
oop key = kvs[i].key; |
|
|
|
if (all || !isSpecial(key)) Object_push(keys, key); |
|
|
|
} |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
return keys; |
|
|
|
} |
|
|
|
|
|
|
|
intptr_t cmp(oop l, oop r, char *who) |
|
|
|
{ |
|
|
|
int tl = getType(l), tr = getType(r); |
|
|
|
if (Integer == tl && Integer == tr) return _integerValue(l) - _integerValue(r); |
|
|
|
if (Float == tl || Float == tr) return floatValue(l, who) - floatValue(r, who); |
|
|
|
if (String == tl && String == tr) { |
|
|
|
int ll = _get(l, String,length), rr = _get(r, String,length); |
|
|
|
if (ll == rr) return strncmp(_get(l, String,value), _get(r, String,value), ll); |
|
|
|
return ll - rr; |
|
|
|
} |
|
|
|
if (Symbol == tl && Symbol == tr) return strcmp(stringValue(l, who), stringValue(r, who)); |
|
|
|
return (intptr_t)l - (intptr_t)r; |
|
|
|
} |
|
|
|
|
|
|
|
#if defined (__linux__) |
|
|
|
int objcmp(const void *a, const void *b, void *who) { return cmp(*(oop *)a, *(oop *)b, who); } |
|
|
|
#else |
|
|
|
int objcmp(void *who, const void *a, const void *b) { return cmp(*(oop *)a, *(oop *)b, who); } |
|
|
|
#endif |
|
|
|
|
|
|
|
oop sortObject(oop obj, char *who) |
|
|
|
{ assert(is(Object, obj)); |
|
|
|
# if defined(__linux__) |
|
|
|
qsort_r(_get(obj, Object,indexed), _get(obj, Object,isize), sizeof(oop), objcmp, "sort"); |
|
|
|
# else |
|
|
|
qsort_r(_get(obj, Object,indexed), _get(obj, Object,isize), sizeof(oop), "sort", objcmp); |
|
|
|
# endif |
|
|
|
return obj; |
|
|
|
} |
|
|
|
|
|
|
|
int chrcmp(const void *a, const void *b) { return *(char *)a - *(char *)b; } |
|
|
|
|
|
|
|
oop sortString(oop obj) |
|
|
|
{ assert(is(String, obj)); |
|
|
|
qsort(_get(obj, String,value), _get(obj, String,length), 1, chrcmp); |
|
|
|
return obj; |
|
|
|
} |
|
|
|
|
|
|
|
oop clone(oop obj) // shallow copy |
|
|
|
{ |
|
|
|
switch (getType(obj)) { |
|
|
|
case String: return newStringLen(_get(obj, String,value), _get(obj, String,length)); |
|
|
|
case Object:{ |
|
|
|
oop clone = new(_getDelegate(obj)); |
|
|
|
oop *elts = _get(obj, Object,indexed); |
|
|
|
int size = _get(obj, Object,isize); |
|
|
|
for (int i = 0; i < size; ++i) Object_push(clone, elts[i]); |
|
|
|
struct property *kvs = _get(obj, Object,properties); |
|
|
|
size = _get(obj, Object,psize); |
|
|
|
for (int i = 0; i < size; ++i) { |
|
|
|
oop key = kvs[i].key; |
|
|
|
if (prop_delegate == key) continue; |
|
|
|
Object_put(clone, key, kvs[i].val); |
|
|
|
} |
|
|
|
return clone; |
|
|
|
} |
|
|
|
default: break; |
|
|
|
} |
|
|
|
return obj; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
oop sorted(oop obj, char *who) |
|
|
|
{ |
|
|
|
switch (getType(obj)) { |
|
|
|
case String: return sortString(clone(obj)); |
|
|
|
case Object: return sortObject(clone(obj), who); |
|
|
|
default: break; |
|
|
|
} |
|
|
|
fatal("sort: cannot sort %s", getTypeName(obj)); |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
oop apply(oop func, oop self, oop args, oop env); |
|
|
|
|
|
|
|
void codeParametersOn(oop str, oop object, char *begin, char *end) |
|
|
@ -822,7 +937,7 @@ oop codeOn(oop str, oop obj, int indent) |
|
|
|
case Symbol: String_format(str, "#%s", _get(obj, Symbol,name)); break; |
|
|
|
case Primitive: { |
|
|
|
String_appendAll(str, "<primitive "); |
|
|
|
if (_get(obj, Primitive,name)) codeOn(str, _get(obj, Primitive,name), indent); |
|
|
|
if (_get(obj, Primitive,name)) printOn(str, _get(obj, Primitive,name), 0); |
|
|
|
else String_format(str, "%p", _get(obj, Primitive,function)); |
|
|
|
String_append(str, '>'); |
|
|
|
break; |
|
|
@ -851,17 +966,97 @@ oop codeOn(oop str, oop obj, int indent) |
|
|
|
return str; |
|
|
|
} |
|
|
|
|
|
|
|
void indentOn(oop buf, int indent) |
|
|
|
{ |
|
|
|
if (indent < 1) return; |
|
|
|
String_append(buf, '\n'); |
|
|
|
for (int i = indent; i--;) String_appendAll(buf, " | "); |
|
|
|
String_appendAll(buf, " "); |
|
|
|
} |
|
|
|
|
|
|
|
void printObjectNameOn(oop buf, oop obj, int indent) |
|
|
|
{ |
|
|
|
int level = 0; |
|
|
|
oop proto = obj; |
|
|
|
oop name = nil; |
|
|
|
do { |
|
|
|
++level; |
|
|
|
name = Object_getLocal(proto, prop_name); |
|
|
|
if (nil != name) break; |
|
|
|
proto = _getDelegate(proto); |
|
|
|
} while (is(Object, proto)); |
|
|
|
for (int i = level; i--;) String_append(buf, '<'); |
|
|
|
if (name != nil) printOn(buf, name, 0); |
|
|
|
else String_appendAll(buf, "?"); |
|
|
|
for (int i = level; i--;) String_append(buf, '>'); |
|
|
|
} |
|
|
|
|
|
|
|
enum { |
|
|
|
NO_DELEGATE = -1, |
|
|
|
NO_SPECIALS = -2, |
|
|
|
}; |
|
|
|
|
|
|
|
int printObjectPropertiesOn(oop buf, oop obj, int indent) |
|
|
|
{ |
|
|
|
oop names = sortObject(keys(obj, indent > 0), "print"); |
|
|
|
int nkeys = _get(names, Object,isize); |
|
|
|
oop *elts = _get(names, Object,indexed); |
|
|
|
int i = 0; |
|
|
|
for (i = 0; i < nkeys; ++i) { |
|
|
|
if (i && indent < 1) String_appendAll(buf, ", "); |
|
|
|
oop key = elts[i]; |
|
|
|
if (prop_delegate == key) continue; |
|
|
|
indentOn(buf, indent); |
|
|
|
printOn(buf, key, 0); |
|
|
|
String_appendAll(buf, ": "); |
|
|
|
printOn(buf, Object_getLocal(obj, key), indent + (indent >= 0)); |
|
|
|
} |
|
|
|
return i; |
|
|
|
} |
|
|
|
|
|
|
|
oop printOn(oop buf, oop obj, int indent) |
|
|
|
{ |
|
|
|
switch (getType(obj)) { |
|
|
|
case Undefined: String_appendAll(buf, "nil"); break; |
|
|
|
case Integer: String_format(buf, "%ld", _integerValue(obj)); break; |
|
|
|
case Float: String_format(buf, "%f" , _floatValue(obj)); break; |
|
|
|
case String: String_format(buf, "%.*s", (int)_get(obj, String,length), _get(obj, String,value)); break; |
|
|
|
case Symbol: String_appendAll(buf, _get(obj, Symbol,name)); break; |
|
|
|
case Undefined: String_appendAll(buf, "nil"); break; |
|
|
|
case Integer: String_format(buf, "%ld", _integerValue(obj)); break; |
|
|
|
case Float: String_format(buf, "%f" , _floatValue(obj)); break; |
|
|
|
case String: { |
|
|
|
char *str = _get(obj, String,value); |
|
|
|
int len = _get(obj, String,length); |
|
|
|
if (indent && indent != 1) { |
|
|
|
String_append(buf, '"'); |
|
|
|
while (len--) { |
|
|
|
int c = *str++; |
|
|
|
if (c >= ' ' && c <= '~') String_append(buf, c); |
|
|
|
else if (c == '"') String_appendAll(buf, "\\\""); |
|
|
|
else if (c == '\\') String_appendAll(buf, "\\\\"); |
|
|
|
else { |
|
|
|
switch (c) { |
|
|
|
case '\a': c = 'a'; break; |
|
|
|
case '\b': c = 'b'; break; |
|
|
|
case '\f': c = 'f'; break; |
|
|
|
case '\n': c = 'n'; break; |
|
|
|
case '\r': c = 'r'; break; |
|
|
|
case '\t': c = 't'; break; |
|
|
|
case '\v': c = 'v'; break; |
|
|
|
defalt: String_format(buf, "\\%03o", c); continue; |
|
|
|
} |
|
|
|
String_format(buf, "\\%c", c); |
|
|
|
} |
|
|
|
} |
|
|
|
String_append(buf, '"'); |
|
|
|
return buf; |
|
|
|
} |
|
|
|
String_format(buf, "%.*s", len, str); |
|
|
|
break; |
|
|
|
} |
|
|
|
case Symbol: |
|
|
|
if (indent < 0) String_append(buf, '#'); |
|
|
|
String_appendAll(buf, _get(obj, Symbol,name)); |
|
|
|
break; |
|
|
|
case Primitive: { |
|
|
|
String_appendAll(buf, "<primitive "); |
|
|
|
if (_get(obj, Primitive,name)) printOn(buf, _get(obj, Primitive,name), indent); |
|
|
|
if (_get(obj, Primitive,name)) printOn(buf, _get(obj, Primitive,name), 0); |
|
|
|
else String_format(buf, "%p", _get(obj, Primitive,function)); |
|
|
|
String_append(buf, '>'); |
|
|
|
break; |
|
|
@ -869,65 +1064,40 @@ oop printOn(oop buf, oop obj, int indent) |
|
|
|
#if PRIMCLOSURE |
|
|
|
case Lambda: { |
|
|
|
String_appendAll(buf, "<<Lambda>>"); |
|
|
|
if (!indent) break; |
|
|
|
if (indent < 1) break; |
|
|
|
|
|
|
|
String_append(buf, '\n'); |
|
|
|
for (int j = indent; j--;) String_appendAll(buf, " | "); |
|
|
|
indentOn(buf, indent); |
|
|
|
String_appendAll(buf, " body: "); |
|
|
|
printOn(buf, _get(obj, Lambda,body), indent+1); |
|
|
|
printOn(buf, _get(obj, Lambda,body), indent + 1); |
|
|
|
|
|
|
|
String_append(buf, '\n'); |
|
|
|
for (int j = indent; j--;) String_appendAll(buf, " | "); |
|
|
|
String_appendAll(buf, " parameters: "); |
|
|
|
printOn(buf, _get(obj, Lambda,parameters), indent+1); |
|
|
|
printOn(buf, _get(obj, Lambda,parameters), indent + 1); |
|
|
|
break; |
|
|
|
} |
|
|
|
case Closure: { |
|
|
|
String_appendAll(buf, "<<Closure>>"); |
|
|
|
if (!indent) break; |
|
|
|
if (indent < 1) break; |
|
|
|
|
|
|
|
String_append(buf, '\n'); |
|
|
|
for (int j = indent; j--;) String_appendAll(buf, " | "); |
|
|
|
String_appendAll(buf, " environment: "); |
|
|
|
printOn(buf, _get(obj, Closure,environment), indent+1); |
|
|
|
printOn(buf, _get(obj, Closure,environment), indent + 1); |
|
|
|
|
|
|
|
String_append(buf, '\n'); |
|
|
|
for (int j = indent; j--;) String_appendAll(buf, " | "); |
|
|
|
String_appendAll(buf, " function: "); |
|
|
|
printOn(buf, _get(obj, Closure,function), indent+1); |
|
|
|
printOn(buf, _get(obj, Closure,function), indent + 1); |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
#endif |
|
|
|
case Object: { |
|
|
|
int level = 0; |
|
|
|
oop proto = obj; |
|
|
|
oop name = nil; |
|
|
|
do { |
|
|
|
++level; |
|
|
|
name = Object_getLocal(proto, prop_name); |
|
|
|
if (nil != name) break; |
|
|
|
proto = _getDelegate(proto); |
|
|
|
} while (is(Object, proto)); |
|
|
|
for (int i = level; i--;) String_append(buf, '<'); |
|
|
|
if (name != nil) |
|
|
|
printOn(buf, name, indent); |
|
|
|
else |
|
|
|
String_appendAll(buf, "?"); |
|
|
|
for (int i = level; i--;) String_append(buf, '>'); |
|
|
|
printObjectNameOn(buf, obj, indent); |
|
|
|
if (!indent) break; |
|
|
|
for (;;) { |
|
|
|
int psize = _get(obj, Object,psize); |
|
|
|
struct property *props = _get(obj, Object,properties); |
|
|
|
for (int i = 0; i < psize; ++i) { |
|
|
|
if (prop_delegate == props[i].key) continue; |
|
|
|
String_append(buf, '\n'); |
|
|
|
for (int j = indent; j--;) String_appendAll(buf, " | "); |
|
|
|
String_appendAll(buf, " "); |
|
|
|
printOn(buf, props[i].key, indent+1); |
|
|
|
String_appendAll(buf, ": "); |
|
|
|
printOn(buf, props[i].val, indent+1); |
|
|
|
} |
|
|
|
printObjectPropertiesOn(buf, obj, indent); |
|
|
|
int isize = _get(obj, Object,isize); |
|
|
|
oop *indexed = _get(obj, Object,indexed); |
|
|
|
for (int i = 0; i < isize; ++i) { |
|
|
@ -1170,18 +1340,18 @@ oop GetVar_eval(oop exp, oop env) { return getvar(env, Object_get( |
|
|
|
|
|
|
|
void GetVar_codeOn(oop exp, oop str, oop env) { printOn(str, Object_get(exp, sym_name), 0); } |
|
|
|
|
|
|
|
oop newSetVar(oop name, oop expr) |
|
|
|
oop newSetVar(oop name, oop value) |
|
|
|
{ |
|
|
|
oop o = new(pSetVar); |
|
|
|
Object_put(o, sym_name, name); |
|
|
|
Object_put(o, sym_expr, expr); |
|
|
|
Object_put(o, sym_name, name); |
|
|
|
Object_put(o, sym_value, value); |
|
|
|
return o; |
|
|
|
} |
|
|
|
|
|
|
|
oop SetVar_eval(oop exp, oop env) |
|
|
|
{ |
|
|
|
oop key = Object_get(exp, sym_name) ; |
|
|
|
oop val = eval(Object_get(exp, sym_expr), env); |
|
|
|
oop key = Object_get(exp, sym_name ) ; |
|
|
|
oop val = eval(Object_get(exp, sym_value), env); |
|
|
|
return setvar(env, key, val); |
|
|
|
} |
|
|
|
|
|
|
@ -1189,7 +1359,7 @@ void SetVar_codeOn(oop exp, oop str, oop env) |
|
|
|
{ |
|
|
|
printOn(str, Object_get(exp, sym_name), 0); |
|
|
|
String_appendAll(str, " = "); |
|
|
|
codeOn(str, Object_get(exp, sym_expr), 0); |
|
|
|
codeOn(str, Object_get(exp, sym_value), 0); |
|
|
|
} |
|
|
|
|
|
|
|
oop newRefProp(oop object, oop key) |
|
|
@ -1352,6 +1522,17 @@ oop GetArray_eval(oop exp, oop env) |
|
|
|
default: fatal("[]: %s is not indexable", storeString(obj, 0)); |
|
|
|
} |
|
|
|
} |
|
|
|
if (getType(ind) == Object && Object_get(ind, prop_name) == Object_get(pRange, prop_name)) { |
|
|
|
switch (getType(obj)) { |
|
|
|
case String: { |
|
|
|
int start = integerValue(eval(Object_get(ind, sym_start), env), "[..]"); |
|
|
|
int end = integerValue(eval(Object_get(ind, sym_end ), env), "[..]"); |
|
|
|
oop slice = newStringLen(String_aref(obj, start), end - start); |
|
|
|
return slice; |
|
|
|
} |
|
|
|
default: fatal("[]: %s is not range - indexable", storeString(obj, 0)); |
|
|
|
} |
|
|
|
} |
|
|
|
if (!is(Object, obj)) fatal("[]: %s is not an object", storeString(obj, 0)); |
|
|
|
return Object_getLocal(obj, ind); |
|
|
|
} |
|
|
@ -1401,6 +1582,25 @@ void SetArray_codeOn(oop exp, oop str, oop env) |
|
|
|
codeOn(str, Object_get(exp, sym_value), 0); |
|
|
|
} |
|
|
|
|
|
|
|
oop newRange(oop start, oop end) { |
|
|
|
oop o = new(pRange); |
|
|
|
Object_put(o, sym_start, start); |
|
|
|
Object_put(o, sym_end, end); |
|
|
|
return o; |
|
|
|
} |
|
|
|
|
|
|
|
oop Range_eval(oop exp, oop env) |
|
|
|
{ |
|
|
|
return exp; |
|
|
|
} |
|
|
|
|
|
|
|
void Range_codeOn(oop exp, oop str, oop env) |
|
|
|
{ |
|
|
|
codeOn(str, Object_get(exp, sym_start), 0); |
|
|
|
String_appendAll(str, ".."); |
|
|
|
codeOn(str, Object_get(exp, sym_end), 0); |
|
|
|
} |
|
|
|
|
|
|
|
oop newCall(oop function, oop arguments) |
|
|
|
{ |
|
|
|
oop o = new(pCall); |
|
|
@ -1618,6 +1818,7 @@ void Closure_codeOn(oop exp, oop str, oop env) |
|
|
|
_(Add, +) _(Sub, -) \ |
|
|
|
_(Mul, *) _(Div, /) _(Mod, %) \ |
|
|
|
_(PostAdd, ++) _(PostDec, --) \ |
|
|
|
_(PreSet, =) \ |
|
|
|
_(PreOr, |=) _(PreXor, ^=) _(PreAnd, &=) \ |
|
|
|
_(PreShl, >>=) _(PreShr, <<=) \ |
|
|
|
_(PreAdd, +=) _(PreSub, -=) \ |
|
|
@ -1675,20 +1876,6 @@ binop(binBitAnd, &); |
|
|
|
|
|
|
|
#undef binop |
|
|
|
|
|
|
|
intptr_t cmp(oop l, oop r, char *who) |
|
|
|
{ |
|
|
|
int tl = getType(l), tr = getType(r); |
|
|
|
if (Integer == tl && Integer == tr) return _integerValue(l) - _integerValue(r); |
|
|
|
if (Float == tl || Float == tr) return floatValue(l, who) - floatValue(r, who); |
|
|
|
if (String == tl && String == tr) { |
|
|
|
int ll = _get(l, String,length), rr = _get(r, String,length); |
|
|
|
if (ll == rr) return strncmp(_get(l, String,value), _get(r, String,value), ll); |
|
|
|
return ll - rr; |
|
|
|
} |
|
|
|
if (Symbol == tl && Symbol == tr) return strcmp(stringValue(l, who), stringValue(r, who)); |
|
|
|
return (intptr_t)l - (intptr_t)r; |
|
|
|
} |
|
|
|
|
|
|
|
#define newBoolean(TF) ((TF) ? sym_t : nil) |
|
|
|
|
|
|
|
#define binop(NAME, OP) \ |
|
|
@ -1735,6 +1922,12 @@ oop binPostDec(oop lhs, oop rhs) |
|
|
|
return value; |
|
|
|
} |
|
|
|
|
|
|
|
oop binPreSet(oop lhs, oop rhs) |
|
|
|
{ assert(isInteger(lhs)); |
|
|
|
oop *ref = (oop *)(intptr_t)_integerValue(lhs); assert(isInteger(rhs)); |
|
|
|
return *ref = rhs; |
|
|
|
} |
|
|
|
|
|
|
|
#define binop(NAME, OP) \ |
|
|
|
oop NAME(oop lhs, oop rhs) \ |
|
|
|
{ assert(isInteger(lhs)); \ |
|
|
@ -1914,6 +2107,10 @@ oop Binop_eval(oop exp, oop env) |
|
|
|
} |
|
|
|
return value; |
|
|
|
} |
|
|
|
case opPreSet: { assert(isInteger(lhs)); // ref |
|
|
|
oop *ref = (oop *)(intptr_t)_integerValue(lhs); |
|
|
|
return *ref = rhs; |
|
|
|
} |
|
|
|
case opPreOr ... opPreMod: { assert(isInteger(lhs)); // ref |
|
|
|
oop *ref = (oop *)(intptr_t)_integerValue(lhs); |
|
|
|
oop val = *ref; assert(isInteger(rhs)); // delta |
|
|
@ -2482,6 +2679,31 @@ void Literal_codeOn(oop exp, oop str, oop env) |
|
|
|
# endif |
|
|
|
} |
|
|
|
|
|
|
|
oop lvalue(oop rval) |
|
|
|
{ |
|
|
|
if (!is(Object,rval)) fatal("cannot assign to: %s", codeString(rval, 0)); |
|
|
|
oop kind = _getDelegate(rval); |
|
|
|
if (kind == pGetVar ) kind = pRefVar; |
|
|
|
else if (kind == pGetProp ) kind = pRefProp; |
|
|
|
else if (kind == pGetArray) kind = pRefArray; |
|
|
|
else fatal("cannot assign to: %s", codeString(rval, 0)); |
|
|
|
_setDelegate(rval, kind); |
|
|
|
return rval; |
|
|
|
} |
|
|
|
|
|
|
|
oop assign(oop rval, oop value) |
|
|
|
{ |
|
|
|
if (!is(Object,rval)) fatal("cannot assign to: %s", codeString(rval, 0)); |
|
|
|
oop kind = _getDelegate(rval); |
|
|
|
if (kind == pGetVar ) kind = pSetVar; |
|
|
|
else if (kind == pGetProp ) kind = pSetProp; |
|
|
|
else if (kind == pGetArray) kind = pSetArray; |
|
|
|
else fatal("cannot assign to: %s", codeString(rval, 0)); |
|
|
|
_setDelegate(rval, kind); |
|
|
|
Object_put(rval, sym_value, value); |
|
|
|
return rval; |
|
|
|
} |
|
|
|
|
|
|
|
%} |
|
|
|
|
|
|
|
|
|
|
@ -2521,23 +2743,19 @@ proto = v:var ( DOT j:id !LPAREN { v = newGetProp(v, j) } |
|
|
|
|
|
|
|
EOS = SEMI+ | &RBRACE | &ELSE |
|
|
|
|
|
|
|
expr = p:postfix |
|
|
|
( DOT i:id ASSIGN e:expr { $$ = newSetProp(p, i, e) } |
|
|
|
| LBRAK i:expr RBRAK ASSIGN e:expr { $$ = newSetArray(p, i, e) } |
|
|
|
) |
|
|
|
| i:id ASSIGN e:expr { $$ = newSetVar(i, e) } |
|
|
|
| l:lvalue ( PLUSEQ r:expr { $$ = newBinop(opPreAdd, l, r) } |
|
|
|
| MINUSEQ r:expr { $$ = newBinop(opPreSub, l, r) } |
|
|
|
| STAREQ r:expr { $$ = newBinop(opPreMul, l, r) } |
|
|
|
| SLASHEQ r:expr { $$ = newBinop(opPreDiv, l, r) } |
|
|
|
| PCENTEQ r:expr { $$ = newBinop(opPreMod, l, r) } |
|
|
|
| SHLEQ r:expr { $$ = newBinop(opPreShl, l, r) } |
|
|
|
| SHREQ r:expr { $$ = newBinop(opPreShr, l, r) } |
|
|
|
| ANDEQ r:expr { $$ = newBinop(opPreAnd, l, r) } |
|
|
|
| XOREQ r:expr { $$ = newBinop(opPreXor, l, r) } |
|
|
|
| OREQ r:expr { $$ = newBinop(opPreOr, l, r) } |
|
|
|
) |
|
|
|
| logor |
|
|
|
expr = i:id ASSIGN e:expr { $$ = newSetVar(i, e) } |
|
|
|
| l:logor ( ASSIGN r:expr { l = assign(l, r) } |
|
|
|
| PLUSEQ r:expr { l = newBinop(opPreAdd, lvalue(l), r) } |
|
|
|
| MINUSEQ r:expr { l = newBinop(opPreSub, lvalue(l), r) } |
|
|
|
| STAREQ r:expr { l = newBinop(opPreMul, lvalue(l), r) } |
|
|
|
| SLASHEQ r:expr { l = newBinop(opPreDiv, lvalue(l), r) } |
|
|
|
| PCENTEQ r:expr { l = newBinop(opPreMod, lvalue(l), r) } |
|
|
|
| SHLEQ r:expr { l = newBinop(opPreShl, lvalue(l), r) } |
|
|
|
| SHREQ r:expr { l = newBinop(opPreShr, lvalue(l), r) } |
|
|
|
| ANDEQ r:expr { l = newBinop(opPreAnd, lvalue(l), r) } |
|
|
|
| XOREQ r:expr { l = newBinop(opPreXor, lvalue(l), r) } |
|
|
|
| OREQ r:expr { l = newBinop(opPreOr, lvalue(l), r) } |
|
|
|
)? { $$ = l } |
|
|
|
|
|
|
|
logor = l:logand ( BARBAR r:logand { l = newBinop(opLogOr, l, r) } |
|
|
|
)* { $$ = l } |
|
|
@ -2572,13 +2790,16 @@ sum = l:prod ( PLUS r:prod { l = newBinop(opAdd, l, r) } |
|
|
|
| MINUS r:prod { l = newBinop(opSub, l, r) } |
|
|
|
)* { $$ = l } |
|
|
|
|
|
|
|
prod = l:prefix ( STAR r:prefix { l = newBinop(opMul, l, r) } |
|
|
|
| SLASH r:prefix { l = newBinop(opDiv, l, r) } |
|
|
|
| PCENT r:prefix { l = newBinop(opMod, l, r) } |
|
|
|
)* { $$ = l } |
|
|
|
prod = l:range ( STAR r:range { l = newBinop(opMul, l, r) } |
|
|
|
| SLASH r:range { l = newBinop(opDiv, l, r) } |
|
|
|
| PCENT r:range { l = newBinop(opMod, l, r) } |
|
|
|
) * { $$ = l } |
|
|
|
|
|
|
|
prefix = PPLUS l:lvalue { $$ = newBinop(opPreAdd, l, newInteger(1)) } |
|
|
|
| MMINUS l:lvalue { $$ = newBinop(opPreSub, l, newInteger(1)) } |
|
|
|
range = i1:prefix ( DOTDOT i2:prefix { i1 = newRange(i1, i2) } |
|
|
|
) ? { $$ = i1 } |
|
|
|
|
|
|
|
prefix = PPLUS p:prefix { $$ = newBinop(opPreAdd, lvalue(p), newInteger(1)) } |
|
|
|
| MMINUS p:prefix { $$ = newBinop(opPreSub, lvalue(p), newInteger(1)) } |
|
|
|
| PLING p:prefix { $$ = newUnyop(opNot, p) } |
|
|
|
| MINUS p:prefix { $$ = newUnyop(opNeg, p) } |
|
|
|
| TILDE p:prefix { $$ = newUnyop(opCom, p) } |
|
|
@ -2586,41 +2807,35 @@ prefix = PPLUS l:lvalue { $$ = newBinop(opPreAdd, l, new |
|
|
|
| COMMAT e:expr { $$ = newUnyop(opUnquote, e) } |
|
|
|
| postfix |
|
|
|
|
|
|
|
lvalue = |
|
|
|
l:primary |
|
|
|
( LBRAK e:expr RBRAK &(DOT | LBRAK | LPAREN) { l = newGetArray(l, e) } |
|
|
|
| DOT i:id a:args &(DOT | LBRAK | LPAREN) { l = newInvoke(l, i, a) } |
|
|
|
| DOT i:id &(DOT | LBRAK | LPAREN) { l = newGetProp(l, i) } |
|
|
|
| a:args &(DOT | LBRAK | LPAREN) { l = newApply(l, a) } |
|
|
|
postfix = p:primary |
|
|
|
( LBRAK e:expr RBRAK { p = newGetArray(p, e) } |
|
|
|
| DOT i:id ( a:args !LBRACE { p = newInvoke(p, i, a) } |
|
|
|
| { p = newGetProp(p, i) } |
|
|
|
) |
|
|
|
| a:args !LBRACE { p = newApply(p, a) } |
|
|
|
)* |
|
|
|
( LBRAK e:expr RBRAK { l = newRefArray(l, e) } |
|
|
|
| DOT i:id { l = newRefProp(l, i) } |
|
|
|
) { $$ = l } |
|
|
|
| |
|
|
|
i:id { $$ = newRefVar(i) } |
|
|
|
|
|
|
|
postfix = l:lvalue ( PPLUS { $$ = newBinop(opPostAdd, l, newInteger( 1)) } |
|
|
|
| MMINUS { $$ = newBinop(opPostAdd, l, newInteger(-1)) } |
|
|
|
) |
|
|
|
| p:primary |
|
|
|
( LBRAK e:expr RBRAK !ASSIGN { p = newGetArray(p, e) } |
|
|
|
| DOT i:id a:args !ASSIGN !LBRACE { p = newInvoke(p, i, a) } |
|
|
|
| DOT i:id !ASSIGN { p = newGetProp(p, i) } |
|
|
|
| a:args !ASSIGN !LBRACE { p = newApply(p, a) } |
|
|
|
)* { $$ = p } |
|
|
|
( PPLUS { p = newBinop(opPostAdd, lvalue(p), newInteger( 1)) } |
|
|
|
| MMINUS { p = newBinop(opPostAdd, lvalue(p), newInteger(-1)) } |
|
|
|
)? { $$ = p } |
|
|
|
|
|
|
|
args = LPAREN a:mkobj |
|
|
|
( ( k:id COLON e:expr { Object_put(a, k, e) } |
|
|
|
| e:expr { Object_push(a, e) } |
|
|
|
( RPAREN |
|
|
|
| ( k:id COLON e:expr { Object_put(a, k, e) } |
|
|
|
| e:expr { Object_push(a, e) } |
|
|
|
) |
|
|
|
( COMMA ( k:id COLON e:expr { Object_put(a, k, e) } |
|
|
|
| e:expr { Object_push(a, e) } |
|
|
|
) )* )? RPAREN { $$ = a } |
|
|
|
( COMMA ( k:id COLON e:expr { Object_put(a, k, e) } |
|
|
|
| e:expr { Object_push(a, e) } |
|
|
|
) )* RPAREN ) { $$ = a } |
|
|
|
|
|
|
|
params = LPAREN p:mkobj |
|
|
|
( i:id { Object_push(p, i) } |
|
|
|
( COMMA i:id { Object_push(p, i) } |
|
|
|
)* )? RPAREN { $$ = p } |
|
|
|
( RPAREN |
|
|
|
| i:id ( COLON e:expr { Object_put(p, i, e) } |
|
|
|
| { Object_push(p, i) } |
|
|
|
) |
|
|
|
( COMMA i:id ( COLON e:expr { Object_put(p, i, e) } |
|
|
|
| { Object_push(p, i) } |
|
|
|
) |
|
|
|
)* RPAREN ) { $$ = p } |
|
|
|
|
|
|
|
mkobj = { $$ = new(pObject) } |
|
|
|
|
|
|
@ -2632,11 +2847,12 @@ subexpr = LPAREN e:expr RPAREN { $$ = e } |
|
|
|
| b:block { $$ = newBlock(b) } |
|
|
|
|
|
|
|
literal = LBRAK o:mkobj |
|
|
|
( ( i:id COLON e:expr { Object_put(o, i, e) } |
|
|
|
| e:expr { Object_push(o, e) } |
|
|
|
) ( COMMA ( i:id COLON e:expr { Object_put(o, i, e) } |
|
|
|
| e:expr { Object_push(o, e) } |
|
|
|
) )* )? RBRAK { $$ = newLiteral(o) } |
|
|
|
( RBRAK |
|
|
|
| ( ( i:id COLON e:expr { Object_put(o, i, e) } |
|
|
|
| e:expr { Object_push(o, e) } |
|
|
|
) ( COMMA ( i:id COLON e:expr { Object_put(o, i, e) } |
|
|
|
| e:expr { Object_push(o, e) } |
|
|
|
) )* )? RBRAK ) { $$ = newLiteral(o) } |
|
|
|
|
|
|
|
block = LBRACE b:mkobj |
|
|
|
( e:stmt { Object_push(b, e) } |
|
|
@ -2644,19 +2860,24 @@ block = LBRACE b:mkobj |
|
|
|
|
|
|
|
nil = NIL { $$ = nil } |
|
|
|
|
|
|
|
number = "-" u:unsign { $$ = neg(u) } |
|
|
|
| "+" n:number { $$ = u } |
|
|
|
| u:unsign { $$ = u } |
|
|
|
number = "-" n:unsign { $$ = neg(n) } |
|
|
|
| "+" n:number { $$ = n } |
|
|
|
| n:unsign { $$ = n } |
|
|
|
|
|
|
|
unsign = < DIGIT+ '.' DIGIT* EXP? > - { $$ = newFloat(strtod(yytext, 0)) } |
|
|
|
| < DIGIT* '.' DIGIT+ EXP? > - { $$ = newFloat(strtod(yytext, 0)) } |
|
|
|
unsign = < DIGIT* '.' DIGIT+ EXP? > - { $$ = newFloat(strtod(yytext, 0)) } |
|
|
|
| "0" [bB] < BIGIT+ > - { $$ = newInteger(strtol(yytext, 0, 2)) } |
|
|
|
| "0" [xX] < HIGIT+ > - { $$ = newInteger(strtol(yytext, 0, 16)) } |
|
|
|
| "0" < OIGIT* > - { $$ = newInteger(strtol(yytext, 0, 8)) } |
|
|
|
| < DIGIT+ > - { $$ = newInteger(strtol(yytext, 0, 10)) } |
|
|
|
|
|
|
|
string = '"' < ( !'"' . )* > '"' - { $$ = newStringEscaped(yytext) } |
|
|
|
| "'" < ( !"'" . )* > "'" - { $$ = newStringEscaped(yytext) } |
|
|
|
string = '"' < ( !'"' char )* > '"' - { $$ = newStringEscaped(yytext) } |
|
|
|
| "'" < ( !"'" char )* > "'" - { $$ = newStringEscaped(yytext) } |
|
|
|
|
|
|
|
char = "\\" ( ["'\\abfnrtv] |
|
|
|
| [xX] HIGIT* |
|
|
|
| [0-7][0-7]?[0-7]? |
|
|
|
) |
|
|
|
| . |
|
|
|
|
|
|
|
symbol = HASH i:id { $$ = i } |
|
|
|
|
|
|
@ -2734,7 +2955,8 @@ SLASH = "/" ![/=] - |
|
|
|
SLASHEQ = "/=" - |
|
|
|
PCENT = "%" ![=] - |
|
|
|
PCENTEQ = "%=" - |
|
|
|
DOT = "." - |
|
|
|
DOT = "." ![.] - |
|
|
|
DOTDOT = ".." - |
|
|
|
PLING = "!" ![=] - |
|
|
|
TILDE = "~" - |
|
|
|
|
|
|
@ -2794,8 +3016,15 @@ oop apply(oop func, oop self, oop args, oop env) |
|
|
|
case NLR_RETURN: return nlrPop(); |
|
|
|
} |
|
|
|
# endif |
|
|
|
// positional args -> named parameters |
|
|
|
for (int i = 0; i < nparam; ++i) |
|
|
|
Object_put(args, pparam[i], i < nargs ? pargs[i] : nil); |
|
|
|
// keyword defaults |
|
|
|
int nkeywd = _get(parameters, Object,psize); |
|
|
|
struct property *pkeywd = _get(parameters, Object,properties); |
|
|
|
for (int i = 0; i < nkeywd; ++i) |
|
|
|
if (Object_find(args, pkeywd[i].key) < 0) |
|
|
|
Object_put(args, pkeywd[i].key, eval(pkeywd[i].val, args)); |
|
|
|
for (int i = 0; i < size; ++i) |
|
|
|
result = eval(exprs[i], args); |
|
|
|
# if NONLOCAL |
|
|
@ -2930,57 +3159,23 @@ oop prim_length(oop func, oop self, oop args, oop env) |
|
|
|
return newInteger(_get(self, Object,isize)); |
|
|
|
} |
|
|
|
|
|
|
|
oop sortObject(oop obj, char *who) |
|
|
|
oop prim_keys(oop func, oop self, oop args, oop env) |
|
|
|
{ |
|
|
|
int limit = _get(obj, Object,isize); |
|
|
|
oop *elts = _get(obj, Object,indexed); |
|
|
|
for (int i = 0; i < limit - 1; ++i) { |
|
|
|
int mindex = i; |
|
|
|
oop minobj = elts[i]; |
|
|
|
for (int j = i + 1; j < limit; ++j) { |
|
|
|
oop newobj = elts[j]; |
|
|
|
if (cmp(newobj, minobj, who) < 0) mindex = j, minobj = newobj; |
|
|
|
} |
|
|
|
if (mindex != i) { |
|
|
|
oop tmpobj = elts[i]; |
|
|
|
elts[i] = minobj; |
|
|
|
elts[mindex] = tmpobj; |
|
|
|
} |
|
|
|
} |
|
|
|
return obj; |
|
|
|
return keys(self, 0); |
|
|
|
} |
|
|
|
|
|
|
|
oop prim_keys(oop func, oop self, oop args, oop env) |
|
|
|
oop prim_allKeys(oop func, oop self, oop args, oop env) |
|
|
|
{ |
|
|
|
oop keys = new(pObject); |
|
|
|
# if DELOPT |
|
|
|
if (nil != _getDelegate(self)) Object_push(keys, prop_delegate); |
|
|
|
# endif |
|
|
|
switch (getType(self)) { |
|
|
|
case Undefined: case Integer: case Float: case String: case Symbol: case Primitive: |
|
|
|
break; |
|
|
|
case Object: { |
|
|
|
int size = _get(self, Object,psize); |
|
|
|
struct property *kvs = _get(self, Object,properties); |
|
|
|
for (int i = 0; i < size; ++i) Object_push(keys, kvs[i].key); |
|
|
|
sortObject(keys, "keys"); |
|
|
|
break; |
|
|
|
} |
|
|
|
# if PRIMCLOSURE |
|
|
|
case Lambda: { |
|
|
|
Object_push(keys, sym_parameters); |
|
|
|
Object_push(keys, sym_body); |
|
|
|
break; |
|
|
|
} |
|
|
|
case Closure: { |
|
|
|
Object_push(keys, sym_fixed); |
|
|
|
Object_push(keys, sym_lambda); |
|
|
|
Object_push(keys, sym_environment); |
|
|
|
break; |
|
|
|
} |
|
|
|
# endif |
|
|
|
return keys(self, 1); |
|
|
|
} |
|
|
|
|
|
|
|
oop prim_sorted(oop func, oop self, oop args, oop env) |
|
|
|
{ assert(is(Object, args)); |
|
|
|
if (self == nil) { |
|
|
|
if (_get(args, Object,isize) != 1) fatal("sorted: one argument expected"); |
|
|
|
self = _get(args, Object,indexed)[0]; |
|
|
|
} |
|
|
|
return keys; |
|
|
|
return sorted(self, "sorted"); |
|
|
|
} |
|
|
|
|
|
|
|
oop prim_env(oop func, oop self, oop args, oop env) |
|
|
@ -2993,6 +3188,11 @@ oop prim_eval(oop func, oop self, oop args, oop env) |
|
|
|
int argc = _get(args, Object,isize); |
|
|
|
oop *indexed = _get(args, Object,indexed); |
|
|
|
oop result = nil; |
|
|
|
|
|
|
|
if (nil != Object_getLocal(args, sym_env)) { |
|
|
|
env = Object_getLocal(args, sym_env); |
|
|
|
} |
|
|
|
|
|
|
|
for (int i = 0; i < argc; ++i) result = eval(indexed[i], env); |
|
|
|
return result; |
|
|
|
} |
|
|
@ -3002,13 +3202,29 @@ oop prim___eval__(oop func, oop self, oop args, oop env) |
|
|
|
return self; |
|
|
|
} |
|
|
|
|
|
|
|
oop prim_intern(oop func, oop self, oop args, oop env) |
|
|
|
{ |
|
|
|
int argc = _get(args, Object,isize); |
|
|
|
oop *indexed = _get(args, Object,indexed); |
|
|
|
oop result = nil; |
|
|
|
|
|
|
|
if (argc != 1) { |
|
|
|
fatal("intern: invalid number of arguments"); |
|
|
|
} |
|
|
|
if (getType(indexed[0]) != String) { |
|
|
|
fatal("intern: argument is not of type String, got %s instead", getTypeName(indexed[0])); |
|
|
|
} |
|
|
|
|
|
|
|
return intern(_get(indexed[0], String, value)); |
|
|
|
} |
|
|
|
|
|
|
|
oop prim_print(oop func, oop self, oop args, oop env) |
|
|
|
{ |
|
|
|
int argc = _get(args, Object,isize); |
|
|
|
oop *indexed = _get(args, Object,indexed); |
|
|
|
oop result = nil; |
|
|
|
int indent = 0; |
|
|
|
if (nil != Object_getLocal(args, sym_full)) indent = 1; |
|
|
|
oop full = Object_getLocal(args, sym_full); |
|
|
|
int indent = isInteger(full) ? _integerValue(full) : nil != full; |
|
|
|
for (int i = 0; i < argc; ++i) print(result = indexed[i], indent); |
|
|
|
fflush(stdout); |
|
|
|
return nil; |
|
|
@ -3137,7 +3353,7 @@ oop prim_exit(oop func, oop self, oop args, oop env) |
|
|
|
oop replFile(FILE *in) |
|
|
|
{ |
|
|
|
int oldline = lineno; |
|
|
|
lineno = 0; |
|
|
|
lineno = 1; |
|
|
|
input = newInput(); |
|
|
|
readFile(in, &input->text, &input->size); |
|
|
|
oop result = nil; |
|
|
@ -3203,7 +3419,7 @@ int main(int argc, char **argv) |
|
|
|
|
|
|
|
# undef defineProto |
|
|
|
|
|
|
|
Object_put(pObject, prop_eval, newPrimitive(prim___eval__)); // inherited by all objects |
|
|
|
Object_put(pObject, prop_eval, newPrimitive(prim___eval__, newString("Object.__eval__"))); // inherited by all objects |
|
|
|
|
|
|
|
#if TYPECODES |
|
|
|
|
|
|
@ -3212,7 +3428,7 @@ int main(int argc, char **argv) |
|
|
|
#else // !TYPECODES |
|
|
|
|
|
|
|
# define defineEvaluator(NAME) \ |
|
|
|
Object_put(p##NAME, prop_eval, newPrimitive(prim_##NAME##_eval)); |
|
|
|
Object_put(p##NAME, prop_eval, newPrimitive(prim_##NAME##_eval, newString(#NAME".__eval__"))); |
|
|
|
|
|
|
|
#endif // !TYPECODES |
|
|
|
|
|
|
@ -3221,7 +3437,7 @@ int main(int argc, char **argv) |
|
|
|
# undef defineEvaluator |
|
|
|
|
|
|
|
# define defineCodeOn(NAME) \ |
|
|
|
Object_put(p##NAME, prop_codeon, newPrimitive(prim_##NAME##_codeOn)); |
|
|
|
Object_put(p##NAME, prop_codeon, newPrimitive(prim_##NAME##_codeOn, newString(#NAME".codeOn"))); |
|
|
|
|
|
|
|
doProtos(defineCodeOn); |
|
|
|
|
|
|
@ -3229,26 +3445,37 @@ int main(int argc, char **argv) |
|
|
|
|
|
|
|
macros = Object_put(pSymbol, intern("macros"), new(pObject)); |
|
|
|
|
|
|
|
_set(intern("__env__" ), Symbol,value, newPrimitive(prim_env)); |
|
|
|
_set(intern("eval" ), Symbol,value, newPrimitive(prim_eval)); |
|
|
|
_set(intern("print" ), Symbol,value, newPrimitive(prim_print)); |
|
|
|
_set(intern("codeString" ), Symbol,value, newPrimitive(prim_codeString)); |
|
|
|
_set(intern("sqrt" ), Symbol,value, newPrimitive(prim_sqrt)); |
|
|
|
_set(intern("round" ), Symbol,value, newPrimitive(prim_round)); |
|
|
|
_set(intern("truncate" ), Symbol,value, newPrimitive(prim_truncate)); |
|
|
|
_set(intern("cputime" ), Symbol,value, newPrimitive(prim_cputime)); |
|
|
|
_set(intern("evaluations"), Symbol,value, newPrimitive(prim_evaluations)); |
|
|
|
_set(intern("len" ), Symbol,value, newPrimitive(prim_len)); |
|
|
|
_set(intern("ord" ), Symbol,value, newPrimitive(prim_ord)); |
|
|
|
_set(intern("chr" ), Symbol,value, newPrimitive(prim_chr)); |
|
|
|
_set(intern("readfile" ), Symbol,value, newPrimitive(prim_readfile)); |
|
|
|
_set(intern("exit" ), Symbol,value, newPrimitive(prim_exit)); |
|
|
|
|
|
|
|
Object_put(pObject, intern("new"), newPrimitive(prim_new )); |
|
|
|
Object_put(pObject, intern("push"), newPrimitive(prim_push )); |
|
|
|
Object_put(pObject, intern("pop"), newPrimitive(prim_pop )); |
|
|
|
Object_put(pObject, intern("length"), newPrimitive(prim_length)); |
|
|
|
Object_put(pObject, intern("keys"), newPrimitive(prim_keys )); |
|
|
|
# define prim(NAME, FUNC) _set(intern(#NAME), Symbol,value, newPrimitive(FUNC, newString(#NAME))) |
|
|
|
|
|
|
|
prim(__env__ , prim_env); |
|
|
|
prim(eval , prim_eval); |
|
|
|
prim(print , prim_print); |
|
|
|
prim(codeString , prim_codeString); |
|
|
|
prim(sqrt , prim_sqrt); |
|
|
|
prim(round , prim_round); |
|
|
|
prim(truncate , prim_truncate); |
|
|
|
prim(cputime , prim_cputime); |
|
|
|
prim(evaluations, prim_evaluations); |
|
|
|
prim(len , prim_len); |
|
|
|
prim(ord , prim_ord); |
|
|
|
prim(chr , prim_chr); |
|
|
|
prim(readfile , prim_readfile); |
|
|
|
prim(exit , prim_exit); |
|
|
|
prim(intern , prim_intern); |
|
|
|
|
|
|
|
# undef prim |
|
|
|
|
|
|
|
# define method(CLASS, NAME, FUNC) Object_put(p##CLASS, intern(#NAME), newPrimitive(FUNC, newString(#CLASS"."#NAME))) |
|
|
|
|
|
|
|
method(Object,new, prim_new ); |
|
|
|
method(Object,push, prim_push ); |
|
|
|
method(Object,pop, prim_pop ); |
|
|
|
method(Object,length, prim_length ); |
|
|
|
method(Object,keys, prim_keys ); |
|
|
|
method(Object,allKeys, prim_allKeys); |
|
|
|
method(Object,sorted, prim_sorted ); |
|
|
|
|
|
|
|
# undef method |
|
|
|
|
|
|
|
_set(sym___globals__, Symbol,value, nil); |
|
|
|
|
|
|
|