|
@ -1,6 +1,6 @@ |
|
|
# main.leg -- C parser + interpreter |
|
|
# main.leg -- C parser + interpreter |
|
|
# |
|
|
# |
|
|
# Last edited: 2025-02-05 13:53:41 by piumarta on xubuntu |
|
|
|
|
|
|
|
|
# Last edited: 2025-03-21 11:45:50 by piumarta on m1mbp.local |
|
|
|
|
|
|
|
|
%{ |
|
|
%{ |
|
|
; |
|
|
; |
|
@ -2262,20 +2262,6 @@ cvt_t converter(int tfrom, int tto) |
|
|
return converters[tto - Tvoid][tfrom - Tvoid]; |
|
|
return converters[tto - Tvoid][tfrom - Tvoid]; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
oop incr(oop val, int amount) |
|
|
|
|
|
{ |
|
|
|
|
|
switch (getType(val)) { |
|
|
|
|
|
case Integer: return newInteger(integerValue(val) + amount); |
|
|
|
|
|
case Float: return newFloat ( floatValue(val) + amount); |
|
|
|
|
|
case Pointer: return newPointer(get(val, Pointer,type), |
|
|
|
|
|
get(val, Pointer,base), |
|
|
|
|
|
get(val, Pointer,offset) + amount); |
|
|
|
|
|
default: |
|
|
|
|
|
fatal("cannot increment: %s", toString(val)); |
|
|
|
|
|
} |
|
|
|
|
|
return nil; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int isType(oop obj) |
|
|
int isType(oop obj) |
|
|
{ |
|
|
{ |
|
|
type_t type = getType(obj); |
|
|
type_t type = getType(obj); |
|
@ -2315,6 +2301,38 @@ int typeSize(oop type) |
|
|
return 0; |
|
|
return 0; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
oop incr(oop val, int amount) |
|
|
|
|
|
{ |
|
|
|
|
|
switch (getType(val)) { |
|
|
|
|
|
case Integer: return newInteger(integerValue(val) + amount); |
|
|
|
|
|
case Float: return newFloat ( floatValue(val) + amount); |
|
|
|
|
|
case Pointer: { |
|
|
|
|
|
oop t = get(val, Pointer,type); |
|
|
|
|
|
oop b = get(val, Pointer,base); |
|
|
|
|
|
int o = get(val, Pointer,offset) + amount; |
|
|
|
|
|
oop p = newPointer(t, b, o); |
|
|
|
|
|
switch (getType(b)) { |
|
|
|
|
|
case Variable: |
|
|
|
|
|
if (o < -1 || o > 1) fatal("pointer modified beyond base object: %s", toString(p)); |
|
|
|
|
|
break; |
|
|
|
|
|
case Memory: { |
|
|
|
|
|
int limit = get(b, Memory,size) / typeSize(get(t, Tpointer,target)); |
|
|
|
|
|
if (o < -1 || o > limit) fatal("pointer modified beyond base object: %s", toString(p)); |
|
|
|
|
|
break; |
|
|
|
|
|
} |
|
|
|
|
|
default: |
|
|
|
|
|
println(b); |
|
|
|
|
|
assert(!"unimplemented"); |
|
|
|
|
|
break; |
|
|
|
|
|
} |
|
|
|
|
|
return p; |
|
|
|
|
|
} |
|
|
|
|
|
default: |
|
|
|
|
|
fatal("cannot increment: %s", toString(val)); |
|
|
|
|
|
} |
|
|
|
|
|
return nil; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
int toBoolean(oop arg) |
|
|
int toBoolean(oop arg) |
|
|
{ |
|
|
{ |
|
|
switch (getType(arg)) { |
|
|
switch (getType(arg)) { |
|
@ -3459,7 +3477,11 @@ int compare(oop a, oop b) |
|
|
case Float: return CMP( _floatValue(a), _floatValue(b)); |
|
|
case Float: return CMP( _floatValue(a), _floatValue(b)); |
|
|
case Pointer: { |
|
|
case Pointer: { |
|
|
oop ba = get(a, Pointer,base), bb = get(b, Pointer,base); |
|
|
oop ba = get(a, Pointer,base), bb = get(b, Pointer,base); |
|
|
if (ba != bb) return CMP((intptr_t)ba, (intptr_t)bb); |
|
|
|
|
|
|
|
|
// BUG -- this should report an illegal comparison |
|
|
|
|
|
if (ba != bb) { |
|
|
|
|
|
fatal("illegal comparison between pointers to different objects: %s and %s\n", toString(a), toString(b)); |
|
|
|
|
|
return CMP((intptr_t)ba, (intptr_t)bb); |
|
|
|
|
|
} |
|
|
int oa = get(a, Pointer,offset), ob = get(b, Pointer,offset); |
|
|
int oa = get(a, Pointer,offset), ob = get(b, Pointer,offset); |
|
|
return CMP(oa, ob); |
|
|
return CMP(oa, ob); |
|
|
} |
|
|
} |
|
|