|
@ -17,7 +17,7 @@ |
|
|
_DO(PostIncVariable) _DO(PostIncMember) _DO(PostIncIndex) \ |
|
|
_DO(PostIncVariable) _DO(PostIncMember) _DO(PostIncIndex) \ |
|
|
_DO(PreDecVariable) _DO(PreDecMember) _DO(PreDecIndex) \ |
|
|
_DO(PreDecVariable) _DO(PreDecMember) _DO(PreDecIndex) \ |
|
|
_DO(PostDecVariable) _DO(PostDecMember) _DO(PostDecIndex) \ |
|
|
_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(Return) _DO(Break) _DO(Continue) _DO(Throw) _DO(Try) \ |
|
|
_DO(Quasiquote) _DO(Unquote) |
|
|
_DO(Quasiquote) _DO(Unquote) |
|
|
|
|
|
|
|
@ -75,7 +75,8 @@ oop globals= 0; |
|
|
_DO(lhs) _DO(rhs) _DO(scope) _DO(args) _DO(expression) _DO(labels) _DO(statements) _DO(initialise) \ |
|
|
_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(update) _DO(this) _DO(fixed) _DO(operator) _DO(map) _DO(func) \ |
|
|
_DO(try) _DO(catch) _DO(finally) _DO(exception) \ |
|
|
_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; |
|
|
#define _DO(NAME) oop NAME##_symbol; |
|
|
DO_SYMBOLS() |
|
|
DO_SYMBOLS() |
|
@ -547,6 +548,15 @@ oop newContinue(void) |
|
|
return obj; |
|
|
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 newTry(oop try, oop exception, oop catch, oop finally) |
|
|
{ |
|
|
{ |
|
|
oop obj = newObject(Try_proto); |
|
|
oop obj = newObject(Try_proto); |
|
@ -664,24 +674,24 @@ cond = c:logor QUERY t:exp COLON f:cond { $$ = newIf(c, t, |
|
|
| logor |
|
|
| logor |
|
|
|
|
|
|
|
|
logor = l:logand |
|
|
logor = l:logand |
|
|
( LOGOR r:logand { l = newBinary(Logor_proto, l, r) } |
|
|
|
|
|
)* { $$ = l } |
|
|
|
|
|
|
|
|
( LOGOR r:logand { l = newBinary(Logor_proto, l, r) } |
|
|
|
|
|
)* { $$ = l } |
|
|
|
|
|
|
|
|
logand = l:bitor |
|
|
logand = l:bitor |
|
|
( LOGAND r:bitor { l = newBinary(Logand_proto, l, r) } |
|
|
|
|
|
)* { $$ = l } |
|
|
|
|
|
|
|
|
( LOGAND r:bitor { l = newBinary(Logand_proto, l, r) } |
|
|
|
|
|
)* { $$ = l } |
|
|
|
|
|
|
|
|
bitor = l:bitxor |
|
|
bitor = l:bitxor |
|
|
( BITOR r:bitxor { l = newBinary(Bitor_proto, l, r) } |
|
|
|
|
|
)* { $$ = l } |
|
|
|
|
|
|
|
|
( BITOR r:bitxor { l = newBinary(Bitor_proto, l, r) } |
|
|
|
|
|
)* { $$ = l } |
|
|
|
|
|
|
|
|
bitxor = l:bitand |
|
|
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 = 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 |
|
|
eq = l:ineq |
|
|
( EQUAL r:ineq { l = newBinary(Equal_proto, l, r) } |
|
|
( EQUAL r:ineq { l = newBinary(Equal_proto, l, r) } |
|
@ -701,8 +711,8 @@ shift = l:sum |
|
|
)* { $$ = l } |
|
|
)* { $$ = l } |
|
|
|
|
|
|
|
|
sum = l:prod |
|
|
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 } |
|
|
)* { $$ = l } |
|
|
|
|
|
|
|
|
prod = l:prefix |
|
|
prod = l:prefix |
|
@ -723,6 +733,10 @@ prefix = PLUS n:prefix { $$= n } |
|
|
|
|
|
|
|
|
postfix = i:value ( DOT s:IDENT a:argumentList { i = newInvoke(i, s, a) } |
|
|
postfix = i:value ( DOT s:IDENT a:argumentList { i = newInvoke(i, s, a) } |
|
|
| DOT s:IDENT !assignOp { i = newGetMap(GetMember_proto, i, s) } |
|
|
| 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) } |
|
|
| LBRAC p:exp RBRAC !assignOp { i = newGetMap(GetIndex_proto, i, p) } |
|
|
| a:argumentList { i = (null != getSyntax(1, i)) ? apply(globals, getSyntax(1, i), a) : newCall(i, a) } |
|
|
| a:argumentList { i = (null != getSyntax(1, i)) ? apply(globals, getSyntax(1, i), a) : newCall(i, a) } |
|
|
| PLUSPLUS { i = newPostIncrement(i) } |
|
|
| PLUSPLUS { i = newPostIncrement(i) } |
|
@ -1556,11 +1570,23 @@ oop eval(oop scope, oop ast) |
|
|
oop key = eval(scope, map_get(ast, key_symbol)); |
|
|
oop key = eval(scope, map_get(ast, key_symbol)); |
|
|
switch (getType(map)) { |
|
|
switch (getType(map)) { |
|
|
case String: |
|
|
case String: |
|
|
if (getInteger(key) >= get(map, String, size)) { |
|
|
|
|
|
runtimeError("GetIndex out of range on String"); |
|
|
|
|
|
|
|
|
if (!isInteger(key)) { |
|
|
|
|
|
runtimeError("non-integer index"); |
|
|
|
|
|
} |
|
|
|
|
|
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(unescape(get(map, String, value))[getInteger(key)]); |
|
|
|
|
|
|
|
|
return makeInteger(get(map, String, value)[i]); |
|
|
case Map: |
|
|
case Map: |
|
|
|
|
|
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); |
|
|
return map_get(map, key); |
|
|
default: |
|
|
default: |
|
|
runtimeError("GetIndex on non Map or String"); |
|
|
runtimeError("GetIndex on non Map or String"); |
|
@ -1574,7 +1600,7 @@ oop eval(oop scope, oop ast) |
|
|
switch (getType(map)) { |
|
|
switch (getType(map)) { |
|
|
case String: |
|
|
case String: |
|
|
if (getInteger(key) >= get(map, String, size)) { |
|
|
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); |
|
|
get(map, String, value)[getInteger(key)] = getInteger(value); |
|
|
return value; |
|
|
return value; |
|
@ -1586,6 +1612,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_Symbol: |
|
|
case t_Integer: |
|
|
case t_Integer: |
|
|
case t_String: { |
|
|
case t_String: { |
|
|