|
@ -1,6 +1,6 @@ |
|
|
# main.leg -- C parser + interpreter |
|
|
# main.leg -- C parser + interpreter |
|
|
# |
|
|
# |
|
|
# Last edited: 2025-02-03 11:58:41 by piumarta on xubuntu |
|
|
|
|
|
|
|
|
# Last edited: 2025-02-04 09:10:32 by piumarta on xubuntu |
|
|
|
|
|
|
|
|
%{ |
|
|
%{ |
|
|
; |
|
|
; |
|
@ -131,16 +131,16 @@ struct List { type_t _type; int size; oop *elements; }; |
|
|
struct Memory { type_t _type; void *base; size_t size; }; |
|
|
struct Memory { type_t _type; void *base; size_t size; }; |
|
|
struct Reference { type_t _type; oop target; }; |
|
|
struct Reference { type_t _type; oop target; }; |
|
|
struct Closure { type_t _type; oop function, environment; }; |
|
|
struct Closure { type_t _type; oop function, environment; }; |
|
|
struct Call { type_t _type; oop function, arguments; }; |
|
|
|
|
|
|
|
|
struct Call { type_t _type; oop function, arguments, token; }; |
|
|
struct Block { type_t _type; oop statements; }; |
|
|
struct Block { type_t _type; oop statements; }; |
|
|
struct Addressof { type_t _type; oop rhs; }; |
|
|
|
|
|
struct Dereference { type_t _type; oop rhs; }; |
|
|
|
|
|
struct Sizeof { type_t _type; oop rhs, size; }; |
|
|
|
|
|
struct Unary { type_t _type; unary_t operator; oop rhs; }; |
|
|
|
|
|
struct Binary { type_t _type; binary_t operator; oop lhs, rhs; }; |
|
|
|
|
|
struct Index { type_t _type; oop lhs, rhs; }; |
|
|
|
|
|
struct Member { type_t _type; oop lhs, name; }; |
|
|
|
|
|
struct Assign { type_t _type; oop token, lhs, rhs; }; |
|
|
|
|
|
|
|
|
struct Addressof { type_t _type; oop rhs, token; }; |
|
|
|
|
|
struct Dereference { type_t _type; oop rhs, token; }; |
|
|
|
|
|
struct Sizeof { type_t _type; oop rhs, size, token; }; |
|
|
|
|
|
struct Unary { type_t _type; unary_t operator; oop rhs, token; }; |
|
|
|
|
|
struct Binary { type_t _type; binary_t operator; oop lhs, rhs, token; }; |
|
|
|
|
|
struct Index { type_t _type; oop lhs, rhs, token; }; |
|
|
|
|
|
struct Member { type_t _type; oop lhs, name, token; }; |
|
|
|
|
|
struct Assign { type_t _type; oop lhs, rhs, token; }; |
|
|
struct Cast { type_t _type; oop type, rhs; cvt_t converter; }; |
|
|
struct Cast { type_t _type; oop type, rhs; cvt_t converter; }; |
|
|
struct While { type_t _type; oop condition, expression; }; |
|
|
struct While { type_t _type; oop condition, expression; }; |
|
|
struct For { type_t _type; oop initialiser, condition, update, body; }; |
|
|
struct For { type_t _type; oop initialiser, condition, update, body; }; |
|
@ -169,7 +169,7 @@ struct Constant { type_t _type; oop name, type, value; }; |
|
|
struct Function { type_t _type; oop name, type, parameters, body, *code; int variadic; }; |
|
|
struct Function { type_t _type; oop name, type, parameters, body, *code; int variadic; }; |
|
|
struct Primitive { type_t _type; oop name, type, parameters; prim_t function; int variadic; }; |
|
|
struct Primitive { type_t _type; oop name, type, parameters; prim_t function; int variadic; }; |
|
|
struct VarDecls { type_t _type; oop type, variables; }; |
|
|
struct VarDecls { type_t _type; oop type, variables; }; |
|
|
struct TypeDecls { type_t _type; oop type, typenames; }; |
|
|
|
|
|
|
|
|
struct TypeDecls { type_t _type; oop type, typenames, token; }; |
|
|
|
|
|
|
|
|
union Object |
|
|
union Object |
|
|
{ |
|
|
{ |
|
@ -583,6 +583,8 @@ int List_equal(oop list, oop brray) |
|
|
return 1; |
|
|
return 1; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
#if 0 |
|
|
|
|
|
|
|
|
struct keyval { oop key, val; }; |
|
|
struct keyval { oop key, val; }; |
|
|
|
|
|
|
|
|
oop newMap(void) |
|
|
oop newMap(void) |
|
@ -629,6 +631,8 @@ oop Map_get(oop map, oop key) |
|
|
return kvs[index].val; |
|
|
return kvs[index].val; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
oop newMemory(void *base, size_t size) |
|
|
oop newMemory(void *base, size_t size) |
|
|
{ |
|
|
{ |
|
|
oop obj = new(Memory); |
|
|
oop obj = new(Memory); |
|
@ -639,39 +643,42 @@ oop newMemory(void *base, size_t size) |
|
|
|
|
|
|
|
|
CTOR1(Reference, target); |
|
|
CTOR1(Reference, target); |
|
|
CTOR2(Closure, function, environment); |
|
|
CTOR2(Closure, function, environment); |
|
|
CTOR2(Call, function, arguments); |
|
|
|
|
|
|
|
|
CTOR3(Call, function, arguments, token); |
|
|
CTOR1(Block, statements); |
|
|
CTOR1(Block, statements); |
|
|
CTOR1(Addressof, rhs); |
|
|
|
|
|
CTOR1(Dereference, rhs); |
|
|
|
|
|
|
|
|
CTOR2(Addressof, rhs, token); |
|
|
|
|
|
CTOR2(Dereference, rhs, token); |
|
|
|
|
|
|
|
|
oop newSizeof(oop operand) |
|
|
|
|
|
|
|
|
oop newSizeof(oop operand, oop token) |
|
|
{ |
|
|
{ |
|
|
oop obj = new(Sizeof); |
|
|
oop obj = new(Sizeof); |
|
|
obj->Sizeof.rhs = operand; |
|
|
obj->Sizeof.rhs = operand; |
|
|
obj->Sizeof.size = nil; |
|
|
obj->Sizeof.size = nil; |
|
|
|
|
|
obj->Sizeof.token = token; |
|
|
return obj; |
|
|
return obj; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
oop newUnary(unary_t operator, oop operand) |
|
|
|
|
|
|
|
|
oop newUnary(unary_t operator, oop operand, oop token) |
|
|
{ |
|
|
{ |
|
|
oop obj = new(Unary); |
|
|
oop obj = new(Unary); |
|
|
obj->Unary.operator = operator; |
|
|
obj->Unary.operator = operator; |
|
|
obj->Unary.rhs = operand; |
|
|
obj->Unary.rhs = operand; |
|
|
|
|
|
obj->Unary.token = token; |
|
|
return obj; |
|
|
return obj; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
oop newBinary(binary_t operator, oop lhs, oop rhs) |
|
|
|
|
|
|
|
|
oop newBinary(binary_t operator, oop lhs, oop rhs, oop token) |
|
|
{ |
|
|
{ |
|
|
oop obj = new(Binary); |
|
|
oop obj = new(Binary); |
|
|
obj->Binary.operator = operator; |
|
|
obj->Binary.operator = operator; |
|
|
obj->Binary.lhs = lhs; |
|
|
obj->Binary.lhs = lhs; |
|
|
obj->Binary.rhs = rhs; |
|
|
obj->Binary.rhs = rhs; |
|
|
|
|
|
obj->Binary.token = token; |
|
|
return obj; |
|
|
return obj; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
CTOR2(Index, lhs, rhs); |
|
|
|
|
|
CTOR2(Member, lhs, name); |
|
|
|
|
|
CTOR3(Assign, token, lhs, rhs); |
|
|
|
|
|
|
|
|
CTOR3(Index, lhs, rhs, token); |
|
|
|
|
|
CTOR3(Member, lhs, name, token); |
|
|
|
|
|
CTOR3(Assign, lhs, rhs, token); |
|
|
|
|
|
|
|
|
oop newCast(oop type, oop rhs) |
|
|
oop newCast(oop type, oop rhs) |
|
|
{ |
|
|
{ |
|
@ -960,11 +967,12 @@ void TypeDecls_append(oop tds, oop decl) |
|
|
List_append(get(tds, TypeDecls,typenames), decl); |
|
|
List_append(get(tds, TypeDecls,typenames), decl); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
oop newTypeDecls(oop type, oop decl) |
|
|
|
|
|
|
|
|
oop newTypeDecls(oop type, oop decl, oop token) |
|
|
{ |
|
|
{ |
|
|
oop obj = new(TypeDecls); |
|
|
oop obj = new(TypeDecls); |
|
|
obj->TypeDecls.type = type; |
|
|
obj->TypeDecls.type = type; |
|
|
obj->TypeDecls.typenames = newList(); |
|
|
obj->TypeDecls.typenames = newList(); |
|
|
|
|
|
obj->TypeDecls.token = token; |
|
|
TypeDecls_append(obj, decl); |
|
|
TypeDecls_append(obj, decl); |
|
|
return obj; |
|
|
return obj; |
|
|
} |
|
|
} |
|
@ -1072,6 +1080,10 @@ oop toStringOn(oop obj, oop str) |
|
|
case Integer: |
|
|
case Integer: |
|
|
String_format(str, "%d", _integerValue(obj)); |
|
|
String_format(str, "%d", _integerValue(obj)); |
|
|
break; |
|
|
break; |
|
|
|
|
|
case Float: { |
|
|
|
|
|
String_format(str, "%f", _floatValue(obj)); |
|
|
|
|
|
break; |
|
|
|
|
|
} |
|
|
case Pointer: { |
|
|
case Pointer: { |
|
|
oop base = get(obj, Pointer,base); |
|
|
oop base = get(obj, Pointer,base); |
|
|
switch (getType(base)) { |
|
|
switch (getType(base)) { |
|
@ -1137,6 +1149,11 @@ oop toStringOn(oop obj, oop str) |
|
|
toStringOn(get(obj, Dereference,rhs), str); |
|
|
toStringOn(get(obj, Dereference,rhs), str); |
|
|
break; |
|
|
break; |
|
|
} |
|
|
} |
|
|
|
|
|
case Addressof: { |
|
|
|
|
|
String_append(str, '&'); |
|
|
|
|
|
toStringOn(get(obj, Addressof,rhs), str); |
|
|
|
|
|
break; |
|
|
|
|
|
} |
|
|
case Sizeof: { |
|
|
case Sizeof: { |
|
|
String_format(str, "sizeof(%d)", toString(get(obj, Sizeof,rhs))); |
|
|
String_format(str, "sizeof(%d)", toString(get(obj, Sizeof,rhs))); |
|
|
break; |
|
|
break; |
|
@ -1364,6 +1381,10 @@ void printiln(oop obj, int indent) |
|
|
switch (getType(obj)) { |
|
|
switch (getType(obj)) { |
|
|
case Undefined: printf("nil\n"); break; |
|
|
case Undefined: printf("nil\n"); break; |
|
|
case Input: printf("<%s>\n", get(obj, Input,name)); break; |
|
|
case Input: printf("<%s>\n", get(obj, Input,name)); break; |
|
|
|
|
|
case Token: printf("Token<%s:%d %s>\n", |
|
|
|
|
|
get(obj, Token,file), |
|
|
|
|
|
get(obj, Token,line), |
|
|
|
|
|
get(obj, Token,text)); break; |
|
|
case Integer: printf("%ld\n", integerValue(obj)); break; |
|
|
case Integer: printf("%ld\n", integerValue(obj)); break; |
|
|
case Float: printf("%f\n", floatValue(obj)); break; |
|
|
case Float: printf("%f\n", floatValue(obj)); break; |
|
|
case Pointer: { |
|
|
case Pointer: { |
|
@ -1765,8 +1786,8 @@ include = HASH INCLUDE ( |
|
|
|
|
|
|
|
|
tldecl = typedec | fundefn | primdef | vardecl |
|
|
tldecl = typedec | fundefn | primdef | vardecl |
|
|
|
|
|
|
|
|
typedec = TYPEDEF |
|
|
|
|
|
t:tname d:decltor { d = newTypeDecls(t, d) } |
|
|
|
|
|
|
|
|
typedec = t:TYPEDEF |
|
|
|
|
|
n:tname d:decltor { d = newTypeDecls(n, d, t) } |
|
|
( COMMA e:decltor { TypeDecls_append(d, e) } |
|
|
( COMMA e:decltor { TypeDecls_append(d, e) } |
|
|
)* SEMI { $$ = d } |
|
|
)* SEMI { $$ = d } |
|
|
|
|
|
|
|
@ -1795,7 +1816,7 @@ members = LBRACE l:mkList ( v:vardecl { List_append(l, v) } |
|
|
| e:error { expected(e, "struct/union member specification") } |
|
|
| e:error { expected(e, "struct/union member specification") } |
|
|
) { $$ = l } |
|
|
) { $$ = l } |
|
|
|
|
|
|
|
|
inidecl = d:decltor ( a:ASSIGN ( e:initor { $$ = newAssign(a, d, e) } |
|
|
|
|
|
|
|
|
inidecl = d:decltor ( t:ASSIGN ( e:initor { $$ = newAssign(d, e, t) } |
|
|
| e:error { expected(e, "variable initialiser") } |
|
|
| e:error { expected(e, "variable initialiser") } |
|
|
) |
|
|
) |
|
|
| { $$ = d } |
|
|
| { $$ = d } |
|
@ -1823,10 +1844,14 @@ pdecl = t:tname d:decltor { $$ = newVariable(d, t, nil) } |
|
|
initor = agrinit | expr |
|
|
initor = agrinit | expr |
|
|
|
|
|
|
|
|
agrinit = LBRACE i:mkList |
|
|
agrinit = LBRACE i:mkList |
|
|
( j:initor { List_append(i, j) } |
|
|
|
|
|
( COMMA j:initor { List_append(i, j) } |
|
|
|
|
|
|
|
|
( j:initelt { List_append(i, j) } |
|
|
|
|
|
( COMMA j:initelt { List_append(i, j) } |
|
|
)* COMMA? )? RBRACE { $$ = i } |
|
|
)* COMMA? )? RBRACE { $$ = i } |
|
|
|
|
|
|
|
|
|
|
|
initelt = t:DOT i:id u:ASSIGN e:expr { $$ = newAssign(newMember(nil, i, t), e, u) } |
|
|
|
|
|
| t:LBRAK i:expr RBRAK u:ASSIGN e:expr { $$ = newAssign(newIndex (nil, i, t), e, u) } |
|
|
|
|
|
| initor |
|
|
|
|
|
|
|
|
fundefn = t:tname d:funid |
|
|
fundefn = t:tname d:funid |
|
|
p:params b:block { $$ = newFunction(d, t, p, b) } |
|
|
p:params b:block { $$ = newFunction(d, t, p, b) } |
|
|
|
|
|
|
|
@ -1866,57 +1891,57 @@ expropt = expr | { $$ = nil } |
|
|
|
|
|
|
|
|
expr = assign |
|
|
expr = assign |
|
|
|
|
|
|
|
|
assign = l:unary a:ASSIGN x:expr { $$ = newAssign(a, l, x) } |
|
|
|
|
|
|
|
|
assign = l:unary t:ASSIGN x:expr { $$ = newAssign(l, x, t) } |
|
|
| logor |
|
|
| logor |
|
|
|
|
|
|
|
|
logor = l:logand ( BARBAR r:logand { l = newBinary(LOR, l, r) } |
|
|
|
|
|
|
|
|
logor = l:logand ( t:BARBAR r:logand { l = newBinary(LOR, l, r, t) } |
|
|
)* { $$ = l } |
|
|
)* { $$ = l } |
|
|
|
|
|
|
|
|
logand = l:bitor ( ANDAND r:bitor { l = newBinary(LAND, l, r) } |
|
|
|
|
|
|
|
|
logand = l:bitor ( t:ANDAND r:bitor { l = newBinary(LAND, l, r, t) } |
|
|
)* { $$ = l } |
|
|
)* { $$ = l } |
|
|
|
|
|
|
|
|
bitor = l:bitxor ( BAR r:bitxor { l = newBinary(BOR, l, r) } |
|
|
|
|
|
|
|
|
bitor = l:bitxor ( t:BAR r:bitxor { l = newBinary(BOR, l, r, t) } |
|
|
)* { $$ = l } |
|
|
)* { $$ = l } |
|
|
|
|
|
|
|
|
bitxor = l:bitand ( HAT r:bitand { l = newBinary(BXOR, l, r) } |
|
|
|
|
|
|
|
|
bitxor = l:bitand ( t:HAT r:bitand { l = newBinary(BXOR, l, r, t) } |
|
|
)* { $$ = l } |
|
|
)* { $$ = l } |
|
|
|
|
|
|
|
|
bitand = l:equal ( AND r:equal { l = newBinary(BAND, l, r) } |
|
|
|
|
|
|
|
|
bitand = l:equal ( t:AND r:equal { l = newBinary(BAND, l, r, t) } |
|
|
)* { $$ = l } |
|
|
)* { $$ = l } |
|
|
|
|
|
|
|
|
equal = l:inequal ( EQUAL r:inequal { l = newBinary(EQ, l, r) } |
|
|
|
|
|
| NEQUAL r:inequal { l = newBinary(NE, l, r) } |
|
|
|
|
|
)* { $$ = l } |
|
|
|
|
|
|
|
|
equal = l:inequal ( t:EQUAL r:inequal { l = newBinary(EQ, l, r, t) } |
|
|
|
|
|
| t:NEQUAL r:inequal { l = newBinary(NE, l, r, t) } |
|
|
|
|
|
)* { $$ = l } |
|
|
|
|
|
|
|
|
inequal = l:shift ( LESS r:shift { l = newBinary(LT, l, r) } |
|
|
|
|
|
| LESSEQ r:shift { l = newBinary(LE, l, r) } |
|
|
|
|
|
| GRTREQ r:shift { l = newBinary(GE, l, r) } |
|
|
|
|
|
| GRTR r:shift { l = newBinary(GT, l, r) } |
|
|
|
|
|
|
|
|
inequal = l:shift ( t:LESS r:shift { l = newBinary(LT, l, r, t) } |
|
|
|
|
|
| t:LESSEQ r:shift { l = newBinary(LE, l, r, t) } |
|
|
|
|
|
| t:GRTREQ r:shift { l = newBinary(GE, l, r, t) } |
|
|
|
|
|
| t:GRTR r:shift { l = newBinary(GT, l, r, t) } |
|
|
)* { $$ = l } |
|
|
)* { $$ = l } |
|
|
|
|
|
|
|
|
shift = l:sum ( LSHIFT r:sum { l = newBinary(SHL, l, r) } |
|
|
|
|
|
| RSHIFT r:sum { l = newBinary(SHR, l, r) } |
|
|
|
|
|
|
|
|
shift = l:sum ( t:LSHIFT r:sum { l = newBinary(SHL, l, r, t) } |
|
|
|
|
|
| t:RSHIFT r:sum { l = newBinary(SHR, l, r, t) } |
|
|
)* { $$ = l } |
|
|
)* { $$ = l } |
|
|
|
|
|
|
|
|
sum = l:prod ( PLUS r:prod { l = newBinary(ADD, l, r) } |
|
|
|
|
|
| MINUS r:prod { l = newBinary(SUB, l, r) } |
|
|
|
|
|
|
|
|
sum = l:prod ( t:PLUS r:prod { l = newBinary(ADD, l, r, t) } |
|
|
|
|
|
| t:MINUS r:prod { l = newBinary(SUB, l, r, t) } |
|
|
)* { $$ = l } |
|
|
)* { $$ = l } |
|
|
|
|
|
|
|
|
prod = l:unary ( STAR r:unary { l = newBinary(MUL, l, r) } |
|
|
|
|
|
| SLASH r:unary { l = newBinary(DIV, l, r) } |
|
|
|
|
|
| PCENT r:unary { l = newBinary(MOD, l, r) } |
|
|
|
|
|
|
|
|
prod = l:unary ( t:STAR r:unary { l = newBinary(MUL, l, r, t) } |
|
|
|
|
|
| t:SLASH r:unary { l = newBinary(DIV, l, r, t) } |
|
|
|
|
|
| t:PCENT r:unary { l = newBinary(MOD, l, r, t) } |
|
|
)* { $$ = l } |
|
|
)* { $$ = l } |
|
|
|
|
|
|
|
|
unary = MINUS r:unary { $$ = newUnary(NEG, r) } |
|
|
|
|
|
| PLING r:unary { $$ = newUnary(NOT, r) } |
|
|
|
|
|
| TILDE r:unary { $$ = newUnary(COM, r) } |
|
|
|
|
|
| STAR r:unary { $$ = newDereference(r) } |
|
|
|
|
|
| AND r:unary { $$ = newAddressof(r) } |
|
|
|
|
|
| PPLUS r:unary { $$ = newUnary(PREINC, r) } |
|
|
|
|
|
| MMINUS r:unary { $$ = newUnary(PREDEC, r) } |
|
|
|
|
|
| SIZEOF |
|
|
|
|
|
( r:unary { $$ = newSizeof(r) } |
|
|
|
|
|
| LPAREN t:tnamdec RPAREN { $$ = newSizeof(t) } |
|
|
|
|
|
|
|
|
unary = t:MINUS r:unary { $$ = newUnary(NEG, r, t) } |
|
|
|
|
|
| t:PLING r:unary { $$ = newUnary(NOT, r, t) } |
|
|
|
|
|
| t:TILDE r:unary { $$ = newUnary(COM, r, t) } |
|
|
|
|
|
| t:STAR r:unary { $$ = newDereference( r, t) } |
|
|
|
|
|
| t:AND r:unary { $$ = newAddressof( r, t) } |
|
|
|
|
|
| t:PPLUS r:unary { $$ = newUnary(PREINC, r, t) } |
|
|
|
|
|
| t:MMINUS r:unary { $$ = newUnary(PREDEC, r, t) } |
|
|
|
|
|
| t:SIZEOF |
|
|
|
|
|
( r:unary { $$ = newSizeof(r, t) } |
|
|
|
|
|
| LPAREN r:tnamdec RPAREN { $$ = newSizeof(r, t) } |
|
|
) |
|
|
) |
|
|
| cast |
|
|
| cast |
|
|
| postfix |
|
|
| postfix |
|
@ -1926,20 +1951,20 @@ cast = LPAREN t:tnamdec |
|
|
|
|
|
|
|
|
tnamdec = t:tname d:decltor { $$ = makeType(t, d) } |
|
|
tnamdec = t:tname d:decltor { $$ = makeType(t, d) } |
|
|
|
|
|
|
|
|
postfix = v:value ( a:args { v = newCall(v, a) } |
|
|
|
|
|
| i:index { v = newIndex(v, i) } |
|
|
|
|
|
| PPLUS { v = newUnary(POSTINC, v) } |
|
|
|
|
|
| MMINUS { v = newUnary(POSTDEC, v) } |
|
|
|
|
|
| DOT i:id { v = newMember(v, i) } |
|
|
|
|
|
| ARROW i:id { v = newMember(newDereference(v), i) } |
|
|
|
|
|
)* { $$ = v } |
|
|
|
|
|
|
|
|
postfix = v:value ( t:LPAREN a:args RPAREN { v = newCall(v, a, t) } |
|
|
|
|
|
| t:LBRAK i:expr RBRAK { v = newIndex(v, i, t) } |
|
|
|
|
|
| t:PPLUS { v = newUnary(POSTINC, v, t) } |
|
|
|
|
|
| t:MMINUS { v = newUnary(POSTDEC, v, t) } |
|
|
|
|
|
| t:DOT i:id { v = newMember(v, i, t) } |
|
|
|
|
|
| t:ARROW i:id { v = newMember(newDereference(v, t), i, t) } |
|
|
|
|
|
)* { $$ = v } |
|
|
|
|
|
|
|
|
args = LPAREN a:mkList |
|
|
|
|
|
( e:expr { List_append(a, e) } |
|
|
|
|
|
( COMMA e:expr { List_append(a, e) } |
|
|
|
|
|
)* )? RPAREN { $$ = a } |
|
|
|
|
|
|
|
|
args = a:mkList |
|
|
|
|
|
( e:expr { List_append(a, e) } |
|
|
|
|
|
( COMMA e:expr { List_append(a, e) } |
|
|
|
|
|
)* )? { $$ = a } |
|
|
|
|
|
|
|
|
index = LBRAK e:expr RBRAK { $$ = e } |
|
|
|
|
|
|
|
|
# index = LBRAK e:expr RBRAK { $$ = e } |
|
|
|
|
|
|
|
|
value = LPAREN e:expr RPAREN { $$ = e } |
|
|
value = LPAREN e:expr RPAREN { $$ = e } |
|
|
| float |
|
|
| float |
|
@ -2002,65 +2027,65 @@ eol = ( '\n' '\r'? | '\r' '\n'? ) { lineNo += 1 } |
|
|
comment = "//" (!eol .)* eol |
|
|
comment = "//" (!eol .)* eol |
|
|
| "/*" (!"*/" (eol | .))* "*/" |
|
|
| "/*" (!"*/" (eol | .))* "*/" |
|
|
|
|
|
|
|
|
INCLUDE = "include" ![_a-zA-Z0-9] - |
|
|
|
|
|
EXTERN = "extern" ![_a-zA-Z0-9] - |
|
|
|
|
|
STATIC = "static" ![_a-zA-Z0-9] - |
|
|
|
|
|
TYPEDEF = "typedef" ![_a-zA-Z0-9] - |
|
|
|
|
|
VOID = "void" ![_a-zA-Z0-9] - |
|
|
|
|
|
CHAR = "char" ![_a-zA-Z0-9] - |
|
|
|
|
|
SHORT = "short" ![_a-zA-Z0-9] - |
|
|
|
|
|
INT = "int" ![_a-zA-Z0-9] - |
|
|
|
|
|
LONG = "long" ![_a-zA-Z0-9] - |
|
|
|
|
|
FLOAT = "float" ![_a-zA-Z0-9] - |
|
|
|
|
|
DOUBLE = "double" ![_a-zA-Z0-9] - |
|
|
|
|
|
STRUCT = "struct" ![_a-zA-Z0-9] - |
|
|
|
|
|
UNION = "union" ![_a-zA-Z0-9] - |
|
|
|
|
|
ENUM = "enum" ![_a-zA-Z0-9] - |
|
|
|
|
|
# UNION = "union" ![_a-zA-Z0-9] - |
|
|
|
|
|
# ENUM = "enum" ![_a-zA-Z0-9] - |
|
|
|
|
|
SIZEOF = "sizeof" ![_a-zA-Z0-9] - |
|
|
|
|
|
IF = "if" ![_a-zA-Z0-9] - |
|
|
|
|
|
ELSE = "else" ![_a-zA-Z0-9] - |
|
|
|
|
|
WHILE = "while" ![_a-zA-Z0-9] - |
|
|
|
|
|
FOR = "for" ![_a-zA-Z0-9] - |
|
|
|
|
|
RETURN = "return" ![_a-zA-Z0-9] - |
|
|
|
|
|
CONTINU = "continue" ![_a-zA-Z0-9] - |
|
|
|
|
|
BREAK = "break" ![_a-zA-Z0-9] - |
|
|
|
|
|
DOT = "." !"." - |
|
|
|
|
|
ARROW = "->" - |
|
|
|
|
|
ETC = "..." - |
|
|
|
|
|
HASH = "#" - |
|
|
|
|
|
ASSIGN = < "=" !"=" > { $$ = newToken(yytext) } - |
|
|
|
|
|
PLUS = "+" !"+" - |
|
|
|
|
|
PPLUS = "++" - |
|
|
|
|
|
MINUS = "-" !"-" - |
|
|
|
|
|
MMINUS = "--" - |
|
|
|
|
|
STAR = "*" - |
|
|
|
|
|
BAR = "|" !"|" - |
|
|
|
|
|
BARBAR = "||" - |
|
|
|
|
|
AND = "&" !"&" - |
|
|
|
|
|
ANDAND = "&&" - |
|
|
|
|
|
HAT = "^" - |
|
|
|
|
|
EQUAL = "==" - |
|
|
|
|
|
NEQUAL = "!=" - |
|
|
|
|
|
LESS = "<" ![=<] - |
|
|
|
|
|
LESSEQ = "<=" - |
|
|
|
|
|
GRTREQ = ">=" - |
|
|
|
|
|
GRTR = ">" ![=>] - |
|
|
|
|
|
LSHIFT = "<<" - |
|
|
|
|
|
RSHIFT = ">>" - |
|
|
|
|
|
SLASH = "/" - |
|
|
|
|
|
PCENT = "%" - |
|
|
|
|
|
PLING = "!" !"=" - |
|
|
|
|
|
TILDE = "~" - |
|
|
|
|
|
LPAREN = "(" - |
|
|
|
|
|
RPAREN = ")" - |
|
|
|
|
|
LBRAK = "[" - |
|
|
|
|
|
RBRAK = "]" - |
|
|
|
|
|
LBRACE = "{" - |
|
|
|
|
|
RBRACE = "}" - |
|
|
|
|
|
COMMA = "," - |
|
|
|
|
|
SEMI = ";" - |
|
|
|
|
|
|
|
|
INCLUDE = < "include" ![_a-zA-Z0-9] > { $$ = newToken(yytext) } - |
|
|
|
|
|
EXTERN = < "extern" ![_a-zA-Z0-9] > { $$ = newToken(yytext) } - |
|
|
|
|
|
STATIC = < "static" ![_a-zA-Z0-9] > { $$ = newToken(yytext) } - |
|
|
|
|
|
TYPEDEF = < "typedef" ![_a-zA-Z0-9] > { $$ = newToken(yytext) } - |
|
|
|
|
|
VOID = < "void" ![_a-zA-Z0-9] > { $$ = newToken(yytext) } - |
|
|
|
|
|
CHAR = < "char" ![_a-zA-Z0-9] > { $$ = newToken(yytext) } - |
|
|
|
|
|
SHORT = < "short" ![_a-zA-Z0-9] > { $$ = newToken(yytext) } - |
|
|
|
|
|
INT = < "int" ![_a-zA-Z0-9] > { $$ = newToken(yytext) } - |
|
|
|
|
|
LONG = < "long" ![_a-zA-Z0-9] > { $$ = newToken(yytext) } - |
|
|
|
|
|
FLOAT = < "float" ![_a-zA-Z0-9] > { $$ = newToken(yytext) } - |
|
|
|
|
|
DOUBLE = < "double" ![_a-zA-Z0-9] > { $$ = newToken(yytext) } - |
|
|
|
|
|
STRUCT = < "struct" ![_a-zA-Z0-9] > { $$ = newToken(yytext) } - |
|
|
|
|
|
UNION = < "union" ![_a-zA-Z0-9] > { $$ = newToken(yytext) } - |
|
|
|
|
|
ENUM = < "enum" ![_a-zA-Z0-9] > { $$ = newToken(yytext) } - |
|
|
|
|
|
# UNION = < "union" ![_a-zA-Z0-9] > { $$ = newToken(yytext) } - |
|
|
|
|
|
# ENUM = < "enum" ![_a-zA-Z0-9] > { $$ = newToken(yytext) } - |
|
|
|
|
|
SIZEOF = < "sizeof" ![_a-zA-Z0-9] > { $$ = newToken(yytext) } - |
|
|
|
|
|
IF = < "if" ![_a-zA-Z0-9] > { $$ = newToken(yytext) } - |
|
|
|
|
|
ELSE = < "else" ![_a-zA-Z0-9] > { $$ = newToken(yytext) } - |
|
|
|
|
|
WHILE = < "while" ![_a-zA-Z0-9] > { $$ = newToken(yytext) } - |
|
|
|
|
|
FOR = < "for" ![_a-zA-Z0-9] > { $$ = newToken(yytext) } - |
|
|
|
|
|
RETURN = < "return" ![_a-zA-Z0-9] > { $$ = newToken(yytext) } - |
|
|
|
|
|
CONTINU = < "continue" ![_a-zA-Z0-9] > { $$ = newToken(yytext) } - |
|
|
|
|
|
BREAK = < "break" ![_a-zA-Z0-9] > { $$ = newToken(yytext) } - |
|
|
|
|
|
DOT = < "." !"." > { $$ = newToken(yytext) } - |
|
|
|
|
|
ARROW = < "->" > { $$ = newToken(yytext) } - |
|
|
|
|
|
ETC = < "..." > { $$ = newToken(yytext) } - |
|
|
|
|
|
HASH = < "#" > { $$ = newToken(yytext) } - |
|
|
|
|
|
ASSIGN = < "=" !"=" > { $$ = newToken(yytext) } - |
|
|
|
|
|
PLUS = < "+" !"+" > { $$ = newToken(yytext) } - |
|
|
|
|
|
PPLUS = < "++" > { $$ = newToken(yytext) } - |
|
|
|
|
|
MINUS = < "-" !"-" > { $$ = newToken(yytext) } - |
|
|
|
|
|
MMINUS = < "--" > { $$ = newToken(yytext) } - |
|
|
|
|
|
STAR = < "*" > { $$ = newToken(yytext) } - |
|
|
|
|
|
BAR = < "|" !"|" > { $$ = newToken(yytext) } - |
|
|
|
|
|
BARBAR = < "||" > { $$ = newToken(yytext) } - |
|
|
|
|
|
AND = < "&" !"&" > { $$ = newToken(yytext) } - |
|
|
|
|
|
ANDAND = < "&&" > { $$ = newToken(yytext) } - |
|
|
|
|
|
HAT = < "^" > { $$ = newToken(yytext) } - |
|
|
|
|
|
EQUAL = < "==" > { $$ = newToken(yytext) } - |
|
|
|
|
|
NEQUAL = "!=" > { $$ = newToken(yytext) } - |
|
|
|
|
|
LESS = < "<" ![=<] > { $$ = newToken(yytext) } - |
|
|
|
|
|
LESSEQ = < "<=" > { $$ = newToken(yytext) } - |
|
|
|
|
|
GRTREQ = < ">=" > { $$ = newToken(yytext) } - |
|
|
|
|
|
GRTR = < ">" ![=>] > { $$ = newToken(yytext) } - |
|
|
|
|
|
LSHIFT = < "<<" > { $$ = newToken(yytext) } - |
|
|
|
|
|
RSHIFT = < ">>" > { $$ = newToken(yytext) } - |
|
|
|
|
|
SLASH = < "/" > { $$ = newToken(yytext) } - |
|
|
|
|
|
PCENT = < "%" > { $$ = newToken(yytext) } - |
|
|
|
|
|
PLING = < "!" !"=" > { $$ = newToken(yytext) } - |
|
|
|
|
|
TILDE = < "~" > { $$ = newToken(yytext) } - |
|
|
|
|
|
LPAREN = < "(" > { $$ = newToken(yytext) } - |
|
|
|
|
|
RPAREN = < ")" > { $$ = newToken(yytext) } - |
|
|
|
|
|
LBRAK = < "[" > { $$ = newToken(yytext) } - |
|
|
|
|
|
RBRAK = < "]" > { $$ = newToken(yytext) } - |
|
|
|
|
|
LBRACE = < "{" > { $$ = newToken(yytext) } - |
|
|
|
|
|
RBRACE = < "}" > { $$ = newToken(yytext) } - |
|
|
|
|
|
COMMA = < "," > { $$ = newToken(yytext) } - |
|
|
|
|
|
SEMI = < ";" > { $$ = newToken(yytext) } - |
|
|
|
|
|
|
|
|
%% |
|
|
%% |
|
|
; |
|
|
; |
|
@ -2227,7 +2252,7 @@ cvt_t converter(int tfrom, int tto) |
|
|
{ 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // short |
|
|
{ 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // short |
|
|
{ 0, 0, 0, cvtI, cvtI, 0, 0, 0, 0 }, // int |
|
|
{ 0, 0, 0, cvtI, cvtI, 0, 0, 0, 0 }, // int |
|
|
{ 0, 0, 0, cvtI, 0, 0, 0, cvt_, 0 }, // long |
|
|
{ 0, 0, 0, cvtI, 0, 0, 0, cvt_, 0 }, // long |
|
|
{ 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // float |
|
|
|
|
|
|
|
|
{ 0, 0, 0, 0, 0, cvt_, 0, 0, 0 }, // float |
|
|
{ 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // double |
|
|
{ 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // double |
|
|
{ 0, 0, 0, 0, cvt_, 0, 0, cvt_, 0 }, // pointer |
|
|
{ 0, 0, 0, 0, cvt_, 0, 0, cvt_, 0 }, // pointer |
|
|
{ 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // array |
|
|
{ 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // array |
|
@ -2584,7 +2609,9 @@ oop typeCheck(oop exp, oop fntype) |
|
|
case Dereference: { |
|
|
case Dereference: { |
|
|
oop rhs = get(exp, Dereference,rhs); |
|
|
oop rhs = get(exp, Dereference,rhs); |
|
|
oop rht = typeCheck(rhs, fntype); |
|
|
oop rht = typeCheck(rhs, fntype); |
|
|
if (!is(Tpointer, rht)) fatal("cannot dereference '%s'", toString(rhs)); |
|
|
|
|
|
|
|
|
if (!is(Tpointer, rht)) |
|
|
|
|
|
fatal("%scannot dereference '%s'", |
|
|
|
|
|
tokloc(get(exp, Dereference,token)), toString(rhs)); |
|
|
return get(rht, Tpointer,target); |
|
|
return get(rht, Tpointer,target); |
|
|
} |
|
|
} |
|
|
case Cast: { |
|
|
case Cast: { |
|
@ -2668,7 +2695,8 @@ oop typeCheck(oop exp, oop fntype) |
|
|
if (is(Tarray, lhs) && t_int == rhs) { |
|
|
if (is(Tarray, lhs) && t_int == rhs) { |
|
|
return newTpointer(get(lhs, Tarray,target)); |
|
|
return newTpointer(get(lhs, Tarray,target)); |
|
|
} |
|
|
} |
|
|
fatal("cannot add '%s' and '%s'", toString(lhs), toString(rhs)); |
|
|
|
|
|
|
|
|
fatal("%scannot add '%s' and '%s'", tokloc(get(exp, Binary,token)), |
|
|
|
|
|
toString(lhs), toString(rhs)); |
|
|
break; |
|
|
break; |
|
|
} |
|
|
} |
|
|
case SUB: assert(!"unimplemented"); break; |
|
|
case SUB: assert(!"unimplemented"); break; |
|
@ -2691,7 +2719,9 @@ oop typeCheck(oop exp, oop fntype) |
|
|
case Index: { |
|
|
case Index: { |
|
|
oop lhs = typeCheck(get(exp, Index,lhs), fntype); |
|
|
oop lhs = typeCheck(get(exp, Index,lhs), fntype); |
|
|
oop rhs = typeCheck(get(exp, Index,rhs), fntype); |
|
|
oop rhs = typeCheck(get(exp, Index,rhs), fntype); |
|
|
if (t_int != rhs) fatal("array index is not 'int': %s", toString(get(exp, Binary,rhs))); |
|
|
|
|
|
|
|
|
if (t_int != rhs) |
|
|
|
|
|
fatal("%sarray index is not 'int': %s", |
|
|
|
|
|
tokloc(get(exp, Index,token)), toString(get(exp, Index,rhs))); |
|
|
switch (getType(lhs)) { |
|
|
switch (getType(lhs)) { |
|
|
case Tpointer: assert(!"unimplemented"); |
|
|
case Tpointer: assert(!"unimplemented"); |
|
|
case Tarray: return get(lhs, Tarray,target); |
|
|
case Tarray: return get(lhs, Tarray,target); |
|
@ -2735,7 +2765,7 @@ oop typeCheck(oop exp, oop fntype) |
|
|
goto error; |
|
|
goto error; |
|
|
} |
|
|
} |
|
|
error: |
|
|
error: |
|
|
fatal("incompatible types assigning '%s' to '%s'", toString(rhs), toString(lhs)); |
|
|
|
|
|
|
|
|
fatal("%sincompatible types assigning '%s' to '%s'", tokloc(get(exp, Assign,token)), toString(rhs), toString(lhs)); |
|
|
return lhs; |
|
|
return lhs; |
|
|
} |
|
|
} |
|
|
case If: { |
|
|
case If: { |
|
@ -2858,7 +2888,8 @@ oop typeCheck(oop exp, oop fntype) |
|
|
oop function = get(exp, Call,function ); |
|
|
oop function = get(exp, Call,function ); |
|
|
oop arguments = get(exp, Call,arguments); |
|
|
oop arguments = get(exp, Call,arguments); |
|
|
oop tfunc = typeCheck(function, fntype); |
|
|
oop tfunc = typeCheck(function, fntype); |
|
|
if (!is(Tfunction, tfunc)) fatal("cannot call %s", getTypeName(tfunc)); |
|
|
|
|
|
|
|
|
if (!is(Tfunction, tfunc)) |
|
|
|
|
|
fatal("%scannot call %s", tokloc(get(exp, Call,token)), toString(tfunc)); |
|
|
oop params = get(tfunc, Tfunction,parameters); |
|
|
oop params = get(tfunc, Tfunction,parameters); |
|
|
int argc = get(arguments, List,size); |
|
|
int argc = get(arguments, List,size); |
|
|
oop *argv = get(arguments, List,elements); |
|
|
oop *argv = get(arguments, List,elements); |
|
@ -2866,7 +2897,8 @@ oop typeCheck(oop exp, oop fntype) |
|
|
oop *parv = get(params, List,elements); |
|
|
oop *parv = get(params, List,elements); |
|
|
int vararg = parc && (t_etc == parv[parc - 1]); |
|
|
int vararg = parc && (t_etc == parv[parc - 1]); |
|
|
if ((!vararg && (argc != parc)) || (vararg && (argc < parc - 1))) |
|
|
if ((!vararg && (argc != parc)) || (vararg && (argc < parc - 1))) |
|
|
fatal("wrong number (%d) of arguments, expected %d", argc, parc); |
|
|
|
|
|
|
|
|
fatal("%swrong number (%d) of arguments, expected %d", |
|
|
|
|
|
tokloc(get(exp, Call,token)), argc, parc); |
|
|
int argn = 0; |
|
|
int argn = 0; |
|
|
while (argn < argc) { |
|
|
while (argn < argc) { |
|
|
oop part = parv[argn]; |
|
|
oop part = parv[argn]; |
|
@ -3295,16 +3327,17 @@ oop assign(oop lhs, oop rhs) |
|
|
return setMemory(memory, offset, vtype, eval(rhs)); |
|
|
return setMemory(memory, offset, vtype, eval(rhs)); |
|
|
} |
|
|
} |
|
|
case Dereference: { // *<&var> = rhs, *<&const> = rhs, *<&memory> = rhs |
|
|
case Dereference: { // *<&var> = rhs, *<&const> = rhs, *<&memory> = rhs |
|
|
lhs = eval(get(lhs, Dereference,rhs)); |
|
|
|
|
|
switch (getType(lhs)) { |
|
|
|
|
|
|
|
|
oop ptr = eval(get(lhs, Dereference,rhs)); |
|
|
|
|
|
switch (getType(ptr)) { |
|
|
case Pointer: { // &x |
|
|
case Pointer: { // &x |
|
|
oop base = get(lhs, Pointer,base); |
|
|
|
|
|
int offset = get(lhs, Pointer,offset); |
|
|
|
|
|
oop type = get(get(lhs, Pointer,type), Tpointer,target); |
|
|
|
|
|
|
|
|
oop base = get(ptr, Pointer,base); |
|
|
|
|
|
int offset = get(ptr, Pointer,offset); |
|
|
|
|
|
oop type = get(get(ptr, Pointer,type), Tpointer,target); |
|
|
int scale = typeSize(type); |
|
|
int scale = typeSize(type); |
|
|
switch (getType(base)) { |
|
|
switch (getType(base)) { |
|
|
case Integer: { // (void *)(intptr_t)N |
|
|
case Integer: { // (void *)(intptr_t)N |
|
|
fatal("attempt to store into arbitrary memory location"); |
|
|
|
|
|
|
|
|
fatal("%sattempt to store into arbitrary memory location", |
|
|
|
|
|
tokloc(get(lhs, Dereference,token))); |
|
|
} |
|
|
} |
|
|
case Variable: { // &var |
|
|
case Variable: { // &var |
|
|
if (offset) fatal("pointer modified"); |
|
|
if (offset) fatal("pointer modified"); |
|
@ -3540,6 +3573,7 @@ oop eval(oop exp) |
|
|
switch (getType(exp)) { |
|
|
switch (getType(exp)) { |
|
|
case Undefined: assert(!"this cannot happen"); |
|
|
case Undefined: assert(!"this cannot happen"); |
|
|
case Input: assert(!"this cannot happen"); |
|
|
case Input: assert(!"this cannot happen"); |
|
|
|
|
|
case Token: assert(!"this cannot happen"); |
|
|
case Integer: RETURN(exp); |
|
|
case Integer: RETURN(exp); |
|
|
case Float: RETURN(exp); |
|
|
case Float: RETURN(exp); |
|
|
case Pointer: RETURN(exp); |
|
|
case Pointer: RETURN(exp); |
|
@ -3610,7 +3644,8 @@ oop eval(oop exp) |
|
|
} |
|
|
} |
|
|
case Index: { |
|
|
case Index: { |
|
|
oop ondex = eval(get(rhs, Index,rhs)); |
|
|
oop ondex = eval(get(rhs, Index,rhs)); |
|
|
if (!is(Integer, ondex)) fatal("array index is not 'int'"); |
|
|
|
|
|
|
|
|
if (!is(Integer, ondex)) |
|
|
|
|
|
fatal("%sarray index is not 'int'", tokloc(get(rhs, Index,token))); |
|
|
int index = _integerValue(ondex); |
|
|
int index = _integerValue(ondex); |
|
|
oop lhs = eval(get(rhs, Index,lhs)); |
|
|
oop lhs = eval(get(rhs, Index,lhs)); |
|
|
switch (getType(lhs)) { |
|
|
switch (getType(lhs)) { |
|
@ -3626,7 +3661,7 @@ oop eval(oop exp) |
|
|
default: |
|
|
default: |
|
|
break; |
|
|
break; |
|
|
} |
|
|
} |
|
|
fatal("cannot take address of: %s", toString(rhs)); |
|
|
|
|
|
|
|
|
fatal("%scannot take address: %s", tokloc(get(exp, Addressof,token)), toString(exp)); |
|
|
break; |
|
|
break; |
|
|
} |
|
|
} |
|
|
case Dereference: { |
|
|
case Dereference: { |
|
@ -3671,7 +3706,8 @@ oop eval(oop exp) |
|
|
default: break; |
|
|
default: break; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
fatal("illegal increment operation: %s", toString(exp)); |
|
|
|
|
|
|
|
|
fatal("%sillegal increment operation: %s", |
|
|
|
|
|
tokloc(get(exp, Unary,token)), toString(exp)); |
|
|
} |
|
|
} |
|
|
case NEG: |
|
|
case NEG: |
|
|
case NOT: |
|
|
case NOT: |
|
@ -3821,6 +3857,7 @@ oop eval(oop exp) |
|
|
switch (getType(type)) { |
|
|
switch (getType(type)) { |
|
|
case Tpointer: { |
|
|
case Tpointer: { |
|
|
if (is(Pointer,rhs)) RETURN(castPointer(rhs, type)); |
|
|
if (is(Pointer,rhs)) RETURN(castPointer(rhs, type)); |
|
|
|
|
|
default: break; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
RETURN(cvt(rhs)); |
|
|
RETURN(cvt(rhs)); |
|
@ -3933,6 +3970,7 @@ oop preval(oop exp) |
|
|
switch (getType(exp)) { |
|
|
switch (getType(exp)) { |
|
|
case Undefined: return exp; |
|
|
case Undefined: return exp; |
|
|
case Input: break; |
|
|
case Input: break; |
|
|
|
|
|
case Token: break; |
|
|
case Integer: return exp; |
|
|
case Integer: return exp; |
|
|
case Float: return exp; |
|
|
case Float: return exp; |
|
|
case Pointer: return exp; |
|
|
case Pointer: return exp; |
|
@ -3978,7 +4016,8 @@ oop preval(oop exp) |
|
|
default: break; |
|
|
default: break; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
fatal("illegal increment operation: %s", toString(exp)); |
|
|
|
|
|
|
|
|
fatal("%sillegal increment operation: %s", |
|
|
|
|
|
tokloc(get(exp, Unary,token)), toString(exp)); |
|
|
} |
|
|
} |
|
|
case NEG: |
|
|
case NEG: |
|
|
case NOT: |
|
|
case NOT: |
|
@ -4391,6 +4430,7 @@ void compileOn(oop exp, oop program, oop cs, oop bs) |
|
|
switch (getType(exp)) { |
|
|
switch (getType(exp)) { |
|
|
case Undefined: EMITio(iPUSH, exp); return; |
|
|
case Undefined: EMITio(iPUSH, exp); return; |
|
|
case Input: EMITio(iPUSH, exp); return; |
|
|
case Input: EMITio(iPUSH, exp); return; |
|
|
|
|
|
case Token: assert(!"this cannot happen"); |
|
|
case Integer: EMITio(iPUSH, exp); return; |
|
|
case Integer: EMITio(iPUSH, exp); return; |
|
|
case Float: EMITio(iPUSH, exp); return; |
|
|
case Float: EMITio(iPUSH, exp); return; |
|
|
case Pointer: assert(!"unimplemented"); |
|
|
case Pointer: assert(!"unimplemented"); |
|
|