Pārlūkot izejas kodu

handle command-line arguments properly

master
Ian Piumarta pirms 3 mēnešiem
vecāks
revīzija
07634df3dc
2 mainītis faili ar 110 papildinājumiem un 59 dzēšanām
  1. +11
    -4
      Makefile
  2. +99
    -55
      main.leg

+ 11
- 4
Makefile Parādīt failu

@ -1,7 +1,8 @@
CFLAGS = -std=c99 -Werror -Wall -Wno-unused -g
CFLAGS = -std=c99 -Werror -Wall -Wno-unused -g
OFLAGS = -std=c99 -Werror -Wall -Wno-unused -DNDEBUG -O2
CPPFLAGS = -I/opt/local/include
LDFLAGS = -L/opt/local/lib
LDLIBS = -lgc -lm
LDFLAGS = -L/opt/local/lib
LDLIBS = -lgc -lm
all : main
@ -11,6 +12,9 @@ all : main
% : %.c
$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -o $@ $< $(LDLIBS)
opt : main.c
$(CC) $(OFLAGS) $(CPPFLAGS) $(LDFLAGS) -o $@ $< $(LDLIBS)
test : main
./main -vv test.txt
@ -20,10 +24,13 @@ demo : main
demov : main
for i in demofiles/*.c; do echo $$i; ./main -vv $$i; done
bench : opt
time ./opt bench.c 28
spotless : clean
rm -rf *~ *.dSYM
clean : .FORCE
rm -f main
rm -f main opt
.FORCE :

+ 99
- 55
main.leg Parādīt failu

@ -1,6 +1,6 @@
# main.leg -- C parser + interpreter
#
# Last edited: 2025-02-04 09:10:32 by piumarta on xubuntu
# Last edited: 2025-02-05 12:43:42 by piumarta on m1mbp
%{
;
@ -1832,12 +1832,12 @@ ddector = ( LPAREN d:decltor RPAREN
)* { $$ = d }
params = LPAREN a:mkList
( p:pdecl { List_append(a, p) }
( COMMA p:pdecl { List_append(a, p) }
)* )? ( ( COMMA ETC { List_append(a, t_etc) }
)? RPAREN { $$ = a }
| e:error { expected(e, "parameter declaration") }
)
( p:pdecl { List_append(a, p) }
( COMMA p:pdecl { List_append(a, p) }
)* )? ( ( COMMA ETC { List_append(a, t_etc) }
)? RPAREN { $$ = a }
| e:error { expected(e, "parameter declaration") }
)
pdecl = t:tname d:decltor { $$ = newVariable(d, t, nil) }
@ -2699,7 +2699,22 @@ oop typeCheck(oop exp, oop fntype)
toString(lhs), toString(rhs));
break;
}
case SUB: assert(!"unimplemented"); break;
case SUB: {
if (lhs == rhs) {
if (t_int == lhs) return lhs;
if (t_float == lhs) return lhs;
}
if (is(Tpointer, lhs) && t_int == rhs) {
return lhs;
}
if (is(Tpointer, lhs) && is(Tpointer, rhs)) {
return t_long;
}
fatal("%scannot subtract '%s' and '%s'",
tokloc(get(exp, Binary,token)),
toString(lhs), toString(rhs));
break;
}
case SHL: assert(!"unimplemented"); break;
case SHR: assert(!"unimplemented"); break;
case LT: return t_int;
@ -2723,7 +2738,7 @@ oop typeCheck(oop exp, oop fntype)
fatal("%sarray index is not 'int': %s",
tokloc(get(exp, Index,token)), toString(get(exp, Index,rhs)));
switch (getType(lhs)) {
case Tpointer: assert(!"unimplemented");
case Tpointer: return get(lhs, Tpointer,target);
case Tarray: return get(lhs, Tarray,target);
default: fatal("'%s' is not indexable: %s", toString(lhs), toString(exp));
}
@ -3123,30 +3138,6 @@ oop getPointer(oop ptr)
return 0;
}
oop getArray(oop array, int index)
{
int size = get(array, Array,size);
if (index < 0) fatal("array index is negative");
if (index >= size) fatal("array index out of bounds");
oop base = get(array, Array,base);
oop type = get(get(array, Array,type), Tarray,target);
int scale = typeSize(type);
assert(is(Memory, base));
void *addr = get(base, Memory,base) + index * scale;
assert(addr < get(base, Memory,base) + get(base, Memory,size));
switch (getType(type)) {
case Tchar: return newInteger(*(char *)addr);
case Tshort: return newInteger(*(short *)addr);
case Tint: return newInteger(*(int *)addr);
case Tlong: return newInteger(*(long *)addr);
case Tfloat: return newFloat (*(float *)addr);
case Tdouble: return newFloat (*(double *)addr);
default: break;
}
fatal("cannot load '%s' from array", getTypeName(type));
return 0;
}
oop getMemory(oop memory, int offset, oop type)
{
int memsize = get(memory, Memory,size);
@ -3166,6 +3157,7 @@ oop getMemory(oop memory, int offset, oop type)
oop target = get(type, Tpointer,target);
switch (getType(target)) {
case Tstruct: return newPointer(type, newMemory(value, typeSize(target)), 0);
case Tchar: return newPointer(t_pchar, newMemory(value, strlen(value)+1), 0);
default: break;
}
fatal("cannot load pointer to '%s' from memory", getTypeName(target));
@ -3220,7 +3212,7 @@ oop setMemory(oop memory, int offset, oop type, oop value)
return 0;
}
oop setArray(oop array, int index, oop value)
oop getArray(oop array, int index)
{
int size = get(array, Array,size);
if (index < 0) fatal("array index is negative");
@ -3231,6 +3223,36 @@ oop setArray(oop array, int index, oop value)
assert(is(Memory, base));
void *addr = get(base, Memory,base) + index * scale;
assert(addr < get(base, Memory,base) + get(base, Memory,size));
switch (getType(type)) {
case Tchar: return newInteger(*(char *)addr);
case Tshort: return newInteger(*(short *)addr);
case Tint: return newInteger(*(int *)addr);
case Tlong: return newInteger(*(long *)addr);
case Tfloat: return newFloat (*(float *)addr);
case Tdouble: return newFloat (*(double *)addr);
case Tpointer: return getMemory(base, scale * index, type);
default: break;
}
fatal("cannot load '%s' from array", getTypeName(type));
return 0;
}
oop setArray(oop array, int index, oop value)
{
int size = get(array, Array,size);
if (index < 0) fatal("array index is negative");
if (index >= size) fatal("array index out of bounds");
oop base = get(array, Array,base);
oop type = get(array, Array,type);
switch (getType(type)) {
case Tarray: type = get(type, Tarray,target); break;
case Tpointer: type = get(type, Tpointer,target); break;
default: assert(0);
}
int scale = typeSize(type);
assert(is(Memory, base));
void *addr = get(base, Memory,base) + index * scale;
assert(addr < get(base, Memory,base) + get(base, Memory,size));
switch (getType(type)) {
case Tchar: return newInteger(*(char *)addr = _integerValue(value));
case Tshort: return newInteger(*(short *)addr = _integerValue(value));
@ -3238,6 +3260,10 @@ oop setArray(oop array, int index, oop value)
case Tlong: return newInteger(*(long *)addr = _integerValue(value));
case Tfloat: return newFloat (*(float *)addr = _floatValue(value));
case Tdouble: return newFloat (*(double *)addr = _floatValue(value));
case Tpointer: {
setMemory(base, scale * index, type, value);
return value;
}
default: break;
}
fatal("cannot store '%s' into array", getTypeName(type));
@ -3806,7 +3832,8 @@ oop eval(oop exp)
int index = _integerValue(ondex);
oop lhs = eval(get(exp, Index,lhs));
switch (getType(lhs)) {
case Array: RETURN(getArray(lhs, index));
case Array: RETURN(getArray(lhs, index));
case Pointer: assert(0);
default: break;
}
println(lhs);
@ -4710,35 +4737,52 @@ int main(int argc, char **argv)
Scope_begin(); // the global scope
int repls = 0;
for (int argn = 1; argn < argc;) {
char *arg = argv[argn++];
if (*arg != '-') {
replPath(arg);
++repls;
}
else {
while (*++arg) {
switch (*arg) {
case 'O': ++opt_O; continue;
case 'v': ++opt_v; continue;
case 'x': ++opt_x; continue;
default: fatal("uknown option '%c'", *arg);
}
int argn = 1;
while (argn < argc) {
char *arg = argv[argn];
if (*arg != '-') break;
++argn;
while (*++arg) {
switch (*arg) {
case 'O': ++opt_O; continue;
case 'v': ++opt_v; continue;
case 'x': ++opt_x; continue;
default: fatal("uknown option '%c'", *arg);
}
}
}
if (!repls) replFile("stdin", stdin);
oop args = newList();
if (argn == argc) fatal("no program file specified");
char *program = argv[argn++];
replPath(program);
List_append(args, newStringWith(program));
while (argn < argc)
List_append(args, newStringWith(argv[argn++]));
int cargs = List_size(args);
int vsize = sizeof(char *) * cargs;
oop vargs = newArray(newTarray(t_pchar, newInteger(cargs)),
newMemory(malloc(vsize), vsize),
cargs);
List_do(args, arg) {
char *elts = String_cString(arg);
oop mem = newMemory(elts, get(arg, String,size));
setArray(vargs, do_index, newPointer(t_pchar, mem, 0));
}
oop args = newList();
List_append(args, newInteger(1));
List_append(args, newStringWith("main"));
args = newList();
List_append(args, newInteger(cargs));
List_append(args, vargs);
List_append(args, newPointer(t_ppchar, newMemory(0, 0), 0));
oop entry = Scope_lookup(intern("main"));
if (!entry || isNil(entry)) fatal("main is not defined");
if (!is(Function, entry)) fatal("main is not a function");
oop params = get(get(entry, Function,type), Tfunction, parameters);
switch (List_size(params)) {
default:

Notiek ielāde…
Atcelt
Saglabāt