Переглянути джерело

include file name and line number in syntax error messages

master
Ian Piumarta 3 місяці тому
джерело
коміт
18caf89d77
3 змінених файлів з 121 додано та 56 видалено
  1. +11
    -8
      demofiles/pointer-compare.c
  2. +107
    -47
      main.leg
  3. +3
    -1
      test.txt

+ 11
- 8
demofiles/pointer-compare.c Переглянути файл

@ -2,14 +2,17 @@
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
int main() {
int array[5] = {0, 1, 2, 3, 4};
int brray[5] = {0, 1, 2, 3, 4};
int *p = array + 2;
int *q = array + 4;
int *r = brray + 4;
if (p > q) abort(); printf("compare OK\n");
if (p < r) abort(); printf("compare OK\n"); // illegal comparison
return 0;
int array[5] = {0, 1, 2, 3, 4};
int brray[5] = {0, 1, 2, 3, 4};
int *p = array + 2;
int *q = array + 4;
int *r = brray + 4;
if (p > q) printf("compare KO\n"); else printf("compare OK\n");
// illegal comparison
if (p < r) printf("compare KO\n"); else printf("compare KO\n");
assert(!"this should not be reached");
return 0;
}

+ 107
- 47
main.leg Переглянути файл

@ -1,6 +1,6 @@
# main.leg -- C parser + interpreter
#
# Last edited: 2025-02-01 15:04:48 by piumarta on xubuntu
# Last edited: 2025-02-03 10:47:46 by piumarta on xubuntu
%{
;
@ -60,16 +60,17 @@ typedef union Object Object, *oop;
#define YYSTYPE oop
#define _do_types(_) \
_(Undefined) _(Input) _(Integer) _(Float) _(Array) _(Symbol) _(Pair) _(String) _(List) \
_(Pointer) _(Struct) \
_(Memory) _(Reference) _(Closure) _(Call) _(Block) \
_(Addressof) _(Dereference) _(Sizeof) _(Unary) \
_(Binary) _(Index) _(Member) _(Assign) _(Cast) \
_(While) _(For) _(If) _(Return) _(Continue) _(Break) \
_(Tvoid) _(Tchar) _(Tshort) _(Tint) _(Tlong) _(Tfloat) _(Tdouble) \
_(Tpointer) _(Tarray) _(Tstruct) _(Tfunction) _(Tetc) \
_(Scope) _(TypeName) _(Variable) _(Constant) _(Function) _(Primitive) \
#define _do_types(_) \
_(Undefined) _(Input) _(Token )_(Integer) _(Float) _(Array) _(Symbol) _(Pair) \
_(String) _(List) \
_(Pointer) _(Struct) \
_(Memory) _(Reference) _(Closure) _(Call) _(Block) \
_(Addressof) _(Dereference) _(Sizeof) _(Unary) \
_(Binary) _(Index) _(Member) _(Assign) _(Cast) \
_(While) _(For) _(If) _(Return) _(Continue) _(Break) \
_(Tvoid) _(Tchar) _(Tshort) _(Tint) _(Tlong) _(Tfloat) _(Tdouble) \
_(Tpointer) _(Tarray) _(Tstruct) _(Tfunction) _(Tetc) \
_(Scope) _(TypeName) _(Variable) _(Constant) _(Function) _(Primitive) \
_(VarDecls) _(TypeDecls)
#define _do_unaries(_) \
@ -116,7 +117,8 @@ typedef oop (* prim_t)(int nargs, oop *arguments, oop environment);
typedef oop (*cvt_t)(oop input);
struct Undefined { type_t _type; };
struct Input { type_t _type; char *name; FILE *file; oop next; };
struct Input { type_t _type; char *name; int line; FILE *file; oop next; };
struct Token { type_t _type; char *text; char *file; int line; };
struct Integer { type_t _type; long value; };
struct Float { type_t _type; double value; };
struct Pointer { type_t _type; oop type, base; int offset; };
@ -138,7 +140,7 @@ 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 lhs, rhs; };
struct Assign { type_t _type; oop token, lhs, rhs; };
struct Cast { type_t _type; oop type, rhs; cvt_t converter; };
struct While { type_t _type; oop condition, expression; };
struct For { type_t _type; oop initialiser, condition, update, body; };
@ -669,7 +671,7 @@ oop newBinary(binary_t operator, oop lhs, oop rhs)
CTOR2(Index, lhs, rhs);
CTOR2(Member, lhs, name);
CTOR2(Assign, lhs, rhs);
CTOR3(Assign, token, lhs, rhs);
oop newCast(oop type, oop rhs)
{
@ -1063,6 +1065,10 @@ oop toStringOn(oop obj, oop str)
case Undefined:
String_appendAll(str, "<NIL>", 5);
break;
case Token: {
String_format(str, "%s:%d: ", get(obj, Token,file), get(obj, Token,line));
break;
}
case Integer:
String_format(str, "%d", _integerValue(obj));
break;
@ -1346,6 +1352,12 @@ char *toString(oop obj)
return get(str, String,elements);
}
char *tokloc(oop token)
{
if (Token == getType(token)) return toString(token);
return "";
}
void printiln(oop obj, int indent)
{
printf("%*s", indent*2, "");
@ -1636,19 +1648,23 @@ oop pushInput(char *name, FILE *file)
{
oop obj = new(Input);
obj->Input.name = STRDUP(name);
obj->Input.line = 1;
obj->Input.file = file;
obj->Input.next = input;
return input = obj;
input = obj;
return input;
}
void popInput(void)
{
if (!input) return;
FILE *file = get(input, Input,file);
oop obj = input;
input = get(obj, Input,next);
FREE(get(obj, Input,name));
fclose(get(obj, Input,file));
FREE(obj);
if (file) {
fclose(file);
set(obj, Input,file, 0);
}
}
FILE *sysOpen(char *path)
@ -1669,13 +1685,13 @@ FILE *usrOpen(char *path)
int getChar(char *buf)
{
while (input) {
if (input && get(input, Input,file)) {
int c = getc(get(input, Input,file));
if (c != EOF) {
*buf = c;
if ('\n' == c) get(input, Input,line) += 1;
return 1;
}
popInput();
}
return 0;
}
@ -1684,31 +1700,68 @@ int getChar(char *buf)
YYSTYPE yysval = 0;
int errorLine = 0;
void expected(oop where, char *what)
{
fatal("%s expected near: %.*s", what, get(where, String,size), get(where, String,elements));
fatal("%s:%d: %s expected near: %.*s",
get(input, Input,name), errorLine,
what, get(where, String,size), get(where, String,elements));
}
oop eval(oop exp);
oop preval(oop exp);
int lineNo = 1;
oop newToken(char *text)
{
oop obj = new(Token);
obj->Token.text = text;
assert(input);
obj->Token.file = get(input, Input,name);
obj->Token.line = lineNo;
return obj;
}
oop names = 0;
oop lines = 0;
void startInput(char *name)
{
if (!names) names = newList();
if (!lines) lines = newList();
List_append(names, newStringWith(name));
List_append(lines, newInteger(lineNo));
lineNo = 1;
}
void endInput(void)
{
if (List_size(lines)) {
lineNo = _integerValue(List_popLast(lines));
List_popLast(names);
}
}
%}
start = - ( interp { yysval = 0 }
| include { yysval = 0 }
| x:tldecl { yysval = x }
| !. { yysval = 0 }
| e:error { expected(e, "declaration") }
start = - ( interp { yysval = 0 }
| include { yysval = 0 }
| x:tldecl { yysval = x }
| !. @{ popInput() } { yysval = 0; endInput() }
| e:error { expected(e, "declaration") }
)
error = < (![\n\r] .)* > { $$ = newStringWith(yytext) }
error = @{ errorLine = get(input, Input,line) }
< (![\n\r] .)* > { $$ = newStringWith(yytext) }
interp = HASH PLING (![\n\r] .)*
interp = "#!" (!eol .)* eol
include = HASH INCLUDE (
'<' < [a-zA-Z0-9_.]* > '>' @{ pushInput(yytext, sysOpen(yytext)) }
| '"' < [a-zA-Z0-9_.]* > '"' @{ pushInput(yytext, usrOpen(yytext)) }
)
) { startInput(yytext) }
tldecl = typedec | fundefn | primdef | vardecl
@ -1742,10 +1795,10 @@ members = LBRACE l:mkList ( v:vardecl { List_append(l, v) }
| e:error { expected(e, "struct/union member specification") }
) { $$ = l }
inidecl = d:decltor ( ASSIGN ( e:initor { $$ = newAssign(d, e) }
| e:error { expected(e, "variable initialiser") }
)
| { $$ = d }
inidecl = d:decltor ( a:ASSIGN ( e:initor { $$ = newAssign(a, d, e) }
| e:error { expected(e, "variable initialiser") }
)
| { $$ = d }
)
decltor = STAR d:decltor { $$ = newTpointer(d) }
@ -1813,7 +1866,7 @@ expropt = expr | { $$ = nil }
expr = assign
assign = l:unary ASSIGN x:expr { $$ = newAssign(l, x) }
assign = l:unary a:ASSIGN x:expr { $$ = newAssign(a, l, x) }
| logor
logor = l:logand ( BARBAR r:logand { l = newBinary(LOR, l, r) }
@ -1943,9 +1996,11 @@ alpha = [a-zA-Z_]
alnum = [a-zA-Z_0-9]
- = blank*
blank = [ \t\n\r] | comment
comment = "//" < (![\n\r] .)* >
| "/*" (!"*/" .)* "*/"
blank = space | eol | comment
space = [ \t]
eol = ( '\n' '\r'? | '\r' '\n'? ) { lineNo += 1 }
comment = "//" (!eol .)* eol
| "/*" (!"*/" (eol | .))* "*/"
INCLUDE = "include" ![_a-zA-Z0-9] -
EXTERN = "extern" ![_a-zA-Z0-9] -
@ -1975,7 +2030,7 @@ DOT = "." !"." -
ARROW = "->" -
ETC = "..." -
HASH = "#" -
ASSIGN = "=" !"=" -
ASSIGN = &lt; &#34;=" !"=" > { $$ = newToken(yytext) } -
PLUS = "+" !"+" -
PPLUS = "++" -
MINUS = "-" !"-" -
@ -2240,6 +2295,7 @@ int toBoolean(oop arg)
switch (getType(arg)) {
case Integer: return !!_integerValue(arg);
case Float: return !! integerValue(arg);
case String: return 1;
case Reference: return 1;
case Pointer: {
oop base = get(arg, Pointer,base);
@ -2472,7 +2528,7 @@ oop prim_sqrtf(int argc, oop *argv, oop env) // array
{
if (argc != 1) fatal("sqrtf: wrong number of arguments");
oop arg = argv[0];
if (!is(Float, arg)) fatal("sqrtf: argument is not an integer");
if (!is(Float, arg)) fatal("sqrtf: argument is not a float");
return newFloat(sqrtf(_floatValue(arg)));
}
@ -2843,10 +2899,12 @@ oop typeCheck(oop exp, oop fntype)
oop decls = get(exp, VarDecls,variables);
oop vars = newList();
List_do(decls, decl) {
oop init = nil;
oop init = nil;
oop assign = nil;
if (is(Assign, decl)) {
init = get(decl, Assign,rhs);
decl = get(decl, Assign,lhs);
assign = get(decl, Assign,token);
init = get(decl, Assign,rhs);
decl = get(decl, Assign,lhs);
}
oop varname = makeName(decl);
oop vartype = makeType(base, decl);
@ -2943,8 +3001,10 @@ oop typeCheck(oop exp, oop fntype)
break;
cvt_t cvt = converter(getType(initype), getType(vartype));
if (!cvt) {
fatal("initialising '%s': cannot convert '%s' to '%s'",
toString(varname), toString(initype), toString(vartype));
fatal("%sinitialising '%s': cannot convert '%s' to '%s'",
tokloc(assign),
toString(varname), toString(initype), toString(vartype)
);
}
break;
}
@ -3561,8 +3621,6 @@ oop eval(oop exp)
}
default: break;
}
println(lhs);
fatal("cannot take address");
break;
}
default:
@ -4486,7 +4544,7 @@ void compileOn(oop exp, oop program, oop cs, oop bs)
return;
}
case Break: {
if (nil == bs) fatal("continue outside loop");
if (nil == bs) fatal("break outside loop");
EMITio(iPUSH, nil);
LABEL(L1);
EMITio(iJMP, nil);
@ -4585,6 +4643,8 @@ void replPath(char *path)
int main(int argc, char **argv)
{
setbuf(stdout, 0);
false = newInteger(0);
true = newInteger(1);
s_etc = newSymbol("...");

+ 3
- 1
test.txt Переглянути файл

@ -1,10 +1,10 @@
#!./main
#include <math.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <assert.h>
int x = 21;
@ -142,6 +142,8 @@ int main(int argc, char **argv)
printf("passed\n");
float f = 42;
return 0;
}

Завантаження…
Відмінити
Зберегти