From: Brendan Hansen Date: Wed, 17 Nov 2021 21:00:42 +0000 (-0600) Subject: bugfixes and completely removed 'proc' keyword X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=4446487be31b683544c9f52c341fa3496b344984;p=onyx.git bugfixes and completely removed 'proc' keyword --- diff --git a/core/container/set.onyx b/core/container/set.onyx index dc3c253e..c421bff2 100644 --- a/core/container/set.onyx +++ b/core/container/set.onyx @@ -8,7 +8,12 @@ package core.set } use package core.intrinsics.onyx { __zero_value } -Set :: struct (T: type_expr) { +#local SetValue :: interface (T: type_expr) { + hash.to_u32(T); + T == T; +} + +Set :: struct (T: type_expr) where SetValue(T) { allocator : Allocator; hashes : [] i32; diff --git a/core/runtime/wasi.onyx b/core/runtime/wasi.onyx index 18fa2b5e..9ad50535 100644 --- a/core/runtime/wasi.onyx +++ b/core/runtime/wasi.onyx @@ -50,3 +50,7 @@ __exit :: (status: i32) do proc_exit(status); __flush_stdio(); } + + +__spawn_thread :: (t: i32, func: (data: rawptr) -> void, data: rawptr) -> bool --- +__kill_thread :: (t: i32) -> i32 --- diff --git a/include/lex.h b/include/lex.h index fb9a9493..f8d5d1c5 100644 --- a/include/lex.h +++ b/include/lex.h @@ -23,7 +23,6 @@ typedef enum TokenType { Token_Type_Keyword_Elseif, Token_Type_Keyword_Return, Token_Type_Keyword_Global, - Token_Type_Keyword_Proc, Token_Type_Keyword_As, Token_Type_Keyword_Cast, Token_Type_Keyword_While, diff --git a/misc/onyx-mode.el b/misc/onyx-mode.el new file mode 100644 index 00000000..8dfea243 --- /dev/null +++ b/misc/onyx-mode.el @@ -0,0 +1,222 @@ +;;; lang/onyx/autoload/onyx.el -*- lexical-binding: t; -*- + + +;; onyx-mode.el - very basic onyx mode + +(require 'cl) +(require 'rx) +(require 'js) + +(defconst onyx-mode-syntax-table + (let ((table (make-syntax-table))) + (modify-syntax-entry ?\" "\"" table) + (modify-syntax-entry ?\\ "\\" table) + + ;; additional symbols + (modify-syntax-entry ?_ "w" table) + + (modify-syntax-entry ?' "." table) + (modify-syntax-entry ?: "." table) + (modify-syntax-entry ?+ "." table) + (modify-syntax-entry ?- "." table) + (modify-syntax-entry ?% "." table) + (modify-syntax-entry ?& "." table) + (modify-syntax-entry ?| "." table) + (modify-syntax-entry ?^ "." table) + (modify-syntax-entry ?! "." table) + (modify-syntax-entry ?$ "/" table) + (modify-syntax-entry ?= "." table) + (modify-syntax-entry ?< "." table) + (modify-syntax-entry ?> "." table) + (modify-syntax-entry ?? "." table) + + ;; Modify some syntax entries to allow nested block comments + (modify-syntax-entry ?/ ". 124b" table) + (modify-syntax-entry ?* ". 23n" table) + (modify-syntax-entry ?\n "> b" table) + (modify-syntax-entry ?\^m "> b" table) + + table)) + +(defconst onyx-builtins + '("cast" "it" "sizeof" "alignof" "typeof")) + +(defconst onyx-keywords + '("if" "elseif" "else" "do" "while" "for" "switch" "case" "struct" "enum" + "return" "continue" "break" "fallthrough" "defer" "macro" "package" + "use" "interface" "where")) + +(defconst onyx-constants + '("null" "true" "false" "null_str" "null_proc")) + +(defconst onyx-typenames + '("u64" "u32" "u16" "u8" + "i64" "i32" "i16" "i8" + "f32" "f64" "str" "cstr" "any" "type_expr" + "bool" "void" "rawptr" + "i8x16" "i16x8" "i32x4" "i64x2" + "f32x4" "f64x2" "v128")) + +(defun onyx-wrap-word-rx (s) + (concat "\\<" s "\\>")) + +(defun onyx-keywords-rx (keywords) + "build keyword regexp" + (onyx-wrap-word-rx (regexp-opt keywords t))) + +(defconst onyx-hat-type-rx (rx (group (and "^" (1+ word))))) +(defconst onyx-dollar-type-rx (rx (group "$" (or (1+ word) (opt "$"))))) +(defconst onyx-number-rx + (rx (and + symbol-start + (or (and (+ digit) (opt (and (any "eE") (opt (any "-+")) (+ digit)))) + (and "0" (any "xX") (+ hex-digit))) + (opt (and (any "_" "A-Z" "a-z") (* (any "_" "A-Z" "a-z" "0-9")))) + symbol-end))) + +(defconst onyx-font-lock-defaults + `( + ;; Keywords + (,(onyx-keywords-rx onyx-keywords) 1 font-lock-keyword-face) + + ;; single quote characters + ("\\('[[:word:]]\\)\\>" 1 font-lock-constant-face) + + ;; Variables + (,(onyx-keywords-rx onyx-builtins) 1 font-lock-variable-name-face) + + ;; Constants + (,(onyx-keywords-rx onyx-constants) 1 font-lock-constant-face) + + ;; Hash directives + ("#\\w+" . font-lock-preprocessor-face) + + ;; At directives + ("@\\w+" . font-lock-preprocessor-face) + + ;; Strings + ("\\\".*\\\"" . font-lock-string-face) + + ;; Numbers + (,(onyx-wrap-word-rx onyx-number-rx) . font-lock-constant-face) + + ;; Types + (,(onyx-keywords-rx onyx-typenames) 1 font-lock-type-face) + (,onyx-dollar-type-rx 1 font-lock-type-face) + + ("---" . font-lock-constant-face) + )) + +;; add setq-local for older emacs versions +(unless (fboundp 'setq-local) + (defmacro setq-local (var val) + `(set (make-local-variable ',var) ,val))) + +(defconst onyx--defun-rx "\(.*\).*\{") + +(defmacro onyx-paren-level () + `(car (syntax-ppss))) + +(defun onyx-line-is-defun () + "return t if current line begins a procedure" + (interactive) + (save-excursion + (beginning-of-line) + (let (found) + (while (and (not (eolp)) (not found)) + (if (looking-at onyx--defun-rx) + (setq found t) + (forward-char 1))) + found))) + +(defun onyx-beginning-of-defun (&optional count) + "Go to line on which current function starts." + (interactive) + (let ((orig-level (onyx-paren-level))) + (while (and + (not (onyx-line-is-defun)) + (not (bobp)) + (> orig-level 0)) + (setq orig-level (onyx-paren-level)) + (while (>= (onyx-paren-level) orig-level) + (skip-chars-backward "^{") + (backward-char)))) + (if (onyx-line-is-defun) + (beginning-of-line))) + +(defun onyx-end-of-defun () + "Go to line on which current function ends." + (interactive) + (let ((orig-level (onyx-paren-level))) + (when (> orig-level 0) + (onyx-beginning-of-defun) + (end-of-line) + (setq orig-level (onyx-paren-level)) + (skip-chars-forward "^}") + (while (>= (onyx-paren-level) orig-level) + (skip-chars-forward "^}") + (forward-char))))) + +(defalias 'onyx-parent-mode + (if (fboundp 'prog-mode) 'prog-mode 'fundamental-mode)) + +;; imenu hookup +(add-hook 'onyx-mode-hook + (lambda () + (setq imenu-generic-expression + '( + ("type" "^\\(.*:*.*\\) : " 1) + ("function" "^\\(.*\\) :: " 1) + ("struct" "^\\(.*\\) *:: *\\(struct\\)\\(.*\\){" 1) + ) + ) + ) +) + +;; NOTE: taken from the scala-indent package and modified for Onyx. +;; Still uses the js-indent-line as a base, which will have to be +;; replaced when the language is more mature. +(defun onyx--indent-on-parentheses () + (when (and (= (char-syntax (char-before)) ?\)) + (= (save-excursion (back-to-indentation) (point)) (1- (point)))) + (js-indent-line))) + +(defun onyx--add-self-insert-hooks () + (add-hook 'post-self-insert-hook + 'onyx--indent-on-parentheses) + ) + +(require 'compile) +(add-hook 'onyx-mode-hook (lambda () + (add-to-list 'compilation-error-regexp-alist 'onyx) + (add-to-list 'compilation-error-regexp-alist-alist '(onyx "^(\\(.*\\):\\([0-9]+\\),\\([0-9]+\\)) \\(.*\\)" 1 2 3)) + )) + +;; (add-hook 'onyx-mode-hook (lambda() +;; (rainbow-delimiters-mode) +;; )) + +;;;###autoload +(define-derived-mode onyx-mode onyx-parent-mode "Onyx" + :syntax-table onyx-mode-syntax-table + :group 'onyx + (setq bidi-paragraph-direction 'left-to-right) + (setq-local require-final-newline mode-require-final-newline) + (setq-local parse-sexp-ignore-comments t) + (setq-local comment-start-skip "\\(//+\\|/\\*+\\)\\s *") + (setq-local comment-start "/*") + (setq-local comment-end "*/") + (setq-local indent-line-function 'js-indent-line) + (setq-local font-lock-defaults '(onyx-font-lock-defaults)) + (setq-local beginning-of-defun-function 'onyx-beginning-of-defun) + (setq-local end-of-defun-function 'onyx-end-of-defun) + + ;; add indent functionality to some characters + (onyx--add-self-insert-hooks) + + (font-lock-fontify-buffer)) + +;;;###autoload +(add-to-list 'auto-mode-alist '("\\.onyx\\'" . onyx-mode)) + +(provide 'onyx-mode) diff --git a/src/astnodes.c b/src/astnodes.c index 07307593..50c9a629 100644 --- a/src/astnodes.c +++ b/src/astnodes.c @@ -573,7 +573,7 @@ TypeMatch unify_node_and_type_(AstTyped** pnode, Type* type, b32 permanent) { if (node->kind == Ast_Kind_Unary_Field_Access) { AstType* ast_type = type->ast_type; AstNode* resolved = try_symbol_resolve_from_node((AstNode *) ast_type, node->token); - if (resolved == NULL) return TYPE_MATCH_FAILED; + if (resolved == NULL) return TYPE_MATCH_YIELD; if (permanent) *pnode = (AstTyped *) resolved; return TYPE_MATCH_SUCCESS; diff --git a/src/lex.c b/src/lex.c index a19b6759..e3152c48 100644 --- a/src/lex.c +++ b/src/lex.c @@ -21,7 +21,6 @@ static const char* token_type_names[] = { "elseif", "return", "global", - "proc", "as", "cast", "while", @@ -366,7 +365,6 @@ whitespace_skipped: break; case 'p': LITERAL_TOKEN("package", 1, Token_Type_Keyword_Package); - LITERAL_TOKEN("proc", 1, Token_Type_Keyword_Proc); break; case 'r': LITERAL_TOKEN("return", 1, Token_Type_Keyword_Return); diff --git a/src/parser.c b/src/parser.c index f7222b68..9c8dde2d 100644 --- a/src/parser.c +++ b/src/parser.c @@ -1717,14 +1717,6 @@ static AstType* parse_type(OnyxParser* parser) { break; } - case Token_Type_Keyword_Proc: { - OnyxToken* proc_token = expect_token(parser, Token_Type_Keyword_Proc); - onyx_report_warning(proc_token->pos, "Warning: 'proc' is a deprecated keyword."); - *next_insertion = parse_function_type(parser, proc_token); - next_insertion = NULL; - break; - } - case '$': { parse_polymorphic_variable(parser, &next_insertion); break; @@ -2284,21 +2276,32 @@ static AstFunction* parse_function_definition(OnyxParser* parser, OnyxToken* tok func_def->return_type = (AstType *) &basic_type_void; + char* name = NULL; + if (bh_arr_length(parser->current_symbol_stack) > 0) { + OnyxToken *current_symbol = bh_arr_last(parser->current_symbol_stack); + name = bh_aprintf(global_heap_allocator, "%b", current_symbol->text, current_symbol->length); + } + if (consume_token_if_next(parser, '=')) { expect_token(parser, '>'); func_def->return_type = (AstType *) &basic_type_auto_return; - AstTyped* returned_value = parse_compound_expression(parser, 0); + if (parser->curr->type == '{') { + func_def->body = parse_block(parser, 1, name); - AstReturn* return_node = make_node(AstReturn, Ast_Kind_Return); - return_node->token = returned_value->token; - return_node->expr = returned_value; + } else { + AstTyped* returned_value = parse_compound_expression(parser, 0); - AstBlock* body_block = make_node(AstBlock, Ast_Kind_Block); - body_block->token = returned_value->token; - body_block->body = (AstNode *) return_node; + AstReturn* return_node = make_node(AstReturn, Ast_Kind_Return); + return_node->token = returned_value->token; + return_node->expr = returned_value; - func_def->body = body_block; + AstBlock* body_block = make_node(AstBlock, Ast_Kind_Block); + body_block->token = returned_value->token; + body_block->body = (AstNode *) return_node; + + func_def->body = body_block; + } goto function_defined; } @@ -2344,11 +2347,6 @@ static AstFunction* parse_function_definition(OnyxParser* parser, OnyxToken* tok } } - char* name = NULL; - if (bh_arr_length(parser->current_symbol_stack) > 0) { - OnyxToken *current_symbol = bh_arr_last(parser->current_symbol_stack); - name = bh_aprintf(global_heap_allocator, "%b", current_symbol->text, current_symbol->length); - } func_def->body = parse_block(parser, 1, name); function_defined: diff --git a/src/polymorph.c b/src/polymorph.c index cfa25705..8c5d237f 100644 --- a/src/polymorph.c +++ b/src/polymorph.c @@ -419,6 +419,11 @@ static AstTyped* try_lookup_based_on_partial_function_type(AstPolyProc *pp, AstF AstType *old_return_type = ft->return_type; ft->return_type = (AstType *) &basic_type_void; ft->partial_function_type = type_build_from_ast(context.ast_alloc, (AstType *) ft); + if (!ft->partial_function_type) { + doing_nested_polymorph_lookup = 1; + return NULL; + } + assert(ft->partial_function_type); ft->return_type = old_return_type; } diff --git a/tests/complicated_polymorph.onyx b/tests/complicated_polymorph.onyx index 9b7c468c..41b45759 100644 --- a/tests/complicated_polymorph.onyx +++ b/tests/complicated_polymorph.onyx @@ -36,4 +36,43 @@ main :: (args: [] cstr) { |> convert(f32) |> map((x) => x * 4 + 2) |> println(); + + + // This does not work at the moment + #if false { + Color :: enum { + Red; Orange; Yellow; Blue; + } + + Guy :: struct { + best_friend: ^Guy; + favorite_color: Color; + } + + nightmare :: (x: (typeof(z.best_friend), $K) -> void, + y: (typeof(x)) -> $R, + z: ^$SomeType, + w: R) { + k := y(x); + } + + dummy1 :: (a: $T, b: typeof(a.favorite_color)) -> void { + printf("dummy1 got T={}, typeof(a.favorite_color)={}\n", a, typeof(b)); + } + + dummy2 :: (f: (a: ^Guy, b: $C) -> void) -> C { + printf("dummy2 got C={}\n", C); + + other_guy := new(Guy); + f(other_guy, .Orange); + + default: C; + return default; + } + + guy := new(Guy); + guy.best_friend = guy; + + nightmare(dummy1, dummy2, guy, .Orange); + } }