|
|
@ -1,6 +1,6 @@ |
|
|
|
# main.leg -- C parser + interpreter |
|
|
|
# |
|
|
|
# Last edited: 2025-01-25 09:19:51 by piumarta on m1mbp |
|
|
|
# Last edited: 2025-01-26 11:37:20 by piumarta on zora |
|
|
|
|
|
|
|
%{ |
|
|
|
; |
|
|
@ -149,6 +149,9 @@ union Object |
|
|
|
# undef _ |
|
|
|
}; |
|
|
|
|
|
|
|
void println(oop obj); |
|
|
|
char *toString(oop obj); |
|
|
|
|
|
|
|
int opt_O = 0; // optimise (use VM) |
|
|
|
int opt_v = 0; // verbose (print eval output, parser output, compiled code) |
|
|
|
int opt_x = 0; // disable execution |
|
|
@ -300,7 +303,7 @@ long integerValue(oop obj) |
|
|
|
case Float: return _floatValue(obj); |
|
|
|
default: break; |
|
|
|
} |
|
|
|
fatal("cannot convert %s to integer", getTypeName(obj)); |
|
|
|
fatal("cannot convert %s to integer: %s", getTypeName(obj), toString(obj)); |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
@ -594,9 +597,6 @@ CTOR1(Return, value); |
|
|
|
CTOR0(Continue); |
|
|
|
CTOR0(Break); |
|
|
|
|
|
|
|
void println(oop obj); |
|
|
|
char *toString(oop obj); |
|
|
|
|
|
|
|
oop newTbase(char *name, int size, base_t type) |
|
|
|
{ |
|
|
|
oop obj = new(Tbase); |
|
|
@ -1041,6 +1041,11 @@ oop toStringOn(oop obj, oop str) |
|
|
|
String_append(str, ')'); |
|
|
|
break; |
|
|
|
} |
|
|
|
case Reference: { |
|
|
|
String_append(str, '&'); |
|
|
|
toStringOn(get(obj, Reference,target), str); |
|
|
|
break; |
|
|
|
} |
|
|
|
case Variable: { |
|
|
|
oop type = get(obj, Variable,type); |
|
|
|
oop name = get(obj, Variable,name); |
|
|
@ -2008,8 +2013,16 @@ oop eval(oop exp, oop env) |
|
|
|
case LE: return IRELOP(lhs, <=, rhs); |
|
|
|
case GE: return IRELOP(lhs, >=, rhs); |
|
|
|
case GT: return IRELOP(lhs, > , rhs); |
|
|
|
case EQ: return IRELOP(lhs, == , rhs); |
|
|
|
case NE: return IRELOP(lhs, !=, rhs); |
|
|
|
case EQ: { |
|
|
|
if (is(Reference,lhs) && is(Integer,rhs) && _integerValue(rhs) == 0) return false; |
|
|
|
if (is(Reference,rhs) && is(Integer,lhs) && _integerValue(lhs) == 0) return false; |
|
|
|
return IRELOP(lhs, == , rhs); |
|
|
|
} |
|
|
|
case NE: { |
|
|
|
if (is(Reference,lhs) && is(Integer,rhs) && _integerValue(rhs) == 0) return true; |
|
|
|
if (is(Reference,rhs) && is(Integer,lhs) && _integerValue(lhs) == 0) return true; |
|
|
|
return IRELOP(lhs, !=, rhs); |
|
|
|
} |
|
|
|
case BAND: return IBINOP(lhs, & , rhs); |
|
|
|
case BXOR: return IBINOP(lhs, ^ , rhs); |
|
|
|
case BOR: return IBINOP(lhs, | , rhs); |
|
|
@ -2889,7 +2902,7 @@ oop typeCheck(oop exp, oop fntype) |
|
|
|
case GE: assert(!"unimplemented"); break; |
|
|
|
case GT: return t_int; |
|
|
|
case EQ: return t_int; |
|
|
|
case NE: assert(!"unimplemented"); break; |
|
|
|
case NE: return t_int; |
|
|
|
case BAND: assert(!"unimplemented"); break; |
|
|
|
case BXOR: assert(!"unimplemented"); break; |
|
|
|
case BOR: assert(!"unimplemented"); break; |
|
|
@ -2969,7 +2982,7 @@ oop typeCheck(oop exp, oop fntype) |
|
|
|
oop parameters = get(exp, Function,parameters); |
|
|
|
oop body = get(exp, Function,body ); |
|
|
|
oop ptypes = newArray(); |
|
|
|
if (t_etc == Array_last(parameters)) { |
|
|
|
if (Array_size(parameters) && t_etc == Array_last(parameters)) { |
|
|
|
Array_popLast(parameters); |
|
|
|
set(exp, Function,variadic, 1); |
|
|
|
} |
|
|
@ -3022,8 +3035,8 @@ oop typeCheck(oop exp, oop fntype) |
|
|
|
oop arg = argv[i]; |
|
|
|
oop argt = typeCheck(arg, fntype); |
|
|
|
if (argt != part) |
|
|
|
fatal("cannot pass argument of type '%s' to parameter of type '%s' ", |
|
|
|
toString(argt), toString(part)); |
|
|
|
fatal("cannot pass argument of type '%s' to parameter of type '%s': %s ", |
|
|
|
toString(argt), toString(part), toString(exp)); |
|
|
|
} |
|
|
|
return get(tfunc, Tfunction,result); |
|
|
|
} |
|
|
|