|
|
@ -1,6 +1,6 @@ |
|
|
|
# main.leg -- C parser + interpreter |
|
|
|
# |
|
|
|
# Last edited: 2025-02-01 08:55:52 by piumarta on xubuntu |
|
|
|
# Last edited: 2025-02-01 10:02:43 by piumarta on xubuntu |
|
|
|
|
|
|
|
%{ |
|
|
|
; |
|
|
@ -1068,13 +1068,13 @@ oop toStringOn(oop obj, oop str) |
|
|
|
oop base = get(obj, Pointer,base); |
|
|
|
switch (getType(base)) { |
|
|
|
case Integer: |
|
|
|
String_format(str, "<%p", (void *)(intptr_t)_integerValue(base)); |
|
|
|
String_format(str, "<%s %p", toString(get(obj, Pointer,type)), (void *)(intptr_t)_integerValue(base)); |
|
|
|
break; |
|
|
|
case Variable: |
|
|
|
String_format(str, "<&%s", symbolName(get(base, Variable,name))); |
|
|
|
String_format(str, "<%s &%s", toString(get(obj, Pointer,type)), symbolName(get(base, Variable,name))); |
|
|
|
break; |
|
|
|
case Memory: |
|
|
|
String_format(str, "<%p[%d]", get(base, Memory,base), get(base, Memory,size)); |
|
|
|
String_format(str, "<%s %p[%d]", toString(get(obj, Pointer,type)), get(base, Memory,base), get(base, Memory,size)); |
|
|
|
break; |
|
|
|
default: |
|
|
|
fatal("cannot convert pointer base %s to string", toString(base)); |
|
|
@ -2254,6 +2254,25 @@ int toBoolean(oop arg) |
|
|
|
#define isTrue(O) ( toBoolean(O)) |
|
|
|
#define isFalse(O) (!toBoolean(O)) |
|
|
|
|
|
|
|
int isNull(oop p) |
|
|
|
{ |
|
|
|
switch (getType(p)) { |
|
|
|
case Integer: return 0 == _integerValue(p); |
|
|
|
case Pointer: { |
|
|
|
if (t_pvoid != get(p, Pointer,type)) return 0; |
|
|
|
oop base = get(p, Pointer,base); |
|
|
|
switch (getType(base)) { |
|
|
|
case Integer: return 0 == _integerValue(base); |
|
|
|
case Memory: return 0 == get(base, Memory,base); |
|
|
|
default: break; |
|
|
|
} |
|
|
|
break; |
|
|
|
} |
|
|
|
default: break; |
|
|
|
} |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
oop pointerType(oop arg) |
|
|
|
{ |
|
|
|
switch (getType(arg)) { |
|
|
@ -3242,6 +3261,8 @@ oop assign(oop lhs, oop rhs) |
|
|
|
case Tdouble: return newFloat (*(double *)addr = _floatValue(rhs)); |
|
|
|
default: break; |
|
|
|
} |
|
|
|
printf("ASSIGN "); println(lhs); |
|
|
|
printf("FROM "); println(rhs); |
|
|
|
fatal("cannot store '%s' through pointer", getTypeName(type)); |
|
|
|
} |
|
|
|
default: break; |
|
|
@ -3338,6 +3359,15 @@ void randomise(unsigned char *mem, size_t size) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
oop castPointer(oop pointer, oop type) |
|
|
|
{ |
|
|
|
oop target = get(type, Tpointer,target); |
|
|
|
int tscale = typeSize(target); |
|
|
|
int pscale = typeSize(get(get(pointer, Pointer,type), Tpointer,target)); |
|
|
|
int offset = get(pointer, Pointer,offset) * pscale / tscale; |
|
|
|
return newPointer(type, get(pointer, Pointer,base), offset); |
|
|
|
} |
|
|
|
|
|
|
|
void initialiseVariable(oop var, int local) |
|
|
|
{ |
|
|
|
oop (*evaluate)(oop) = local ? eval : preval; |
|
|
@ -3395,6 +3425,35 @@ void initialiseVariable(oop var, int local) |
|
|
|
set(var, Variable,value, value); |
|
|
|
break; |
|
|
|
} |
|
|
|
case Tpointer: { |
|
|
|
oop value = isNil(init) ? nil : evaluate(init); |
|
|
|
switch (getType(value)) { |
|
|
|
case Undefined: { |
|
|
|
set(var, Variable,value, nil); |
|
|
|
break; |
|
|
|
} |
|
|
|
case Integer: { |
|
|
|
if (_integerValue(value)) fatal("storing non-zero integer into pointer"); |
|
|
|
value = newPointer(type, value, 0); |
|
|
|
set(var, Variable,value, value); |
|
|
|
break; |
|
|
|
} |
|
|
|
case Pointer: { |
|
|
|
oop vtype = get(value, Pointer,type); |
|
|
|
if (type != vtype) { |
|
|
|
if (vtype != t_pvoid || !isNull(value)) |
|
|
|
fatal("cannot convert non-NULL pointer '%s' to '%s'", toString(vtype), toString(type)); |
|
|
|
value = castPointer(value, type); |
|
|
|
} |
|
|
|
set(var, Variable,value, castPointer(value, type)); |
|
|
|
break; |
|
|
|
} |
|
|
|
default: |
|
|
|
println(value); |
|
|
|
fatal("cannot initialise pointer with %s", getTypeName(value)); |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
default: { |
|
|
|
if (!isNil(init)) set(var, Variable,value, evaluate(init)); |
|
|
|
break; |
|
|
@ -3420,9 +3479,12 @@ oop eval(oop exp) |
|
|
|
case Symbol: { |
|
|
|
oop value = Scope_lookup(exp); |
|
|
|
if (!value) fatal("'%s' is undefined\n", get(exp, Symbol,name)); |
|
|
|
if (isNil(value)) fatal("'%s' is uninitialised\n", get(exp, Symbol,name)); |
|
|
|
switch (getType(value)) { |
|
|
|
case Variable: RETURN(get(value, Variable,value)); |
|
|
|
case Variable: { |
|
|
|
value = get(value, Variable,value); |
|
|
|
if (isNil(value)) fatal("use of uninitialised variable '%s'", get(exp, Symbol,name)); |
|
|
|
RETURN(value); |
|
|
|
} |
|
|
|
case Function: RETURN(value); |
|
|
|
case Primitive: RETURN(value); |
|
|
|
default: fatal("cannot eval: %s", toString(value)); |
|
|
@ -3691,13 +3753,7 @@ oop eval(oop exp) |
|
|
|
rhs = cvt(rhs); |
|
|
|
switch (getType(type)) { |
|
|
|
case Tpointer: { |
|
|
|
if (is(Pointer,rhs)) { |
|
|
|
int offset = get(rhs, Pointer,offset); |
|
|
|
int rscale = typeSize(get(get(rhs, Pointer,type), Tpointer,target)); |
|
|
|
int lscale = typeSize(get(type, Tpointer,target)); |
|
|
|
offset = offset * lscale / rscale; |
|
|
|
RETURN(newPointer(type, get(rhs, Pointer,base), get(rhs, Pointer,offset))); |
|
|
|
} |
|
|
|
if (is(Pointer,rhs)) RETURN(castPointer(rhs, type)); |
|
|
|
} |
|
|
|
} |
|
|
|
RETURN(cvt(rhs)); |
|
|
|