Skip to content

Commit

Permalink
Merge pull request #1289 from andrew-johnson-4/ansi-c-frontend-rqer
Browse files Browse the repository at this point in the history
Ansi c frontend rqer
  • Loading branch information
andrew-johnson-4 authored Feb 24, 2025
2 parents 95202c3 + 7f4a3ca commit 7ed2b1a
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 11 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
CC = cc

dev: install-production
lm tests/regress/numerical-pyramid.lsts
lm tests/c/main.c
$(CC) -O3 tmp.c
./a.out
#lm tests/c/main.c
Expand Down
83 changes: 83 additions & 0 deletions PLUGINS/FRONTEND/C/c-ast-to-lm-ast.lsts
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@

let std-c-declare(t: CTerm): Nil = (
match t {
CFunctionDefinition{spec=specifiers,decl=declarator,dl=declaration-list,stmt=statement} => std-c-declare-function(spec, decl, dl, stmt);
_ => fail("Unsupported C Declaration:\n\{t}\n");
};
);

let std-c-declare-function(specifiers: CTerm, declarator: CTerm, declaration-list: CTerm, statement: CTerm): Nil = (
(let return-type, let misc-types) = std-c-type-of-specifiers(specifiers);
(let name, let pointer) = std-c-name-of-declarator(declarator);
let params = std-c-lhs-of-parameter-list(declaration-list);
let body = std-c-expr-of-statement(statement);
print("Name: \{name}\n");
print("Return Type: \{return-type}\n");
print("Misc Type: \{misc-types}\n");
exit(1);
);

let std-c-type-of-specifiers(specifiers: CTerm): Tuple<Type,Type> = (
let misc = TAny;
let rtype = match specifiers {
CList{value:[CType1{rv=value}..]} => t2(c"C", t1(untern(rv)));
_ => fail("Unsupported C Specifiers:\n\{specifiers}\n");
};
(rtype, misc);
);

let std-c-name-of-declarator(declarator: CTerm): Tuple<String,Type> = (
match declarator {
CUnaryPrefix{op:"Declarator(", arg:CIdentifier{name=value}} => (name, TAny);
_ => fail("Unsupported C Declarator:\n\{declarator}\n");
};
);

let std-c-lhs-of-parameter-list(declaration-list: CTerm): AST = (
match declaration-list {
CMaybe{value:None{}} => ASTNil;
_ => fail("Unsupported C Parameter List:\n\{declaration-list}\n");
};
);

let std-c-expr-of-statement(t: CTerm): AST = (
match t {
CCompound{terms=terms} => (
let inner = ASTNil;
for it in terms {
inner = App{ true, close(inner), close(std-c-expr-of-statement(it)) };
};
App{ false, close(Var{c"c::compound", mk-token(c"c::compound")}), close(inner) }
);
CUnaryPrefix{op:"return", arg=arg} => (
let inner = std-c-expr-of-statement(arg);
App{ false, close(Var{c"c::return", mk-token(c"c::return")}), close(inner) }
);
CInteger{value=value} => (
App{ false,
close(Var{c":", mk-token(c":")}),
close(App{
close(Lit{ untern(value), mk-token(value) }),
close(AType{ std-c-type-of-integer(value) })
})
}
);
_ => fail("Unsupported C Statement:\n\{t}\n");
};
);

let std-c-type-of-integer(i: String): Type = (
if i.has-prefix("-") {
let n = to-u64(untern(tail-string(i)));
if n <= 128 then t2(c"C",t1(c"uint8_t")) else
if n <= 32768 then t2(c"C",t1(c"uint16_t")) else
if n <= 2147483648 then t2(c"C",t1(c"uint32_t")) else
t2(c"C",t1(c"uint64_t"))
} else {
let n = to-u64(untern(i));
if n <= 255 then t2(c"C",t1(c"int8_t")) else
if n <= 65535 then t2(c"C",t1(c"int16_t")) else
if n <= 4294967295 then t2(c"C",t1(c"int32_t")) else
t2(c"C",t1(c"int64_t"))
};
);
5 changes: 1 addition & 4 deletions PLUGINS/FRONTEND/C/c-frontend.lsts
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@

let c-frontend(fp: CString): Nil = (
let tokens = std-c-tokenize-string(fp, read-file(fp));
for t in tokens {
print("token: \{t.key}\n");
};
print("TODO: parse \{fp}\n"); exit(1);
std-c-parse(tokens);
);

register-frontend(c".c", c-frontend);
20 changes: 14 additions & 6 deletions PLUGINS/FRONTEND/C/c-parse.lsts
Original file line number Diff line number Diff line change
Expand Up @@ -63,15 +63,23 @@ let to-smart-string(l: CTerm): String = (
CCharacter{rv=value} => "{Character \{rv}}";
CFloating{rv=value} => "{Floating \{rv}}";
CEnumeration{rv=value} => "{Enumeration \{rv}}";
CMaybe{rv=value} => "{Maybe \{rv}}";
CList{rv=value} => "{List \{rv}}";
CString{rv=value} => "{String \{rv}}";
CIdentifier{rv=value} => "{Identifier \{rv}}";
CType1{rv=value} => "{Type \{rv}}";
CList{rv=value} => "{List \{rv}}";
CIList{rv=value} => "{IList \{rv}}";
CMaybe{rv=value} => "{Maybe \{rv}}";
CZOp{op=op} => "{ZOp \{op}}";
CIdentifier{rv=value} => "{Identifier \{rv}}";
CUnaryPrefix{rop=op,rarg=arg} => "{Prefix \{rop} \{rarg}}";
CCompound{rv=terms} => "{Compound \{rv}}";
CPointer{q=qualifiers,n=next} => "{Pointer \{q} \{n}}";
CInitializer{q=designator,n=initializer} => "{Initializer \{q} \{n}}";
CInitializerList{q=terms} => "{InitializerList \{q}}";
CUnaryPostfix{rop=op,rarg=arg} => "{Postfix \{rop} \{rarg}}";
CUnaryPrefix{rop=op,rarg=arg} => "{Prefix \{rop} \{rarg}}";
CBinaryOp{op=op,arg1=arg1,arg2=arg2} => "{BinaryOp \{op} \{arg1} \{arg2}}";
CTernaryOp{op=op,arg1=arg1,arg2=arg2,arg3=arg3} => "{TernaryOp \{op} \{arg1} \{arg2} \{arg3}}";
CFor{op=op,arg1=arg1,arg2=arg2,arg3=arg3,stmt=stmt} => "{For \{op} \{arg1} \{arg2} \{arg3} \{stmt}}";
CFunctionDefinition{spec=specifiers,decl=declarator,dl=declaration-list,stmt=statement} => "{Function\n\t\{spec}\n\t\{decl}\n\t\{dl}\n\t\{stmt}\n}";
CAccessor{racc=accessor,rf=field,rarg=arg} => "{Accessor \{racc} \{rf} \{rarg}}";
}
);
Expand Down Expand Up @@ -162,9 +170,9 @@ let std-c-take-maybe(tokens: List<Token>, cls: String): List<Token> = (

let std-c-parse-external-declaration(tokens: List<Token>): List<Token> = (
let fd = std-c-parse-function-definition(tokens); tokens = fd.second;
if fd.first.is-some { print("TODO: declare function \{fd.first.get-or-panic}\n"); };
if fd.first.is-some { std-c-declare(fd.first.get-or-panic); };
let d = std-c-parse-declaration(tokens); tokens = d.second;
if d.first.is-some { print("TODO: declare \{d.first.get-or-panic}\n"); };
if d.first.is-some { std-c-declare(d.first.get-or-panic); };
tokens;
);

Expand Down
1 change: 1 addition & 0 deletions PLUGINS/FRONTEND/C/index-index.lm
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ import PLUGINS/FRONTEND/C/c-parse.lsts;
import PLUGINS/FRONTEND/C/c-tokenize.lsts;
import PLUGINS/FRONTEND/C/c-frontend.lsts;
import PLUGINS/FRONTEND/C/c-smart-tokenize.lsts;
import PLUGINS/FRONTEND/C/c-ast-to-lm-ast.lsts;

0 comments on commit 7ed2b1a

Please sign in to comment.