From 373b31c24884298219f4236676dfef0a1a524e30 Mon Sep 17 00:00:00 2001 From: Brendan Hansen Date: Mon, 11 May 2020 09:42:45 -0500 Subject: [PATCH] updates --- .vimspector.json | 2 +- bh.h | 20 ++--- onyx | Bin 33824 -> 35904 bytes onyx.c | 205 ++++++++++++++++++++++++++++++++++++++++------- progs/demo.onyx | 5 +- progs/mvp.onyx | 12 ++- 6 files changed, 201 insertions(+), 43 deletions(-) diff --git a/.vimspector.json b/.vimspector.json index ee0c1bfc..72e3a7ab 100644 --- a/.vimspector.json +++ b/.vimspector.json @@ -6,7 +6,7 @@ "type": "cppdbg", "request": "launch", "program": "${workspaceFolder}/onyx", - "args": ["demo.onyx"], + "args": ["progs/mvp.onyx"], "stopAtEntry": true, "cwd": "${workspaceFolder}", "environment": [], diff --git a/bh.h b/bh.h index 7eb4fd09..40dd979f 100644 --- a/bh.h +++ b/bh.h @@ -26,11 +26,11 @@ typedef i32 b32; //------------------------------------------------------------------------------------- // Better character functions //------------------------------------------------------------------------------------- -inline b32 char_is_alpha(const char a); -inline b32 char_is_num(const char a); -inline b32 char_is_alphanum(const char a); -inline b32 char_is_whitespace(const char a); -inline b32 char_in_range(const char lo, const char hi, const char a); +b32 char_is_alpha(const char a); +b32 char_is_num(const char a); +b32 char_is_alphanum(const char a); +b32 char_is_whitespace(const char a); +b32 char_in_range(const char lo, const char hi, const char a); char charset_contains(const char* charset, char ch); //------------------------------------------------------------------------------------- @@ -168,23 +168,23 @@ i32 bh_file_contents_delete(bh_file_contents* contents); //------------------------------------------------------------------------------------- // CHAR FUNCTIONS //------------------------------------------------------------------------------------- -inline b32 char_is_alpha(const char a) { +b32 char_is_alpha(const char a) { return ('a' <= a && a <= 'z') || ('A' <= a && a <= 'Z'); } -inline b32 char_is_num(const char a) { +b32 char_is_num(const char a) { return ('0' <= a && a <= '9'); } -inline b32 char_is_alphanum(const char a) { +b32 char_is_alphanum(const char a) { return char_is_alpha(a) || char_is_num(a); } -inline b32 char_is_whitespace(const char a) { +b32 char_is_whitespace(const char a) { return charset_contains(" \t\r\n", a); } -inline b32 char_in_range(const char lo, const char hi, const char a) { +b32 char_in_range(const char lo, const char hi, const char a) { return lo <= a <= hi; } diff --git a/onyx b/onyx index 2d5a2d93f7c2ed09c2d0dd54a2cc0bc6f90e9a32..b0a2ad6f86daadfc6c9215135d1e8514ea63ec3b 100755 GIT binary patch literal 35904 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 // TODO: Replace with custom lib -#include // TODO: Replace with custom lib #include "bh.h" typedef struct Tokenizer { char *start, *curr, *end; + + // TODO: Fix the line number and column count u64 line_number; + u64 line_column; } Tokenizer; typedef enum TokenType { TOKEN_TYPE_UNKNOWN, TOKEN_TYPE_END_STREAM, + TOKEN_TYPE_COMMENT, + TOKEN_TYPE_KEYWORD_STRUCT, TOKEN_TYPE_KEYWORD_USE, TOKEN_TYPE_KEYWORD_EXPORT, @@ -20,18 +24,33 @@ typedef enum TokenType { TOKEN_TYPE_KEYWORD_RETURN, TOKEN_TYPE_RIGHT_ARROW, + TOKEN_TYPE_LEFT_ARROW, TOKEN_TYPE_OPEN_PAREN, TOKEN_TYPE_CLOSE_PAREN, TOKEN_TYPE_OPEN_BRACE, TOKEN_TYPE_CLOSE_BRACE, TOKEN_TYPE_OPEN_BRACKET, TOKEN_TYPE_CLOSE_BRACKET, + TOKEN_TYPE_OPEN_ANGLE, + TOKEN_TYPE_CLOSE_ANGLE, + + TOKEN_TYPE_SYM_PLUS, + TOKEN_TYPE_SYM_MINUS, + TOKEN_TYPE_SYM_STAR, + TOKEN_TYPE_SYM_PERCENT, + TOKEN_TYPE_SYM_FSLASH, + TOKEN_TYPE_SYM_BSLASH, + TOKEN_TYPE_SYM_COLON, + TOKEN_TYPE_SYM_SEMICOLON, + TOKEN_TYPE_SYM_COMMA, + TOKEN_TYPE_SYM_EQUALS, + TOKEN_TYPE_SYM_GRAVE, + TOKEN_TYPE_SYM_TILDE, + TOKEN_TYPE_SYM_BANG, - TOKEN_TYPE_OP_ADD, - TOKEN_TYPE_OP_SUB, - TOKEN_TYPE_OP_MUL, - TOKEN_TYPE_OP_DIV, - TOKEN_TYPE_OP_MOD, + TOKEN_TYPE_SYMBOL, + TOKEN_TYPE_LITERAL_STRING, + TOKEN_TYPE_LITERAL_NUMERIC, TOKEN_TYPE_COUNT } TokenType; @@ -40,6 +59,8 @@ static const char* TokenTypeNames[] = { "TOKEN_TYPE_UNKNOWN", "TOKEN_TYPE_END_STREAM", + "TOKEN_TYPE_COMMENT", + "TOKEN_TYPE_KEYWORD_STRUCT", "TOKEN_TYPE_KEYWORD_USE", "TOKEN_TYPE_KEYWORD_EXPORT", @@ -49,18 +70,33 @@ static const char* TokenTypeNames[] = { "TOKEN_TYPE_KEYWORD_RETURN", "TOKEN_TYPE_RIGHT_ARROW", + "TOKEN_TYPE_LEFT_ARROW", "TOKEN_TYPE_OPEN_PAREN", "TOKEN_TYPE_CLOSE_PAREN", "TOKEN_TYPE_OPEN_BRACE", "TOKEN_TYPE_CLOSE_BRACE", "TOKEN_TYPE_OPEN_BRACKET", "TOKEN_TYPE_CLOSE_BRACKET", + "TOKEN_TYPE_OPEN_ANGLE", + "TOKEN_TYPE_CLOSE_ANGLE", + + "TOKEN_TYPE_SYM_PLUS", + "TOKEN_TYPE_SYM_MINUS", + "TOKEN_TYPE_SYM_STAR", + "TOKEN_TYPE_SYM_PERCENT", + "TOKEN_TYPE_SYM_FSLASH", + "TOKEN_TYPE_SYM_BSLASH", + "TOKEN_TYPE_SYM_COLON", + "TOKEN_TYPE_SYM_SEMICOLON", + "TOKEN_TYPE_SYM_COMMA", + "TOKEN_TYPE_SYM_EQUALS", + "TOKEN_TYPE_SYM_GRAVE", + "TOKEN_TYPE_SYM_TILDE", + "TOKEN_TYPE_SYM_BANG", - "TOKEN_TYPE_OP_ADD", - "TOKEN_TYPE_OP_SUB", - "TOKEN_TYPE_OP_MUL", - "TOKEN_TYPE_OP_DIV", - "TOKEN_TYPE_OP_MOD", + "TOKEN_TYPE_SYMBOL", + "TOKEN_TYPE_LITERAL_STRING", + "TOKEN_TYPE_LITERAL_NUMERIC", "TOKEN_TYPE_COUNT" }; @@ -72,58 +108,172 @@ typedef struct Token { u64 line_number, line_column; } Token; +#ifndef LITERAL_TOKEN +#define LITERAL_TOKEN(token, token_type) \ + if (token_lit(tokenizer, &tk, token, token_type)) goto token_parsed; +#endif + +#ifndef INCREMENT_CURR_TOKEN +#define INCREMENT_CURR_TOKEN(tkn) { \ + tkn->curr++; \ + tkn->line_column++; \ + if (*tkn->curr == '\n') { \ + tkn->line_number++; \ + tkn->line_column = 1; \ + } \ +} +#endif + b32 token_lit(Tokenizer* tokenizer, Token* tk, char* lit, TokenType type) { i64 len = chars_match(tokenizer->curr, lit); if (len > 0) { tk->type = type; tk->token = tokenizer->curr; tk->length = len; + tokenizer->curr += len; + tokenizer->line_column += len; + return 1; } return 0; } Token get_token(Tokenizer* tokenizer) { - #ifndef LITERAL_TOKEN - #define LITERAL_TOKEN(token, token_type) \ - if (token_lit(tokenizer, &tk, token, token_type)) goto token_parsed; - #endif - Token tk; + // Skip whitespace + while (char_is_whitespace(*tokenizer->curr) && tokenizer->curr != tokenizer->end) + INCREMENT_CURR_TOKEN(tokenizer) + tk.type = TOKEN_TYPE_UNKNOWN; tk.token = tokenizer->curr; tk.length = 1; - tk.line_number = 0; - tk.line_column = 0; + tk.line_number = tokenizer->line_number; + tk.line_column = tokenizer->line_column; if (tokenizer->curr == tokenizer->end) { tk.type = TOKEN_TYPE_END_STREAM; goto token_parsed; } + // Comments + if (*tokenizer->curr == '/' && *(tokenizer->curr + 1) == '*') { + tokenizer->curr += 2; + tk.type = TOKEN_TYPE_COMMENT; + tk.token = tokenizer->curr; + u16 layers = 1; + + while (layers >= 1) { + INCREMENT_CURR_TOKEN(tokenizer); + + if (tokenizer->curr == tokenizer->end) { + tk.type = TOKEN_TYPE_END_STREAM; + break; + } + + if (*tokenizer->curr == '/' && *(tokenizer->curr + 1) == '*') { + layers++; + INCREMENT_CURR_TOKEN(tokenizer); + } + + if (*tokenizer->curr == '*' && *(tokenizer->curr + 1) == '/') { + layers--; + INCREMENT_CURR_TOKEN(tokenizer); + } + } + + INCREMENT_CURR_TOKEN(tokenizer); + + tk.length = tokenizer->curr - tk.token - 2; + goto token_parsed; + } + LITERAL_TOKEN("struct", TOKEN_TYPE_KEYWORD_STRUCT); LITERAL_TOKEN("export", TOKEN_TYPE_KEYWORD_EXPORT); LITERAL_TOKEN("use", TOKEN_TYPE_KEYWORD_USE); LITERAL_TOKEN("if", TOKEN_TYPE_KEYWORD_IF); - LITERAL_TOKEN("else", TOKEN_TYPE_KEYWORD_IF); + LITERAL_TOKEN("else", TOKEN_TYPE_KEYWORD_ELSE); LITERAL_TOKEN("for", TOKEN_TYPE_KEYWORD_FOR); LITERAL_TOKEN("return", TOKEN_TYPE_KEYWORD_RETURN); LITERAL_TOKEN("->", TOKEN_TYPE_RIGHT_ARROW); + LITERAL_TOKEN("<-", TOKEN_TYPE_RIGHT_ARROW); LITERAL_TOKEN("(", TOKEN_TYPE_OPEN_PAREN); LITERAL_TOKEN(")", TOKEN_TYPE_CLOSE_PAREN); LITERAL_TOKEN("{", TOKEN_TYPE_OPEN_BRACE); LITERAL_TOKEN("}", TOKEN_TYPE_CLOSE_BRACE); LITERAL_TOKEN("[", TOKEN_TYPE_OPEN_BRACKET); LITERAL_TOKEN("]", TOKEN_TYPE_CLOSE_BRACKET); - LITERAL_TOKEN("+", TOKEN_TYPE_OP_ADD); - LITERAL_TOKEN("-", TOKEN_TYPE_OP_SUB); - LITERAL_TOKEN("*", TOKEN_TYPE_OP_MUL); - LITERAL_TOKEN("/", TOKEN_TYPE_OP_DIV); - LITERAL_TOKEN("%", TOKEN_TYPE_OP_MOD); + LITERAL_TOKEN("<", TOKEN_TYPE_OPEN_ANGLE); + LITERAL_TOKEN(">", TOKEN_TYPE_CLOSE_ANGLE); + LITERAL_TOKEN("+", TOKEN_TYPE_SYM_PLUS); + LITERAL_TOKEN("-", TOKEN_TYPE_SYM_MINUS); + LITERAL_TOKEN("*", TOKEN_TYPE_SYM_STAR); + LITERAL_TOKEN("/", TOKEN_TYPE_SYM_FSLASH); + LITERAL_TOKEN("%", TOKEN_TYPE_SYM_PERCENT); + LITERAL_TOKEN("\\", TOKEN_TYPE_SYM_BSLASH); + LITERAL_TOKEN(":", TOKEN_TYPE_SYM_COLON); + LITERAL_TOKEN(";", TOKEN_TYPE_SYM_SEMICOLON); + LITERAL_TOKEN(",", TOKEN_TYPE_SYM_COMMA); + LITERAL_TOKEN("=", TOKEN_TYPE_SYM_EQUALS); + LITERAL_TOKEN("`", TOKEN_TYPE_SYM_GRAVE); + LITERAL_TOKEN("~", TOKEN_TYPE_SYM_TILDE); + LITERAL_TOKEN("!", TOKEN_TYPE_SYM_BANG); + + // Symbols + if (char_is_alpha(*tk.token)) { + u64 len = 0; + while (char_is_alphanum(*tokenizer->curr) || charset_contains("_$", *tokenizer->curr)) { + len++; + INCREMENT_CURR_TOKEN(tokenizer); + } + + tk.length = len; + tk.type = TOKEN_TYPE_SYMBOL; + goto token_parsed; + } + + // String literal + if (*tk.token == '"') { + u64 len = 0; + u64 slash_count = 0; + + INCREMENT_CURR_TOKEN(tokenizer); + + while (!(*tokenizer->curr == '"' && slash_count == 0)) { + len++; + + if (*tokenizer->curr == '\\') { + slash_count += 1; + slash_count %= 2; + } else { + slash_count = 0; + } + + INCREMENT_CURR_TOKEN(tokenizer); + } + + INCREMENT_CURR_TOKEN(tokenizer); + + tk.token++; + tk.type = TOKEN_TYPE_LITERAL_STRING; + tk.length = len; + goto token_parsed; + } + + // Number literal + if (char_is_num(*tokenizer->curr)) { + u64 len = 0; + while (char_is_num(*tokenizer->curr) || *tokenizer->curr == '.') { + len++; + INCREMENT_CURR_TOKEN(tokenizer); + } + + tk.type = TOKEN_TYPE_LITERAL_NUMERIC; + tk.length = len; + } - tokenizer->curr++; // Ignore token + INCREMENT_CURR_TOKEN(tokenizer); token_parsed: return tk; @@ -143,8 +293,9 @@ int main(int argc, char *argv[]) { Tokenizer tknizer = { .start = fc.data, .curr = fc.data, - .end = fc.data + fc.length, + .end = fc.data + fc.length - 1, .line_number = 1, + .line_column = 1, }; Token tk; @@ -152,7 +303,7 @@ int main(int argc, char *argv[]) { tk = get_token(&tknizer); char c = *(tk.token + tk.length); *(tk.token + tk.length) = '\0'; - printf("%s: %s\n", TokenTypeNames[tk.type], tk.token); + printf("Line %ld, Column %ld: \n%s: %s\n", tk.line_number, tk.line_column, TokenTypeNames[tk.type], tk.token); *(tk.token + tk.length) = c; } while (tk.type != TOKEN_TYPE_END_STREAM); diff --git a/progs/demo.onyx b/progs/demo.onyx index 32a37db1..b0d3cf07 100644 --- a/progs/demo.onyx +++ b/progs/demo.onyx @@ -7,5 +7,6 @@ use "core"; /* Looks for "core.onyx" in the current directory */ Foo :: struct { x i32, y i32 }; add :: (a i32, b i32) -> i32 { - return a + b; -}; \ No newline at end of file + return a + b + 1234.56; +}; + diff --git a/progs/mvp.onyx b/progs/mvp.onyx index 10f24015..cf693c37 100644 --- a/progs/mvp.onyx +++ b/progs/mvp.onyx @@ -1,11 +1,17 @@ -/* Comments need to be parsed */ +/* Comments need to be parsed + /* nested comments /* are /* okay */ */ */ +*/ -export add :: (a: i32, b: i32) -> i32 { +foreign "console" "log" :: (ptr, i32) -> void; + +export add :: (a i32, b i32) -> i32 { return a + b; } -export max :: (a: i32, b: i32) -> i32 { +export max :: (a i32, b i32) -> i32 { /* Curly braces are required */ + x := "String literal! HERE \\\"Woot Woot\" done"; + if a > b { return a; } else { -- 2.25.1