summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main.c3
-rw-r--r--parse.c18
-rw-r--r--test.toc6
3 files changed, 22 insertions, 5 deletions
diff --git a/main.c b/main.c
index ee98903..5f69aa7 100644
--- a/main.c
+++ b/main.c
@@ -18,7 +18,6 @@
/*
TODO:
-no foreign parameter declarations
see NOTE in test.toc
variadic fns
#include
@@ -86,7 +85,7 @@ int main(int argc, char **argv) {
}
++contents;
if (ferror(in)) {
- fprintf(stderr, "Error reading input file: %s.\n", argv[1]);
+ fprintf(stderr, "Error reading input file: %s.\n", in_filename);
return EXIT_FAILURE;
}
fclose(in);
diff --git a/parse.c b/parse.c
index 89c5e74..c93d5cc 100644
--- a/parse.c
+++ b/parse.c
@@ -589,6 +589,10 @@ static bool parse_type(Parser *p, Type *type) {
err_print(field_decl.where, "Constant struct members are not supported (yet).");
return false;
}
+ if ((field_decl.flags & DECL_FOREIGN) && !(field_decl.flags & DECL_IS_CONST)) {
+ err_print(field_decl.where, "Non-constant struct members cannot be foreign.");
+ return false;
+ }
if (field_decl.flags & DECL_HAS_EXPR) {
err_print(field_decl.where, "struct members cannot have initializers.");
return false;
@@ -807,7 +811,7 @@ static bool parse_block(Parser *p, Block *b) {
return ret;
}
-/* does NOT handle empty declaration lists */
+/* does NOT handle empty declaration list. */
static bool parse_decl_list(Parser *p, Declaration **decls, DeclEndKind decl_end) {
Tokenizer *t = p->tokr;
bool ret = true;
@@ -853,6 +857,12 @@ static bool parse_fn_expr(Parser *p, FnExpr *f) {
} else {
if (!parse_decl_list(p, &f->params, DECL_END_RPAREN_COMMA))
return false;
+ arr_foreach(f->params, Declaration, param) {
+ if (param->flags & DECL_FOREIGN) {
+ err_print(param->where, "Parameters cannot be foreign.");
+ return false;
+ }
+ }
}
if (t->token->kind == TOKEN_EOF) {
@@ -873,7 +883,11 @@ static bool parse_fn_expr(Parser *p, FnExpr *f) {
return false;
}
if (d->flags & DECL_INFER) {
- err_print(d->where, "Can't infer the value of a return declaration!");
+ err_print(d->where, "Can't infer the value of a named return value!");
+ return false;
+ }
+ if (d->flags & DECL_FOREIGN) {
+ err_print(d->where, "Named return values can't be foreign.");
return false;
}
}
diff --git a/test.toc b/test.toc
index d4f021a..b6ebe53 100644
--- a/test.toc
+++ b/test.toc
@@ -3,6 +3,10 @@
// io.puts("Hello, world!");
// };
+foo ::= fn(bar :: int = #foreign "X") {
+
+};
+
stdout :: &u8 = #foreign "stdout";
fwrite :: fn(&u8, u64, u64, &u8) = #foreign "fwrite";
@@ -13,4 +17,4 @@ puts ::= fn(x : []char) {
main ::= fn() {
puts("Hello, world!\n");
-}; \ No newline at end of file
+};