diff options
-rw-r--r-- | main.c | 2 | ||||
-rw-r--r-- | parse.c | 19 | ||||
-rw-r--r-- | test.toc | 4 | ||||
-rw-r--r-- | tokenizer.c | 2 | ||||
-rw-r--r-- | types.h | 7 |
5 files changed, 24 insertions, 10 deletions
@@ -19,8 +19,8 @@ /* TODO: C functions (#foreign) -#include variadic fns +#include --- X ::= newtype(int); or something don't allow while {3; 5} (once break is added) @@ -314,8 +314,8 @@ static Token *expr_find_end(Parser *p, ExprEndFlags flags) { Token *token = t->token; bool could_be_vbs = false; /* could this be a void block statement (whose semicolons can be omitted)? e.g. {x := 5;} */ while (1) { + bool all_levels_0 = paren_level == 0 && brace_level == 0 && square_level == 0; if (token->kind == TOKEN_KW) { - bool all_levels_0 = paren_level == 0 && brace_level == 0 && square_level == 0; switch (token->kw) { case KW_COMMA: if ((flags & EXPR_CAN_END_WITH_COMMA) && all_levels_0) @@ -853,8 +853,6 @@ 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) - param->flags |= DECL_IS_PARAM; } if (t->token->kind == TOKEN_EOF) { @@ -1681,6 +1679,7 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) { e->unary.op = UNARY_DALIGNOF; single_arg = e->unary.of = parser_new_expr(p); break; + case DIRECT_FOREIGN: case DIRECT_EXPORT: tokr_err(t, "Unrecognized expression."); return false; @@ -1831,7 +1830,17 @@ static bool parse_decl(Parser *p, Declaration *d, DeclEndKind ends_with, U16 fla if (token_is_kw(t->token, KW_EQ)) { ++t->token; - if ((flags & PARSE_DECL_ALLOW_INFER) && ends_decl(t->token, ends_with)) { + if (token_is_direct(t->token, DIRECT_FOREIGN)) { + d->flags |= DECL_FOREIGN; + ++t->token; + /* TODO: foreign name */ + if (!ends_decl(t->token, ends_with)) { + tokr_err(t, "Expected declaration to stop after #foreign, but it continues."); + goto ret_false; + } + ++t->token; + + } else if ((flags & PARSE_DECL_ALLOW_INFER) && ends_decl(t->token, ends_with)) { /* inferred expression */ d->flags |= DECL_INFER; if (arr_len(d->idents) > 1) { @@ -1875,7 +1884,7 @@ static bool parse_decl(Parser *p, Declaration *d, DeclEndKind ends_with, U16 fla } } - if ((d->flags & DECL_IS_CONST) && !(d->flags & DECL_HAS_EXPR) && !(flags & PARSE_DECL_ALLOW_CONST_WITH_NO_EXPR)) { + if ((d->flags & DECL_IS_CONST) && !(d->flags & (DECL_HAS_EXPR | DECL_FOREIGN)) && !(flags & PARSE_DECL_ALLOW_CONST_WITH_NO_EXPR)) { --t->token; /* disallowed constant without an expression, e.g. x :: int; */ tokr_err(t, "You must have an expression at the end of this constant declaration."); @@ -5,6 +5,10 @@ import ::= fn(x :: []char) &Package { p_ptr }; +// n should be size_t +memcpy :: fn (&u8, &u8, u64) = #foreign; + + main ::= fn() { io ::= import("std/io"); io.puts("Hello, world!"); diff --git a/tokenizer.c b/tokenizer.c index 8aece94..1ca3b3b 100644 --- a/tokenizer.c +++ b/tokenizer.c @@ -20,7 +20,7 @@ static const char *const keywords[KW_COUNT] = static inline const char *kw_to_str(Keyword k) { return keywords[k]; } static const char *directives[DIRECT_COUNT] = - {"C", "sizeof", "alignof", "export"}; + {"C", "sizeof", "alignof", "export", "foreign"}; /* Returns KW_COUNT if it's not a keyword */ /* OPTIM: don't use strncmp so much */ @@ -205,6 +205,7 @@ typedef enum { DIRECT_SIZEOF, DIRECT_ALIGNOF, DIRECT_EXPORT, + DIRECT_FOREIGN, DIRECT_COUNT } Directive; @@ -696,9 +697,9 @@ enum { DECL_FOUND_TYPE = 0x0010, DECL_ERRORED_ABOUT_SELF_REFERENCE = 0x0020, /* has there been an error about this decl referencing itself? */ DECL_FOUND_VAL = 0x0040, - DECL_IS_PARAM = 0x0080, - DECL_INFER = 0x0100, /* infer the value (e.g. fn(t::Type=, x:t)) */ - DECL_EXPORT = 0x0200 + DECL_INFER = 0x0080, /* infer the value (e.g. fn(t::Type=, x:t)) */ + DECL_EXPORT = 0x0100, + DECL_FOREIGN = 0x0200 }; typedef U16 DeclFlags; |