diff --git a/bootstrap.txt b/bootstrap.txt index 0d151ce..818c585 100644 --- a/bootstrap.txt +++ b/bootstrap.txt @@ -4,7 +4,7 @@ fun require(__fileName__) { if (__requires__[__fileName__] != null) { return __requires__[__fileName__] } - import(__fileName__); + import(__fileName__); __requires__[__fileName__]= scope(); return scope(); } diff --git a/object.c b/object.c index c5f6488..55c9be9 100644 --- a/object.c +++ b/object.c @@ -197,7 +197,7 @@ oop _checkType(oop ptr, type_t type, char *file, int line) { assert(ptr); if (getType(ptr) != type) { - fprintf(stderr, "\n%s:%i: expected %i got %i\n", file, line, type, ptr->type); + fprintf(stderr, "\n%s:%i: expected %i got %i\n", file, line, type, getType(ptr)); } assert(getType(ptr) == type); return ptr; @@ -262,11 +262,47 @@ oop makeString(char *value) return newString; } +// value will be used directly +oop makeStringFrom(char *value, size_t l) +{ + oop newString = malloc(sizeof(struct String)); + newString->type = String; + newString->String.value = value; + newString->String.size = l; + return newString; +} + +oop makeStringFromChar(char c, int repeat) +{ + char *str= malloc(sizeof(char) * (repeat + 1)); + for (int i=0; i len) return NULL; + if (stop < 0 || stop > len) return NULL; + if (start > stop) return NULL; + + size_t cpylen = stop - start; + char *slice= memcheck(malloc(sizeof(char) * (cpylen + 1))); + memcpy(slice, get(str, String, value) + start, cpylen); + slice[cpylen]= '\0'; + return makeStringFrom(slice, cpylen); +} + oop string_concat(oop str1, oop str2) { size_t len = string_size(str1) + string_size(str2); @@ -274,11 +310,7 @@ oop string_concat(oop str1, oop str2) memcpy(concat, get(str1, String, value), string_size(str1)); memcpy(concat + string_size(str1), get(str2, String, value), string_size(str2)); concat[len]= '\0'; - oop newString = malloc(sizeof(struct String)); - newString->type = String; - newString->String.value = concat; - newString->String.size = len; - return newString; + return makeStringFrom(concat, len); } oop string_mul(oop str, oop factor) @@ -290,11 +322,7 @@ oop string_mul(oop str, oop factor) memcpy(concat + (i * string_size(str)), get(str, String, value), string_size(str)); } concat[len]= '\0'; - oop newString = malloc(sizeof(struct String)); - newString->type = String; - newString->String.value = concat; - newString->String.size = len; - return newString; + return makeStringFrom(concat, len); } oop makeSymbol(char *name) @@ -306,6 +334,25 @@ oop makeSymbol(char *name) return newSymb; } +oop makeSymbolFrom(char *name) +{ + oop newSymbol= malloc(sizeof(struct Symbol)); + newSymbol->type= Symbol; + newSymbol->Symbol.name= name; + newSymbol->Symbol.prototype= 0; + return newSymbol; +} + +oop makeSymbolFromChar(char c, int repeat) +{ + char *str= malloc(sizeof(char) * (repeat + 1)); + for (int i=0; i len) return NULL; + if (stop < 0 || stop > len) return NULL; + if (start > stop) return NULL; + + oop slice= makeMap(); + if (start < stop) { + if (!map_hasIntegerKey(map, start )) return NULL; + if (!map_hasIntegerKey(map, stop - 1)) return NULL; + for (size_t i= start; i < stop; ++i) { + map_append(slice, get(map, Map, elements)[i].value); + } + } + return slice; +} + DECLARE_BUFFER(oop, OopStack); OopStack printing = BUFFER_INITIALISER; diff --git a/parse.leg b/parse.leg index 5669166..3c0078e 100644 --- a/parse.leg +++ b/parse.leg @@ -20,9 +20,9 @@ _DO(PostIncVariable) _DO(PostIncMember) _DO(PostIncIndex) \ _DO(PreDecVariable) _DO(PreDecMember) _DO(PreDecIndex) \ _DO(PostDecVariable) _DO(PostDecMember) _DO(PostDecIndex) \ - _DO(GetVariable) _DO(GetMember) _DO(SetMember) _DO(GetIndex) _DO(SetIndex) \ + _DO(GetVariable) _DO(GetMember) _DO(SetMember) _DO(GetIndex) _DO(SetIndex) _DO(Slice) \ _DO(Return) _DO(Break) _DO(Continue) _DO(Throw) _DO(Try) \ - _DO(Quasiquote) _DO(Unquote) + _DO(Quasiquote) _DO(Unquote) _DO(Unsplice) _DO(Splice) typedef enum { t_UNDEFINED=0, @@ -71,7 +71,8 @@ oop globals= 0; _DO(lhs) _DO(rhs) _DO(scope) _DO(args) _DO(expression) _DO(labels) _DO(statements) _DO(initialise) \ _DO(update) _DO(this) _DO(fixed) _DO(operator) _DO(map) _DO(func) \ _DO(try) _DO(catch) _DO(finally) _DO(exception) \ - _DO(__line__) _DO(__file__) + _DO(__line__) _DO(__file__) \ + _DO(start) _DO(stop) #define _DO(NAME) oop NAME##_symbol; DO_SYMBOLS() @@ -568,6 +569,15 @@ oop newContinue(void) return obj; } +oop newSlice(oop value, oop start, oop stop) +{ + oop obj= newObject(Slice_proto); + map_set(obj, value_symbol, value); + map_set(obj, start_symbol, start); + map_set(obj, stop_symbol, stop); + return obj; +} + oop newTry(oop try, oop exception, oop catch, oop finally) { oop obj = newObject(Try_proto); @@ -650,7 +660,7 @@ exp = VAR l:ident ASSIGN e:exp { $$ = newDeclarati | c:cond { $$ = c } ident = l:IDENT { $$ = l } - | AT n:prefix { $$ = newUnary(Unquote_proto, n) } + | AT n:value { $$ = newUnary(Unquote_proto, n) } syntax2 = < [a-zA-Z_][a-zA-Z0-9_]* > &{ null != getSyntaxId(2, intern(yytext)) } - { $$ = getSyntaxId(2, intern(yytext)) } @@ -686,23 +696,23 @@ cond = c:logor QUERY t:exp COLON f:cond { $$ = newIf(c, t, logor = l:logand ( LOGOR r:logand { l = newBinary(Logor_proto, l, r) } - )* { $$ = l } + )* { $$ = l } logand = l:bitor ( LOGAND r:bitor { l = newBinary(Logand_proto, l, r) } - )* { $$ = l } + )* { $$ = l } bitor = l:bitxor ( BITOR r:bitxor { l = newBinary(Bitor_proto, l, r) } - )* { $$ = l } + )* { $$ = l } bitxor = l:bitand - ( BITXOR r:bitand { l = newBinary(Bitxor_proto, l, r) } - )* { $$ = l } + ( BITXOR r:bitand { l = newBinary(Bitxor_proto, l, r) } + )* { $$ = l } bitand = l:eq - ( BITAND r:eq { l = newBinary(Bitand_proto, l, r) } - )* { $$ = l } + ( BITAND r:eq { l = newBinary(Bitand_proto, l, r) } + )* { $$ = l } eq = l:ineq ( EQUAL r:ineq { l = newBinary(Equal_proto, l, r) } @@ -722,8 +732,8 @@ shift = l:sum )* { $$ = l } sum = l:prod - ( PLUS r:prod { l = newBinary(Add_proto, l, r) } - | MINUS r:prod { l = newBinary(Sub_proto, l, r) } + ( PLUS r:prod { l = newBinary(Add_proto, l, r) } + | MINUS r:prod { l = newBinary(Sub_proto, l, r) } )* { $$ = l } prod = l:prefix @@ -738,12 +748,14 @@ prefix = PLUS n:prefix { $$= n } | PLING n:prefix { $$= newUnary(Not_proto, n) } | PLUSPLUS n:prefix { $$= newPreIncrement(n) } | MINUSMINUS n:prefix { $$= newPreDecrement(n) } - | BACKTICK n:prefix { $$ = newUnary(Quasiquote_proto, n) } - | AT n:prefix { $$ = newUnary(Unquote_proto, n) } | n:postfix { $$= n } postfix = i:value ( DOT s:IDENT a:argumentList { i = newInvoke(i, s, a) } | DOT s:IDENT !assignOp { i = newGetMap(GetMember_proto, i, s) } + | LBRAC e1:exp COLON e2:exp RBRAC !assignOp { i = newSlice(i, e1, e2) } + | LBRAC e1:exp COLON RBRAC !assignOp { i = newSlice(i, e1, null) } + | LBRAC COLON e2:exp RBRAC !assignOp { i = newSlice(i, null, e2) } + | LBRAC COLON RBRAC !assignOp { i = newSlice(i, null, null) } | LBRAC p:exp RBRAC !assignOp { i = newGetMap(GetIndex_proto, i, p) } | a:argumentList { i = (null != getSyntax(1, i)) ? apply(globals, globals, getSyntax(1, i), a, i) : newCall(i, a) } | PLUSPLUS { i = newPostIncrement(i) } @@ -751,20 +763,29 @@ postfix = i:value ( DOT s:IDENT a:argumentList { i = newInvoke( ) * { $$ = i } paramList = LPAREN m:makeMap - ( i:IDENT { map_append(m, i) } - ( COMMA i:IDENT { map_append(m, i) } + ( p:parameter { map_append(m, p) } + ( COMMA p:parameter { map_append(m, p) } ) * ) ? RPAREN { $$ = m } +parameter = ATAT p:value { $$ = newUnary(Unsplice_proto, p) } + | p:ident { $$ = p } + argumentList = LPAREN m:makeMap - ( e:exp { map_append(m, e) } - ( COMMA e:exp { map_append(m, e) } + ( a:argument { map_append(m, a) } + ( COMMA a:argument { map_append(m, a) } ) * ) ? RPAREN { $$ = m } -value = n:FLOAT { $$ = newFloat(n) } +argument = ATAT e:value { $$ = newUnary(Unsplice_proto, e) } + | MULTI e:exp { $$ = newUnary(Splice_proto, e) } + | e:exp { $$ = e } + +value = BACKTICK n:value { $$ = newUnary(Quasiquote_proto, n) } + | AT n:value { $$ = newUnary(Unquote_proto, n) } + | n:FLOAT { $$ = newFloat(n) } | n:integer { $$ = newInteger(n) } | s:string { $$ = newString(s) } | s:symbol { $$ = s } @@ -790,11 +811,11 @@ map = LCB m:makeMap ) ? RCB { $$ = m } | LBRAC m:makeMap - ( v:exp { map_append(m, v) } - ( COMMA v:exp { map_append(m, v) } + ( v:argument { map_append(m, v) } + ( COMMA v:argument { map_append(m, v) } ) * ) ? - RBRAC { $$ = m } + RBRAC { $$ = m } makeMap = { $$ = makeMap() } @@ -891,7 +912,8 @@ SEMICOLON = ';' - COMMA = ',' - DOT = '.' - BACKTICK= '`' - -AT = '@' - +AT = '@' ![@] - +ATAT = '@@' ![@] - LCB = '{' - RCB = '}' - LBRAC = '[' - @@ -939,6 +961,11 @@ oop clone(oop obj) set(map, Map, elements, elements); return map; } + case Function: { + oop fun= malloc(sizeof(*obj)); + memcpy(fun, obj, sizeof(*obj)); + return fun; + } } return obj; } @@ -1087,22 +1114,52 @@ oop modOperation(oop lhs, oop rhs) #undef TYPESIG #undef CASE -oop expandUnquotes(oop scope, oop obj) -{ - obj = clone(obj); - if (!is(Map, obj)) { - return obj; - } - if (map_get(obj, __proto___symbol) == Unquote_proto) { - return eval(scope, map_get(obj, rhs_symbol)); - } - for (size_t i= 0; i < map_size(obj); ++i) { - struct Pair *pair= &get(obj, Map, elements)[i]; - if (__proto___symbol != pair->key) { - pair->value= expandUnquotes(scope, pair->value); - } +oop expandUnquotes(oop scope, oop ast) +{ + if (!is(Map, ast)) return clone(ast); + + if (Unquote_proto == map_get(ast, __proto___symbol)) return eval(scope, map_get(ast, rhs_symbol)); + if (Unsplice_proto == map_get(ast, __proto___symbol)) runtimeError("@@ outside of array expression"); + + oop map= makeMap(); + if (map_isArray(ast)) { + for (size_t i= 0; i < map_size(ast); ++i) { + struct Pair *pair= &get(ast, Map, elements)[i]; + if (!is(Map, pair->value)) { + map_append(map, clone(pair->value)); + continue; + } + oop proto= map_get(pair->value, __proto___symbol); + if (Unquote_proto == proto) { + map_append(map, eval(scope, map_get(pair->value, rhs_symbol))); + continue; + } + if (Unsplice_proto == proto) { + oop sub= eval(scope, map_get(pair->value, rhs_symbol)); + if (is(Map, sub) && (Map_proto == map_get(sub, __proto___symbol))) sub= map_get(sub, value_symbol); + if (!map_isArray(sub)) runtimeError("cannot splice non-array: %s", printString(sub)); + for (size_t j= 0; j < map_size(sub); ++j) + map_append(map, get(sub, Map, elements)[j].value); + continue; + } + map_append(map, expandUnquotes(scope, pair->value)); + } + } + else { + for (size_t i= 0; i < map_size(ast); ++i) { + struct Pair *pair= &get(ast, Map, elements)[i]; + oop key= expandUnquotes(scope, pair->key); + if (!is(Map, pair->value)) { + map_set(map, key, clone(pair->value)); + continue; + } + if (__proto___symbol == key) + map_set(map, key, pair->value); + else + map_set(map, key, expandUnquotes(scope, pair->value)); + } } - return obj; + return map; } oop applyOperator(oop op, oop lhs, oop rhs) @@ -1260,6 +1317,9 @@ oop eval(oop scope, oop ast) case t_Unquote: { runtimeError("@ outside of `"); } + case t_Unsplice: { + runtimeError("@@ outside of `"); + } case t_Declaration: { oop lhs = map_get(ast, lhs_symbol); oop rhs = eval(scope, map_get(ast, rhs_symbol)); @@ -1506,6 +1566,9 @@ oop eval(oop scope, oop ast) } return apply(scope, this, func, args, ast); } + case t_Splice: { + runtimeError("* outside of argument list"); + } case t_Return: { assert(jbs); @@ -1608,12 +1671,24 @@ oop eval(oop scope, oop ast) oop key = eval(scope, map_get(ast, key_symbol)); switch (getType(map)) { case String: - if (getInteger(key) >= get(map, String, size)) { - runtimeError("GetIndex out of range on String"); + if (!isInteger(key)) { + runtimeError("non-integer index"); } - return makeInteger(unescape(get(map, String, value))[getInteger(key)]); + ssize_t i= getInteger(key); + size_t len= string_size(map); + if (i < 0) i+= len; + if (i < 0 || i >= len) { + runtimeError("GetIndex out of bounds on String"); + } + return makeInteger(get(map, String, value)[i]); case Map: - return getVariable(map, key); + if (isInteger(key) && getInteger(key) < 0) { + size_t size= map_size(map); + if (size > 0 && map_hasIntegerKey(map, size - 1)) { + key= makeInteger(getInteger(key) + size); + } + } + return map_get(map, key); default: runtimeError("GetIndex on non Map or String"); } @@ -1626,7 +1701,7 @@ oop eval(oop scope, oop ast) switch (getType(map)) { case String: if (getInteger(key) >= get(map, String, size)) { - runtimeError("SetIndex out of range on String"); + runtimeError("SetIndex out of bounds on String"); } get(map, String, value)[getInteger(key)] = getInteger(value); return value; @@ -1638,6 +1713,35 @@ oop eval(oop scope, oop ast) } } + case t_Slice: { + oop pre= eval(scope, map_get(ast, value_symbol)); + oop start= eval(scope, map_get(ast, start_symbol)); + oop stop= eval(scope, map_get(ast, stop_symbol)); + ssize_t first= start == null ? 0 : getInteger(start); + + if (start == null) { + start= makeInteger(0); + } + switch (getType(pre)) { + case String: { + ssize_t last= stop == null ? string_size(pre) : getInteger(stop); + oop res= string_slice(pre, first, last); + if (NULL == res) { + runtimeError("index out of bounds"); + } + return res; + } + case Map: { + ssize_t last= stop == null ? map_size(pre) : getInteger(stop); + oop res= map_slice(pre, first, last); + if (NULL == res) { + runtimeError("index out of bounds"); + } + return res; + } + } + runtimeError("slicing a non-String or non-Map"); + } case t_Symbol: case t_Integer: case t_Float: @@ -1819,11 +1923,29 @@ oop prim_keys(oop scope, oop params) return null; } +oop prim_allKeys(oop scope, oop params) +{ + if (map_hasIntegerKey(params, 0)) { + oop arg= get(params, Map, elements)[0].value; + if (is(Map, arg)) return map_allKeys(arg); + } + return null; +} + oop prim_values(oop scope, oop params) { if (map_hasIntegerKey(params, 0)) { - oop arg= get(params, Map, elements)[0].value; - if (is(Map, arg)) return map_values(arg); + oop arg= get(params, Map, elements)[0].value; + if (is(Map, arg)) return map_values(arg); + } + return null; +} + +oop prim_allValues(oop scope, oop params) +{ + if (map_hasIntegerKey(params, 0)) { + oop arg= get(params, Map, elements)[0].value; + if (is(Map, arg)) return map_allValues(arg); } return null; } @@ -1871,16 +1993,27 @@ oop prim_print(oop scope, oop params) return params; } -oop evalArgs(oop scope, oop args) +oop evalArgs(oop scope, oop asts) { - int i = 0; - oop params = makeMap(); - oop index; - while ((index = makeInteger(i)), map_hasKey(args, index)) { - map_set(params, index, eval(scope, map_get(args, index))); - i++; - } - return params; + oop args= makeMap(); + size_t nargs= map_size(asts); + for (size_t i= 0; i < nargs; ++i) { + oop ast= get(asts, Map, elements)[i].value; + if (is(Map, ast) && (Splice_proto == map_get(ast, __proto___symbol))) { + oop splice= eval(scope, map_get(ast, rhs_symbol)); + if (!is(Map, splice)) map_append(args, splice); + else { + size_t nsplice= map_size(splice); + for (size_t j= 0; j < nsplice; ++j) { + map_append(args, get(splice, Map, elements)[j].value); + } + } + } + else { + map_append(args, eval(scope, ast)); + } + } + return args; } oop AST= NULL; @@ -1940,8 +2073,218 @@ oop prim_import(oop scope, oop params) oop prim_String(oop scope, oop params) { - if (!map_hasIntegerKey(params, 0)) return null; - return makeString(printString(get(params, Map, elements)[0].value)); + if (!map_hasIntegerKey(params, 0)) return makeString(""); + oop arg= get(params, Map, elements)[0].value; + switch (getType(arg)) { + case Undefined: { + return makeString(""); + } + case Integer: { + int repeat= getInteger(arg); + if (!map_hasIntegerKey(params, 1)) { + return makeStringFromChar('\0', repeat); + } + char c= getInteger(get(params, Map, elements)[1].value); + return makeStringFromChar(c, repeat); + } + case String: { + return clone(arg); + } + case Map: { + if (map_isArray(arg)) { + size_t len= map_size(arg); + char *str= malloc(sizeof(char) * len + 1); + for (size_t i=0; i < len; ++i) { + str[i]= getInteger(get(arg, Map, elements)[i].value); + } + return makeStringFrom(str, len); + } + } + case Symbol: { + return makeString(get(arg, Symbol, name)); + } + } + runtimeError("cannot make string from: %s", printString(arg)); + return NULL; +} + +oop prim_Symbol(oop scope, oop params) +{ + oop arg= null; + if (map_hasIntegerKey(params, 0)) { + arg= get(params, Map, elements)[0].value; + switch (getType(arg)) { + case Integer: { + if (map_hasIntegerKey(params, 1)) { + int repeat= getInteger(arg); + char c= getInteger(get(params, Map, elements)[1].value); + return makeSymbolFromChar(c, repeat); + } + break; + } + case String: { + return makeSymbol(get(arg, String, value)); + } + case Map: { + if (map_isArray(arg)) { + size_t len= map_size(arg); + char *str= malloc(sizeof(char) * len + 1); + for (size_t i=0; i < len; ++i) { + str[i]= getInteger(get(arg, Map, elements)[i].value); + } + return makeSymbolFrom(str); + } + } + case Symbol: { + return arg; + } + } + } + runtimeError("cannot make symbol from: %s", printString(arg)); + return NULL; +} + +oop prim_Integer(oop scope, oop params) +{ + oop arg= null; + if (map_hasIntegerKey(params, 0)) { + arg= get(params, Map, elements)[0].value; + switch (getType(arg)) { + case Undefined: { + return makeInteger(0); + } + case Integer: { + return arg; + } + case String: { + if (!map_hasIntegerKey(params, 1)) { + return makeInteger(strtoll(get(arg, String, value), NULL, 0)); + } + int base= getInteger(get(params, Map, elements)[1].value); + if (base > 36 || base < 2) { + runtimeError("base must be between 2 and 36 inclusive"); + } + return makeInteger(strtoll(get(arg, String, value), NULL, base)); + } + } + } + runtimeError("cannot make integer from: %s", printString(arg)); + return NULL; +} + +oop prim_Map(oop scope, oop params) +{ + if (!map_hasIntegerKey(params, 0)) return makeMap(); + oop arg= get(params, Map, elements)[0].value; + switch (getType(arg)) { + case Undefined: { + return makeMap(); + } + case Integer: { + return makeMapCapacity(getInteger(arg)); + } + case Map: { + return clone(arg); + } + } + runtimeError("cannot make map from: %s", printString(arg)); + return NULL; +} + +oop prim_Array(oop scope, oop params) +{ + if (!map_hasIntegerKey(params, 0)) return makeMap(); + oop arg= get(params, Map, elements)[0].value; + switch (getType(arg)) { + case Undefined: { + return makeMap(); + } + case Integer: { + int repeat= getInteger(arg); + oop array= NULL; + if (map_hasIntegerKey(params, 1)) { + array= makeArrayFromElement(get(params, Map, elements)[1].value, repeat); + } else { + array= makeArrayFromElement(null, repeat); + } + return array; + } + case Symbol: { + return makeArrayFromString(get(arg, Symbol, name)); + } + case String: { + return makeArrayFromString(get(arg, String, value)); + } + case Map: { + return clone(arg); + } + } + runtimeError("cannot make array from: %s", printString(arg)); + return NULL; +} + +oop prim_Function(oop scope, oop params) +{ + oop arg= null; + if (map_hasIntegerKey(params, 0)) { + arg= get(params, Map, elements)[0].value; + switch (getType(arg)) { + case Function: { + if (isTrue(get(arg, Function, fixed))) { + oop unfix= clone(arg); + set(unfix, Function, fixed, makeInteger(0)); + return unfix; + } else { + return clone(arg); + } + } + case Map: { + if (map_hasIntegerKey(params, 1) && map_hasIntegerKey(params, 2) && map_hasIntegerKey(params, 3)) { + oop param= arg; + oop body= get(params, Map, elements)[1].value; + oop parentScope= get(params, Map, elements)[2].value; + oop name= get(params, Map, elements)[3].value; + if (is(Map, body) && is(Map, parentScope) && is(Map, name)) { + return makeFunction(NULL, name, param, body, parentScope, makeInteger(0)); + } + } + } + } + } + runtimeError("cannot make function from: %s", printString(arg)); + return NULL; +} + +oop prim_Syntax(oop scope, oop params) +{ + oop arg= null; + if (map_hasIntegerKey(params, 0)) { + arg= get(params, Map, elements)[0].value; + switch (getType(arg)) { + case Function: { + if (isFalse(get(arg, Function, fixed))) { + oop fix= clone(arg); + set(fix, Function, fixed, makeInteger(1)); + return fix; + } else { + return clone(arg); + } + } + case Map: { + if (map_hasIntegerKey(params, 1) && map_hasIntegerKey(params, 2) && map_hasIntegerKey(params, 3)) { + oop param= arg; + oop body= get(params, Map, elements)[1].value; + oop parentScope= get(params, Map, elements)[2].value; + oop name= get(params, Map, elements)[3].value; + if (is(Map, body) && is(Map, parentScope) && is(Map, name)) { + return makeFunction(NULL, name, param, body, parentScope, makeInteger(1)); + } + } + } + } + } + runtimeError("cannot make syntax from: %s", printString(arg)); + return NULL; } oop prim_scope(oop scope, oop params) @@ -1969,7 +2312,9 @@ int main(int argc, char **argv) map_set(globals, intern("exit" ), makeFunction(prim_exit, intern("exit" ), null, null, globals, null)); map_set(globals, intern("keys" ), makeFunction(prim_keys, intern("keys" ), null, null, globals, null)); + map_set(globals, intern("allKeys" ), makeFunction(prim_allKeys, intern("allKeys" ), null, null, globals, null)); map_set(globals, intern("values" ), makeFunction(prim_values, intern("values" ), null, null, globals, null)); + map_set(globals, intern("allValues" ), makeFunction(prim_allValues, intern("allValues" ), null, null, globals, null)); map_set(globals, intern("length" ), makeFunction(prim_length, intern("length" ), null, null, globals, null)); map_set(globals, intern("print" ), makeFunction(prim_print, intern("print" ), null, null, globals, null)); map_set(globals, intern("invoke" ), makeFunction(prim_invoke, intern("invoke" ), null, null, globals, null)); @@ -1978,6 +2323,12 @@ int main(int argc, char **argv) map_set(globals, intern("import" ), makeFunction(prim_import, intern("import" ), null, null, globals, null)); map_set(globals, intern("microseconds"), makeFunction(prim_microseconds, intern("microseconds"), null, null, globals, null)); map_set(globals, intern("String" ), makeFunction(prim_String , intern("String" ), null, null, globals, null)); + map_set(globals, intern("Integer" ), makeFunction(prim_Integer , intern("Integer" ), null, null, globals, null)); + map_set(globals, intern("Symbol" ), makeFunction(prim_Symbol , intern("Symbol" ), null, null, globals, null)); + map_set(globals, intern("Map" ), makeFunction(prim_Map , intern("Map" ), null, null, globals, null)); + map_set(globals, intern("Array" ), makeFunction(prim_Array , intern("Array" ), null, null, globals, null)); + map_set(globals, intern("Function" ), makeFunction(prim_Function , intern("Function" ), null, null, globals, null)); + map_set(globals, intern("Syntax" ), makeFunction(prim_Syntax , intern("Syntax" ), null, null, globals, null)); map_set(globals, intern("scope"), makeFunction(prim_scope, intern("scope"), null, null, globals, null)); diff --git a/test-object.txt b/test-object.txt index 7b87da3..5b8e3f5 100644 --- a/test-object.txt +++ b/test-object.txt @@ -81,18 +81,16 @@ syntax double(a) { return `(@a+@a) } -double(21) +println(double(21)) -syntax until(c, b) { +syntax until (c) b { return `(while (!@c) @b) } var x = 0; -/* -until(x==10) { +until (x==10) { println(x++) } -*/ println(`x); diff --git a/test-slice.txt b/test-slice.txt index 23313f2..921c9ac 100644 --- a/test-slice.txt +++ b/test-slice.txt @@ -1,10 +1,10 @@ s = "hello" b = [2, 4, 6] -b.pizza= "ok" println(s[-4:-3]) println(s[:-3]) println(s[-4:]) println(s[:]) println(s[:]) -m = { 3: "three", 1: "four", 2: "five" } -println({}[-0]); \ No newline at end of file +m = { 1: "three", 2: "four", 3: "five" } +println(m) +println(b[-2]); \ No newline at end of file diff --git a/test-splice.txt b/test-splice.txt new file mode 100644 index 0000000..269f78f --- /dev/null +++ b/test-splice.txt @@ -0,0 +1,16 @@ +fun f(a, b, c, d, e) { + print(a, " ", b, " ", c, " ", d, " ", e, "\n"); +} + +args = ["a", "b", "c"]; + +f(1, 2, 3, 4, 5); +f(1, *args, 2); + +fun myprintln() { + print(*__arguments__); + print("\n"); +} + +myprintln("Hello, world"); +myprintln("Goodbye, world"); diff --git a/test-syntax.txt b/test-syntax.txt new file mode 100644 index 0000000..4041538 --- /dev/null +++ b/test-syntax.txt @@ -0,0 +1,5 @@ +syntax ncall(function, args) { + return `(@function ( @(length(args)), @@args )) +} + +ncall(print, [1,2,3]); \ No newline at end of file