From a66d9199eb6169265a103361b624fc1f8cb21364 Mon Sep 17 00:00:00 2001 From: Leo Tenenbaum Date: Sat, 18 Jan 2020 00:34:02 -0500 Subject: started #foreign --- main.c | 2 +- parse.c | 19 ++++++++++++++----- test.toc | 4 ++++ tokenizer.c | 2 +- types.h | 7 ++++--- 5 files changed, 24 insertions(+), 10 deletions(-) diff --git a/main.c b/main.c index a98fbb2..c3a5bb9 100644 --- a/main.c +++ b/main.c @@ -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) diff --git a/parse.c b/parse.c index 921a3b0..dd868a6 100644 --- a/parse.c +++ b/parse.c @@ -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."); diff --git a/test.toc b/test.toc index d7654e3..aa12b62 100644 --- a/test.toc +++ b/test.toc @@ -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 */ diff --git a/types.h b/types.h index 6fb68c2..f3adcee 100644 --- a/types.h +++ b/types.h @@ -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; -- cgit v1.2.3