summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main.c5
-rw-r--r--parse.c56
-rw-r--r--test.toc20
3 files changed, 58 insertions, 23 deletions
diff --git a/main.c b/main.c
index ee98903..8561f26 100644
--- a/main.c
+++ b/main.c
@@ -18,7 +18,10 @@
/*
TODO:
+<<<<<<< HEAD
+=======
no foreign parameter declarations
+>>>>>>> 3fa3c17a12cb52edbcc9890cad59d610e0360f90
see NOTE in test.toc
variadic fns
#include
@@ -86,7 +89,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..54a6bc5 100644
--- a/parse.c
+++ b/parse.c
@@ -298,12 +298,12 @@ static inline Expression *parser_new_expr(Parser *p) {
}
typedef enum {
- EXPR_CAN_END_WITH_COMMA = 0x01, /* a comma could end the expression */
- EXPR_CAN_END_WITH_LBRACE = 0x02,
- EXPR_CAN_END_WITH_COLON = 0x04,
- EXPR_CAN_END_WITH_DOTDOT = 0x08,
- EXPR_CAN_END_WITH_EQ = 0x10,
- /* note that parse_type uses -1 for this */
+ EXPR_CAN_END_WITH_COMMA = 0x01, /* a comma could end the expression */
+ EXPR_CAN_END_WITH_LBRACE = 0x02,
+ EXPR_CAN_END_WITH_COLON = 0x04,
+ EXPR_CAN_END_WITH_DOTDOT = 0x08,
+ EXPR_CAN_END_WITH_EQ = 0x10,
+ /* note that parse_type uses -1 for this */
} ExprEndFlags;
static Token *expr_find_end(Parser *p, ExprEndFlags flags) {
@@ -589,6 +589,11 @@ 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;
@@ -612,13 +617,13 @@ static bool parse_type(Parser *p, Type *type) {
break;
default:
type_expr: {
- /* TYPE_EXPR */
- Token *end = expr_find_end(p, (ExprEndFlags)-1 /* end as soon as possible */);
- if (parse_expr(p, type->expr = parser_new_expr(p), end)) {
- type->kind = TYPE_EXPR;
- } else {
- return false;
- }
+ /* TYPE_EXPR */
+ Token *end = expr_find_end(p, (ExprEndFlags)-1 /* end as soon as possible */);
+ if (parse_expr(p, type->expr = parser_new_expr(p), end)) {
+ type->kind = TYPE_EXPR;
+ } else {
+ return false;
+ }
} break;
}
type->where.end = t->token;
@@ -627,9 +632,9 @@ static bool parse_type(Parser *p, Type *type) {
}
/*
-is the thing we're looking at definitely a type, as opposed to an expression?
-if end is not NULL, it is set to the token one past the last one in the type,
-assuming it's successful
+ is the thing we're looking at definitely a type, as opposed to an expression?
+ if end is not NULL, it is set to the token one past the last one in the type,
+ assuming it's successful
*/
static bool parser_is_definitely_type(Parser *p, Token **end) {
Tokenizer *t = p->tokr;
@@ -815,8 +820,8 @@ static bool parse_decl_list(Parser *p, Declaration **decls, DeclEndKind decl_end
*decls = NULL;
while (t->token->kind != TOKEN_EOF &&
(first || (
- !token_is_kw(t->token - 1, KW_RPAREN) &&
- !token_is_kw(t->token - 1, KW_LBRACE)))) {
+ !token_is_kw(t->token - 1, KW_RPAREN) &&
+ !token_is_kw(t->token - 1, KW_LBRACE)))) {
first = false;
Declaration *decl = parser_arr_add(p, decls);
if (!parse_decl(p, decl, decl_end, PARSE_DECL_ALLOW_CONST_WITH_NO_EXPR | PARSE_DECL_ALLOW_SEMI_CONST | PARSE_DECL_ALLOW_INFER)) {
@@ -853,6 +858,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 +884,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;
}
}
@@ -1322,7 +1337,6 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) {
&& op_precedence(lowest_precedence_op[-1].kw) != NOT_AN_OP) {
--lowest_precedence_op;
}
-
if (lowest_precedence_op == t->token) {
/* Unary */
UnaryOp op;
@@ -1397,7 +1411,7 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) {
++t->token;
Expression *of = parser_new_expr(p);
e->unary.of = of;
- if (!parse_expr(p, of, end))
+ if (!parse_expr(p, of, end))
return false;
goto success;
}
diff --git a/test.toc b/test.toc
index d4f021a..0d1e239 100644
--- a/test.toc
+++ b/test.toc
@@ -3,6 +3,23 @@
// io.puts("Hello, world!");
// };
+<<<<<<< HEAD
+foo ::= fn(bar :: int = #foreign "X") {
+
+};
+
+stdout :: &u8 = #foreign "stdout";
+fwrite :: fn(&u8, u64, u64, &u8) = #foreign "fwrite";
+
+puts ::= fn(x : []char) {
+// NOTE: removing brackets here causes error! this shouldn't happen!
+ fwrite((&x[0]) as (&u8), 1, x.len as u64, stdout);
+};
+
+main ::= fn() {
+ puts("Hello, world!\n");
+};
+=======
stdout :: &u8 = #foreign "stdout";
fwrite :: fn(&u8, u64, u64, &u8) = #foreign "fwrite";
@@ -13,4 +30,5 @@ puts ::= fn(x : []char) {
main ::= fn() {
puts("Hello, world!\n");
-}; \ No newline at end of file
+};
+>>>>>>> 3fa3c17a12cb52edbcc9890cad59d610e0360f90