浏览代码

Merge with master

pull/22/head
mtardy 4 年前
父节点
当前提交
18717eb9a9
共有 7 个文件被更改,包括 559 次插入77 次删除
  1. +1
    -1
      bootstrap.txt
  2. +123
    -11
      object.c
  3. +408
    -57
      parse.leg
  4. +3
    -5
      test-object.txt
  5. +3
    -3
      test-slice.txt
  6. +16
    -0
      test-splice.txt
  7. +5
    -0
      test-syntax.txt

+ 1
- 1
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();
}

+ 123
- 11
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<repeat; ++i) {
str[i]= c;
}
str[repeat]= '\0';
return makeStringFrom(str, repeat);
}
size_t string_size(oop s)
{
return get(s, String, size);
}
oop string_slice(oop str, ssize_t start, ssize_t stop) {
assert(is(String, str));
size_t len = string_size(str);
if (start < 0) start= start + len;
if (stop < 0) stop= stop + len;
if (start < 0 || start > 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<repeat; ++i) {
str[i]= c;
}
str[repeat]= '\0';
return makeSymbolFrom(str);
}
oop makeFunction(primitive_t primitive, oop name, oop param, oop body, oop parentScope, oop fixed)
{
oop newFunc = malloc(sizeof(struct Function));
@ -326,6 +373,14 @@ oop makeMap()
return newMap;
}
oop makeMapCapacity(size_t capa)
{
oop map= makeMap();
set(map, Map, elements, malloc(sizeof(struct Pair) * capa));
set(map, Map, capacity, capa);
return map;
}
size_t map_size(oop map)
{
assert(is(Map, map));
@ -340,6 +395,14 @@ bool map_hasIntegerKey(oop map, size_t index)
return index == getInteger(key);
}
bool map_isArray(oop map)
{
assert(is(Map, map));
size_t size= map_size(map);
if (size == 0) return true;
return map_hasIntegerKey(map, 0) && map_hasIntegerKey(map, size-1);
}
int oopcmp(oop a, oop b)
{
type_t ta = getType(a), tb = getType(b);
@ -477,6 +540,25 @@ oop map_append(oop map, oop value)
return map_set(map, makeInteger(map_size(map)), value);
}
oop makeArrayFromElement(oop elem, int repeat)
{
oop array= makeMapCapacity(repeat);
for(int i=0; i < repeat; ++i) {
map_append(array, elem);
}
return array;
}
oop makeArrayFromString(char *str)
{
size_t len= strlen(str);
oop array= makeMapCapacity(len);
for(int i=0; i < len; ++i) {
map_append(array, makeInteger(str[i]));
}
return array;
}
bool isHidden(oop obj) {
if (is(Symbol, obj)) {
char *s = get(obj, Symbol, name);
@ -521,6 +603,36 @@ oop map_values(oop map)
return values;
}
oop map_allValues(oop map)
{
assert(is(Map, map));
oop values = makeMap();
for (size_t i = 0; i < get(map, Map, size); i++) {
map_append(values, get(map, Map, elements)[i].value);
}
return values;
}
oop map_slice(oop map, ssize_t start, ssize_t stop) {
assert(is(Map, map));
size_t len = map_size(map);
if (start < 0) start= start + len;
if (stop < 0) stop= stop + len;
if (start < 0 || start > 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;

+ 408
- 57
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));

+ 3
- 5
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);

+ 3
- 3
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]);
m = { 1: "three", 2: "four", 3: "five" }
println(m)
println(b[-2]);

+ 16
- 0
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");

+ 5
- 0
test-syntax.txt 查看文件

@ -0,0 +1,5 @@
syntax ncall(function, args) {
return `(@function ( @(length(args)), @@args ))
}
ncall(print, [1,2,3]);

正在加载...
取消
保存