diff --git a/arch/web/main.c b/arch/web/main.c index eb27e20..ca8993c 100644 --- a/arch/web/main.c +++ b/arch/web/main.c @@ -1 +1,63 @@ -// wip +#include "../../libc.h" +#include "../../compiler.h" +#include +#include +#include + +#define MEM_SIZE (1 << 16) + +static size_t List_size(List *list) { + size_t total = 0; + Node *curr = list->head; + while (curr) { + total += curr->size; + curr = curr->next; + } + return total; +} + +static void list2buffer(List *list, char *buffer, size_t *offset) { + Node *curr = list->head; + while (curr) { + char *tmp_str = node_value(curr); + memcpy(buffer + *offset, tmp_str, curr->size); + *offset += curr->size; + curr = curr->next; + } +} + +EMSCRIPTEN_KEEPALIVE +char *undar_compile(int emitter_type, char *source) { + Emitter e; + if (emitter_type == 0) { + e = rer_emitter(); + } else if (emitter_type == 1) { + e = uxn_emitter(); + } else { + return NULL; + } + + u8 tape[MEM_SIZE]; + Arena a = {tape, 0, MEM_SIZE}; + + List *code = List_init(&a); + List *memory = List_init(&a); + + compile(&a, code, memory, e, source); + + size_t code_size = List_size(code); + size_t mem_size = List_size(memory); + size_t total_size = code_size + mem_size + 1; + + char *result = (char *)malloc(total_size); + if (result == NULL) return NULL; + + size_t offset = 0; + list2buffer(code, result, &offset); + list2buffer(memory, result, &offset); + result[offset] = '\0'; + + afree(&a); + + return result; +} \ No newline at end of file diff --git a/build b/build index 05ff27e..6ad1792 100755 --- a/build +++ b/build @@ -93,7 +93,13 @@ case $ARCH in BUILD_CMD="$CC -o $BUILD_DIR/undar $SRC_DIR/main.c emit/rer/emit.c emit/uxn/emit.c $LINK_FLAGS $BUILD_DIR/libc.o $BUILD_DIR/list.o $BUILD_DIR/lexer.o $BUILD_DIR/compiler.o $BUILD_DIR/strbuf.o $BUILD_FLAGS $LINK_FLAGS" ;; "web") - BUILD_CMD="$CC $SRC_DIR/main.c emit/rer/emit.c emit/uxn/emit.c $BUILD_DIR/libc.o $BUILD_DIR/list.o $BUILD_DIR/lexer.o $BUILD_DIR/compiler.o -o $BUILD_DIR/undar.html $BUILD_FLAGS $LINK_FLAGS" + WEB_BUILD_FLAGS="-O3 -s STACK_SIZE=1048576" + + WEB_EXPORTS="-s EXPORTED_FUNCTIONS=[\"_undar_compile\",\"_malloc\",\"_free\"] -s EXPORTED_RUNTIME_METHODS=[\"cwrap\"]" + + BUILD_CMD="$CC $SRC_DIR/main.c emit/rer/emit.c emit/uxn/emit.c $BUILD_DIR/libc.o $BUILD_DIR/list.o $BUILD_DIR/lexer.o $BUILD_DIR/compiler.o $BUILD_DIR/strbuf.o -o $BUILD_DIR/undar.js $WEB_BUILD_FLAGS $WEB_EXPORTS" + + cp ./tools/index.html $BUILD_DIR/ ;; esac diff --git a/compiler.c b/compiler.c index b4d7994..5c023b2 100644 --- a/compiler.c +++ b/compiler.c @@ -15,7 +15,7 @@ List *memory; * Scope ***************************************************/ void -scopes_init() +scopes_init(void) { Scope *current; Scope child = {0}; @@ -27,7 +27,7 @@ scopes_init() } Scope * -scope_new() +scope_new(void) { Scope *current; Scope child = {0}; @@ -43,7 +43,7 @@ scope_new() } void -scope_pop() +scope_pop(void) { if(parser.current_scope) { parser.current_scope = parser.current_scope->parent; @@ -52,7 +52,7 @@ scope_pop() } void -scope_push() +scope_push(void) { Scope *scope = List_get(parser.scopes, parser.scope_idx); parser.current_scope = scope; @@ -109,13 +109,13 @@ scope_add_symbol(const char *name, u32 name_length, SymbolType type, u32 size) } bool -is_global() +is_global(void) { return parser.current_scope != nil && parser.current_scope->parent == nil; } bool -is_type() +is_type(void) { return parser.previous.type >= TOKEN_TYPE_I8 && parser.previous.type <= TOKEN_TYPE_PTR; @@ -156,7 +156,7 @@ token_type_to_sym_type(TokenType t) ***************************************************/ bool -advance() +advance(void) { parser.previous = parser.current; @@ -174,7 +174,7 @@ check(TokenType type) } bool -consume_is_type() +consume_is_type(void) { if(is_type()) { advance(); @@ -215,17 +215,17 @@ expect(TokenType type) u32 variable_declaration(Symbol *def); void -define_plex() +define_plex(void) { } void -define_trait() +define_trait(void) { } void -define_function() +define_function(void) { Symbol *fn; u32 size = 0; @@ -298,7 +298,7 @@ calculate_strides(List *dims, List *strides) } void -define_array() +define_array(void) { i32 size = 0, n = 0, flat_array_length = 1; TokenType tt = parser.previous.type; @@ -365,9 +365,9 @@ build_symbol_table(char *source) } } -void expression(); -void statement(); -void declaration(); +void expression(void); +void statement(void); +void declaration(void); ParseRule *get_rule(TokenType type); void parse_precedence(Precedence precedence); @@ -459,7 +459,7 @@ variable_declaration(Symbol *def) } void -binary() +binary(void) { TokenType operatorType = parser.previous.type; ParseRule *rule = get_rule(operatorType); @@ -521,7 +521,7 @@ binary() } void -literal() +literal(void) { switch(parser.previous.type) { case TOKEN_KEYWORD_FALSE: @@ -539,13 +539,13 @@ literal() } void -expression() +expression(void) { parse_precedence(PREC_ASSIGNMENT); } void -variable() +variable(void) { Symbol *sym = scope_get_symbol(parser.current_scope, parser.previous.start, parser.previous.length); @@ -594,7 +594,7 @@ variable() } void -cast_type() +cast_type(void) { SymbolType st = parser.current_type; TokenType cast_type; @@ -691,7 +691,7 @@ cast_type() } void -declaration() +declaration(void) { if(is_type() && (parser.current.type == TOKEN_IDENTIFIER || parser.current.type == TOKEN_LBRACKET) ) variable_declaration(nil); @@ -700,7 +700,7 @@ declaration() } void -print_statement() +print_statement(void) { expression(); consume(TOKEN_SEMICOLON); @@ -709,7 +709,7 @@ print_statement() } void -if_statement() +if_statement(void) { consume(TOKEN_LPAREN); expression(); @@ -727,7 +727,7 @@ if_statement() } void -while_statement() +while_statement(void) { u32 this_while = emitter.loops++; emitter.emit_while(arena, code, this_while); @@ -740,7 +740,7 @@ while_statement() } void -block() +block(void) { while(!check(TOKEN_RBRACE) && !check(TOKEN_EOF)) declaration(); @@ -748,7 +748,7 @@ block() } void -function() +function(void) { Symbol *sym = scope_get_symbol(parser.current_scope, parser.previous.start, parser.previous.length); @@ -762,7 +762,7 @@ function() } void -call() +call(void) { if(!check(TOKEN_RPAREN)) { do { @@ -777,7 +777,7 @@ call() } void -return_statement() +return_statement(void) { if(match(TOKEN_SEMICOLON)) { emitter.emit_early_return(arena, code); @@ -789,7 +789,7 @@ return_statement() } void -statement() +statement(void) { if(match(TOKEN_LBRACE)) { scope_push(); @@ -814,7 +814,7 @@ statement() } void -grouping() +grouping(void) { emitter.emit_open_paren(arena, code); @@ -825,25 +825,25 @@ grouping() } void -number() +number(void) { emitter.emit_int(arena, code, parser.previous.start, parser.previous.length); } void -string() +string(void) { emitter.emit_str(arena, code, parser.previous.start, parser.previous.length); } void -character() +character(void) { emitter.emit_char(arena, code, parser.previous.start, parser.previous.length); } void -unary() +unary(void) { TokenType operatorType = parser.previous.type; parse_precedence(PREC_UNARY); @@ -861,13 +861,13 @@ unary() } void -read() +read(void) { emitter.emit_read(arena, code); } void -write() +write(void) { consume(TOKEN_EQ); advance(); diff --git a/compiler.h b/compiler.h index 3386385..54945c2 100644 --- a/compiler.h +++ b/compiler.h @@ -31,7 +31,7 @@ typedef enum { PREC_PRIMARY } Precedence; -typedef void (*ParseFn)(); +typedef void (*ParseFn)(void); struct parse_rule_s { ParseFn prefix; diff --git a/emit.h b/emit.h index 137e947..cb70648 100644 --- a/emit.h +++ b/emit.h @@ -109,7 +109,7 @@ struct emitter_s { StrArgEmit emit_char; }; -Emitter rer_emitter(); -Emitter uxn_emitter(); +Emitter rer_emitter(void); +Emitter uxn_emitter(void); #endif diff --git a/lexer.c b/lexer.c index 151e918..7af6a34 100644 --- a/lexer.c +++ b/lexer.c @@ -30,26 +30,26 @@ is_digit(char c) } static bool -is_at_end() +is_at_end(void) { return *lexer.current == '\0'; } static char -advance() +advance(void) { lexer.current++; return lexer.current[-1]; } char -peek() +peek(void) { return *lexer.current; } static char -peek_next() +peek_next(void) { if(is_at_end()) return '\0'; return lexer.current[1]; @@ -87,7 +87,7 @@ error_token(const char *message) } static void -skip_whitespace() +skip_whitespace(void) { for(;;) { char c = peek(); @@ -140,7 +140,7 @@ check_keyword(i32 start, i32 length, const char *rest, TokenType type) } static TokenType -identifierType() +identifierType(void) { switch(lexer.start[0]) { case 'a': @@ -343,14 +343,14 @@ identifierType() } static Token -identifier() +identifier(void) { while(is_alpha(peek()) || is_digit(peek())) advance(); return make_token(identifierType()); } static Token -number() +number(void) { while(is_digit(peek())) advance(); @@ -368,7 +368,7 @@ number() } static Token -string() +string(void) { while(peek() != '"' && !is_at_end()) { if(peek() == '\n') lexer.line++; @@ -383,7 +383,7 @@ string() } static Token -character() +character(void) { advance(); if(peek() != '\'' && !is_at_end()) { @@ -398,7 +398,7 @@ character() } Token -next_token() +next_token(void) { char c; char next; diff --git a/lexer.h b/lexer.h index ba595f7..0ab5384 100644 --- a/lexer.h +++ b/lexer.h @@ -101,8 +101,8 @@ struct token_s { }; void init_lexer(const char *source); -Token next_token(); +Token next_token(void); const char *token_type_to_string(TokenType type); -char peek(); +char peek(void); #endif diff --git a/libc.c b/libc.c index 24ced35..4b7d801 100644 --- a/libc.c +++ b/libc.c @@ -367,7 +367,7 @@ stoi(const char *str, u32 length) } while (is_digit(*str) && length-- > 0) { - int digit = *str++ - '0'; + i32 digit = *str++ - '0'; if (neg) { if (n < (I32_MIN / 10) || (n == (I32_MIN / 10) && digit > -(I32_MIN % 10))) { @@ -396,7 +396,7 @@ ston(const char *str, u32 length) } while (is_digit(*str) && length-- > 0) { - int digit = *str++ - '0'; + u32 digit = *str++ - '0'; if (n > (U32_MAX / 10) || (n == (U32_MAX / 10) && digit > (U32_MAX % 10))) { return U32_MAX; diff --git a/libc.h b/libc.h index aa10841..b50a99c 100644 --- a/libc.h +++ b/libc.h @@ -5,9 +5,6 @@ #if __has_include() #define HAVE_STDINT 1 #endif -#if __has_include() -#define HAVE_STDBOOL 1 -#endif #if __has_include() #define HAVE_STDDEF 1 #endif @@ -34,13 +31,9 @@ typedef signed int r32; typedef float f32; #endif -#ifdef HAVE_STDBOOL -#include -#else #define true 1 #define false 0 typedef u8 bool; -#endif #ifdef HAVE_STDDEF #include @@ -59,7 +52,7 @@ typedef u8 bool; #define I32_MIN -2147483647 #define I32_MAX 2147483647 -#define U32_MAX 4294967295 +#define U32_MAX 4294967295UL #define FIXED_CONST 65536.0f diff --git a/tools/index.html b/tools/index.html new file mode 100644 index 0000000..04b86b4 --- /dev/null +++ b/tools/index.html @@ -0,0 +1,104 @@ + + + + + + Undâr Compiler + + + + + + + + + + + + + +
+
+
+
Source
+
+
+
+
+
+
Output
+
+
+
+
+
+
+ + + + \ No newline at end of file