├── .editorconfig ├── .gitattributes ├── LICENSE ├── README.md ├── bin └── volant ├── build.sh ├── examples ├── _build │ ├── 0heapmemory.vo.c │ ├── 0promises.vo.c │ ├── 1heap.vo.h │ └── 1mem.vo.h ├── arrays.vo ├── closures.vo ├── heapmemory.vo ├── helloworld.vo ├── pointers.vo ├── promises.vo ├── structs.vo ├── tuples.vo ├── unions.vo ├── uvloop.vo └── vectors.vo ├── lib ├── callback.vo ├── heap.vo ├── internal │ ├── async.h │ ├── default.h │ ├── heap.h │ ├── promise.h │ ├── types.h │ └── vector.h ├── io.vo ├── math.vo ├── mem.vo ├── num.vo ├── path.vo ├── string.vo ├── uv │ ├── libuv.h │ └── uv.vo └── vector.vo └── src ├── compiler ├── analyzer.go ├── compiler.go ├── formatter.go ├── importer.go ├── names.go └── symbolTable.go ├── error └── error.go ├── main.go └── parser ├── ast.go ├── lexer.go ├── parser.go ├── tokens.go └── util.go /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = tab 5 | indent_size = unset 6 | tab_width = 3 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [{GNUmakefile,Makefile,makefile,*.mk}] 13 | indent_style = tab 14 | 15 | [*.{yaml,yml}] 16 | indent_style = space 17 | 18 | [*.{diff,md,snap}] 19 | trim_trailing_whitespace = false 20 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2020, volantlang 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | 3. Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # The Volant Programming Language 2 | 3 | A general-purpose imperative data-oriented high-level programming language with emphasis on speed, concurrency and asynchronicity. 4 | 5 | ### [Wiki](https://github.com/volantlang/volant/wiki) 6 | -------------------------------------------------------------------------------- /bin/volant: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/volantlang/volant/849136c9fb190159cfceccc4e66382807e9ebae0/bin/volant -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | export GOPATH=$PWD 2 | go build -o ./bin/volant ./src 3 | -------------------------------------------------------------------------------- /examples/_build/0heapmemory.vo.c: -------------------------------------------------------------------------------- 1 | #include "internal/default.h" 2 | #include "1heap.vo.h" 3 | #include "1mem.vo.h" 4 | i32 (^v0_main)(void) = ^i32 (void){ 5 | i32 (*v0_ptr) = (i32*)(v1_malloc((sizeof(i32))*100)); 6 | { 7 | size_t v0_i = 0; 8 | while(v0_i<100){ 9 | printf("%i ", (*(v0_ptr+v0_i))); 10 | (++v0_i); 11 | } 12 | } 13 | printf("\n\n"); 14 | v2_set(v0_ptr, 0, (sizeof(i32))*100); 15 | (*(v0_ptr+10)) = 100; 16 | { 17 | i32 v0_i = 0; 18 | while(v0_i<100){ 19 | printf("%i ", (*(v0_ptr+v0_i))); 20 | (++v0_i); 21 | } 22 | } 23 | printf("\n"); 24 | v1_free(v0_ptr); 25 | i32 (*v0_ptr2)[10] = new3(i32,i32[10],((i32[10]){0, 0, 0, 0, 0, 0, 0, 0, 0, 0, })); 26 | delete(v0_ptr2); 27 | 28 | return 0; 29 | }; 30 | 31 | int main() { 32 | return v0_main(); 33 | } -------------------------------------------------------------------------------- /examples/_build/0promises.vo.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/volantlang/volant/849136c9fb190159cfceccc4e66382807e9ebae0/examples/_build/0promises.vo.c -------------------------------------------------------------------------------- /examples/_build/1heap.vo.h: -------------------------------------------------------------------------------- 1 | #ifndef H_1 2 | #define H_1 3 | #include "internal/default.h" 4 | void* (^v1_malloc)(size_t); 5 | void* (^v1_realloc)(void*, size_t); 6 | void* (^v1_calloc)(size_t, size_t); 7 | void (^v1_free)(void*); 8 | void* (^v1_malloc)(size_t) =^void* (size_t v1_s){ 9 | return (void*)(malloc(v1_s)); 10 | };void* (^v1_realloc)(void*, size_t) =^void* (void (*v1_ptr), size_t v1_s){ 11 | return (void*)(realloc(v1_ptr, v1_s)); 12 | };void* (^v1_calloc)(size_t, size_t) =^void* (size_t v1_el_size, size_t v1_el_num){ 13 | return (void*)(calloc(v1_el_size, v1_el_num)); 14 | };void (^v1_free)(void*) =^void (void (*v1_ptr)){ 15 | free(v1_ptr); 16 | }; 17 | #endif -------------------------------------------------------------------------------- /examples/_build/1mem.vo.h: -------------------------------------------------------------------------------- 1 | #ifndef H_2 2 | #define H_2 3 | #include "internal/default.h" 4 | void* (^v2_copy)(void*, void*, size_t); 5 | i8 (^v2_compare)(void*, void*, size_t); 6 | void* (^v2_set)(void*, u8, size_t); 7 | void* (^v2_copy)(void*, void*, size_t) =^void* (void (*v2_dest), void (*v2_src), size_t v2_length){ 8 | u8 (*v2_l) = (u8*)(v2_dest); u8 (*v2_r) = (u8*)(v2_src); 9 | { 10 | size_t v2_i = 0; 11 | while(v2_i {100} 10 | vector1.concat((vec u32){50}); // vector -> {100, 50} 11 | 12 | $printf("Length: %zu, Capacity: %zu.\n", vector1.length, vector1.capacity); 13 | $printf("vector1[0] is %u\n", vector1[0]); 14 | $printf("vector1[1] is %u\n", vector1[1]); 15 | 16 | vector2 := vector1.clone(); 17 | vector2[0] = 99; 18 | 19 | $printf("vector1[0] is %u\n", vector1[0]); 20 | $printf("vector2[0] is %u\n", vector2[0]); 21 | return 0; 22 | } -------------------------------------------------------------------------------- /lib/callback.vo: -------------------------------------------------------------------------------- 1 | export func work copy(fnc: *void) *void { 2 | return $_Block_copy(fnc); 3 | }; 4 | 5 | export func work free(fnc: *void) { 6 | $_Block_release(fnc); 7 | }; 8 | -------------------------------------------------------------------------------- /lib/heap.vo: -------------------------------------------------------------------------------- 1 | export func work malloc(s: size_t) *void { 2 | return cast(*void)$malloc(s); 3 | } 4 | export func work realloc(ptr: *void, s: size_t) *void { 5 | return cast(*void)$realloc(ptr, s); 6 | } 7 | export func work calloc(el_size: size_t, el_num: size_t) *void { 8 | return cast(*void)$calloc(el_size, el_num); 9 | } 10 | export func work free(ptr: *void) { 11 | $free(ptr); 12 | } -------------------------------------------------------------------------------- /lib/internal/async.h: -------------------------------------------------------------------------------- 1 | #ifndef VO_INTERNAL_ASYNC 2 | #define VO_INTERNAL_ASYNC 3 | 4 | #define VO_ASYNC_START_CONTEXT() a_ctx_t *a_ctx = (a_ctx_t*)(check->data); switch(a_ctx->state){ case 0:; 5 | #define VO_AWAIT(promise, state1) ({ ctx->prom[state1-1] = promise; a_ctx->state++; case state1: if(a_ctx->prom[state1-1]->state == PENDING) return; a_ctx->prom[state1-1]->val; }) 6 | #define VO_RETURN_ASYNC(value) RESOLVE_PROM(ctx->return_promise, value); uv_idle_stop(check); free(check); free(a_ctx); return; 7 | #define VO_ASYNC_VAR(var) a_ctx->v_##var 8 | #define VO_ASYNC_END_CONTEXT() a_ctx->return_promise->state = COMPLETED; uv_idle_stop(check); free(check); free(a_ctx); return; } 9 | 10 | #endif -------------------------------------------------------------------------------- /lib/internal/default.h: -------------------------------------------------------------------------------- 1 | #ifndef VO_DEFAULT 2 | #define VO_DEFAULT 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "types.h" 9 | 10 | void _memcpy(void *dest, void *src, size_t size) { 11 | char *l = (char *)dest; 12 | char *r = (char *)src; 13 | for(size_t i = 0; i < size; ++i){ 14 | l[i] = r[i]; 15 | } 16 | } 17 | 18 | #ifndef VO_NO_HEAP 19 | # include "heap.h" 20 | # include "vector.h" 21 | # include "promise.h" 22 | 23 | # define new(type, size_type) (type *)malloc(sizeof(size_type)) 24 | # define new2(type, size_type, val) (type *)({type *ptr = malloc(sizeof(size_type)); *ptr = (type)val; ptr;}) 25 | # define new3(type, size_type, val) (type *)({type *ptr = malloc(sizeof(size_type)); _memcpy(ptr, val, sizeof(size_type)); ptr;}) 26 | # define new4(type, val, size) ({ VECTOR_TYPE(type) vector = VECTOR_NEW(type); VECTOR_COPY(vector, (char *)val, size); (void *)vector; }) 27 | # define new5(type) PROMISE_NEW(type) 28 | 29 | # define delete(block) free(block); 30 | #endif 31 | 32 | #ifndef VO_NO_BLOCKSRUNTIME 33 | # include "Block.h" 34 | #else 35 | void * _NSConcreteStackBlock[32] = { 0 }; 36 | void * _NSConcreteMallocBlock[32] = { 0 }; 37 | void * _NSConcreteAutoBlock[32] = { 0 }; 38 | void * _NSConcreteFinalizingBlock[32] = { 0 }; 39 | void * _NSConcreteGlobalBlock[32] = { 0 }; 40 | void * _NSConcreteWeakBlockVariable[32] = { 0 }; 41 | #endif 42 | 43 | #endif -------------------------------------------------------------------------------- /lib/internal/heap.h: -------------------------------------------------------------------------------- 1 | #ifndef VO_INTERNAL_HEAP 2 | #define VO_INTERNAL_HEAP 3 | 4 | #ifndef VO_NO_GC 5 | # include "gc.h" 6 | # define malloc(size) GC_malloc(size) 7 | # define realloc(ptr, size) GC_realloc(ptr, size) 8 | # define calloc(size1, size2) GC_malloc(size1*size2) 9 | # define free(ptr) GC_free(ptr) 10 | #else 11 | # include 12 | #endif 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /lib/internal/promise.h: -------------------------------------------------------------------------------- 1 | #ifndef VO_INTERNAL_PROMISE 2 | #define VO_INTERNAL_PROMISE 3 | 4 | #include "heap.h" 5 | #include "vector.h" 6 | 7 | #define PROMISE_TYPE(type) \ 8 | struct { \ 9 | u8 state; \ 10 | VECTOR_TYPE(void *) listeners; \ 11 | type val; \ 12 | } * 13 | 14 | #define PROMISE_NEW(type) (void *)({PROMISE_TYPE(type) prom = malloc(sizeof(PROMISE_TYPE(type))); prom->listeners = VECTOR_NEW(void *); prom->state = 0; prom; }) 15 | #define PROMISE_THEN(promise, callback) VECTOR_PUSH(promise->listeners, (void *)callback) 16 | #define PROMISE_RESOLVE(promise, value) ({ promise->val = value; promise->state = 1; VECTOR_FOREACH(promise->listeners, ({ ((void (^)(typeof(promise->val)))it)(promise->val); })); }) 17 | 18 | #endif -------------------------------------------------------------------------------- /lib/internal/types.h: -------------------------------------------------------------------------------- 1 | #ifndef VO_INTERNAL_TYPES 2 | #define VO_INTERNAL_TYPES 3 | 4 | typedef unsigned char u8; 5 | typedef unsigned short u16; 6 | typedef unsigned int u32; 7 | typedef unsigned long long u64; 8 | 9 | typedef char i8; 10 | typedef short i16; 11 | typedef int i32; 12 | typedef long long i64; 13 | 14 | typedef float f32; 15 | typedef double f64; 16 | 17 | typedef u64 uptr; 18 | typedef u8 bool; 19 | 20 | #define true 1 21 | #define false 0 22 | #define null ((void *)0) 23 | #endif -------------------------------------------------------------------------------- /lib/internal/vector.h: -------------------------------------------------------------------------------- 1 | #ifndef VO_INTERNAL_VECTOR 2 | #define VO_INTERNAL_VECTOR 3 | 4 | #include "heap.h" 5 | 6 | typedef struct VectorLayout { 7 | bool is_owner; 8 | size_t length; 9 | size_t capacity; 10 | char *mem; 11 | } VectorLayout; 12 | 13 | VectorLayout *_vector_new(size_t); 14 | VectorLayout *_vector_copy(VectorLayout *, char *, size_t, size_t); 15 | VectorLayout *_vector_resize(VectorLayout *, size_t, size_t); 16 | VectorLayout *_vector_concat(VectorLayout *, VectorLayout *, size_t); 17 | VectorLayout *_vector_slice(VectorLayout *, size_t, size_t, size_t); 18 | void _vector_free(VectorLayout *); 19 | 20 | #define VECTOR_TYPE(type) \ 21 | struct { \ 22 | bool is_owner; \ 23 | size_t length; \ 24 | size_t capacity; \ 25 | type *mem; \ 26 | } * 27 | 28 | #define VECTOR_NEW(type) ((void *)_vector_new(sizeof(type))) 29 | #define VECTOR_RESIZE(vector, num) ((void *)_vector_resize((VectorLayout*)vector, sizeof(VectorLayout) + (num + vector->capacity), sizeof(*vector->mem))) 30 | #define VECTOR_COPY(vector, val, len) ((void *)_vector_copy((VectorLayout *)vector, val, len, sizeof(*vector->mem))) 31 | #define VECTOR_RAW(vector) (vector->mem) 32 | 33 | #define VECTOR_PUSH(vector, value) \ 34 | ({ if(vector->length == vector->capacity){ \ 35 | VECTOR_RESIZE(vector, 8); \ 36 | } \ 37 | vector->mem[vector->length++] = value; }) 38 | 39 | #define VECTOR_APPEND(vector, ptr, length) ((void *)_vector_append((VectorLayout *)vector, (char *)ptr, length, sizeof(*vector->mem))) 40 | #define VECTOR_POP(vector) (vector->mem[--vector->length]) 41 | #define VECTOR_CONCAT(vector1, vector2) ((void *)_vector_concat((VectorLayout *)vector1, (VectorLayout *)vector2, sizeof(*vector1->mem))) 42 | #define VECTOR_FREE(vector) (_vector_free((VectorLayout *)vector)) 43 | #define VECTOR_CLONE(vector) ((void *)_vector_clone((VectorLayout *)vector, sizeof(*vector->mem))) 44 | #define VECTOR_SLICE(vector, start, len) ((void *)_vector_slice((VectorLayout *)vector, start, len, sizeof(*vector->mem))) 45 | 46 | #define VECTOR_FOREACH(vector, block) \ 47 | for(size_t i = 0; i < vector->length; ++i){ \ 48 | typeof(vector->mem[0]) it = vector->mem[i]; \ 49 | block; \ 50 | } 51 | 52 | VectorLayout *_vector_new(size_t size_of_each_element){ 53 | VectorLayout *vector = malloc(sizeof(VectorLayout)); 54 | vector->mem = malloc(size_of_each_element*8); 55 | vector->length = 0; 56 | vector->capacity = 8; 57 | vector->is_owner = true; 58 | return vector; 59 | } 60 | 61 | VectorLayout *_vector_copy(VectorLayout *vec, char *mem, size_t len, size_t el_size) { 62 | if(vec->capacity < len){ 63 | _vector_resize(vec, len, el_size); 64 | } 65 | size_t size = len*el_size; 66 | for(size_t i = 0; i < size; ++i) { 67 | vec->mem[i] = mem[i]; 68 | } 69 | vec->length = len; 70 | return vec; 71 | } 72 | 73 | VectorLayout *_vector_resize(VectorLayout *vector, size_t new_length, size_t el_size){ 74 | char *temp = (char *)vector->mem; 75 | vector->capacity = new_length; 76 | vector->mem = malloc(new_length*el_size); 77 | 78 | _memcpy(vector->mem, temp, vector->length*el_size); 79 | 80 | if(vector->is_owner){ 81 | free(temp); 82 | } 83 | return vector; 84 | } 85 | 86 | VectorLayout *_vector_concat(VectorLayout *first, VectorLayout *second, size_t el_size) { 87 | size_t newLength = first->length + second->length; 88 | if(first->capacity < newLength){ 89 | _vector_resize(first, newLength, el_size); 90 | } 91 | size_t size1 = first->length*el_size; 92 | size_t size2 = second->length*el_size; 93 | 94 | for(size_t i = 0; i < size2; ++i) { 95 | first->mem[i+size1] = second->mem[i]; 96 | } 97 | first->length = newLength; 98 | return first; 99 | } 100 | 101 | VectorLayout *_vector_append(VectorLayout *vector, char *mem, size_t size, size_t el_size) { 102 | size_t newSize = vector->length + size; 103 | if(vector->capacity < newSize){ 104 | _vector_resize(vector, newSize + (8*el_size), el_size); 105 | } 106 | size_t size1 = vector->length*el_size; 107 | 108 | for(size_t i = 0; i < size; ++i) { 109 | vector->mem[i+size1] = *(mem+i); 110 | } 111 | vector->length = newSize; 112 | return vector; 113 | } 114 | 115 | VectorLayout *_vector_clone(VectorLayout *vec, size_t el_size) { 116 | VectorLayout *newVec = _vector_new(el_size); 117 | return _vector_copy(newVec, vec->mem, vec->length, el_size); 118 | } 119 | 120 | VectorLayout *_vector_slice(VectorLayout *vec, size_t start, size_t length, size_t el_size){ 121 | VectorLayout *newVec = malloc(sizeof(VectorLayout)); 122 | newVec->mem = vec->mem+(start*el_size); 123 | newVec->is_owner = false; 124 | newVec->length = length; 125 | newVec->capacity = vec->capacity-start; 126 | return newVec; 127 | } 128 | 129 | void _vector_free(VectorLayout *vector) { 130 | free(vector->mem); 131 | free(vector); 132 | } 133 | 134 | #endif -------------------------------------------------------------------------------- /lib/io.vo: -------------------------------------------------------------------------------- 1 | export func work printChar(char: i8){ 2 | $putchar(char); 3 | }; 4 | 5 | export func work getChar() i8 { 6 | return cast(i8)$getchar(); 7 | }; 8 | 9 | export func work print(buf: *i8){ 10 | c := buf[0]; 11 | for i: size_t = 1; c != 0; ++i { 12 | printChar(c); 13 | c = buf[i]; 14 | } 15 | }; 16 | 17 | export func work printn(buf: *i8, n: size_t){ 18 | for i: size_t = 0; i < n; ++i { 19 | printChar(*(buf++)); 20 | } 21 | }; 22 | 23 | export func work printnln(buf: *i8, n: size_t){ 24 | printn(buf, n); 25 | printChar('\n'); 26 | }; 27 | 28 | export func work println(buf: *i8){ 29 | print(buf); 30 | printChar('\n'); 31 | }; 32 | 33 | export func work scan() *void { 34 | str := (vec u8){}; 35 | for char := getChar(); char != '\n'; char = getChar() { 36 | str.push(char); 37 | } 38 | return cast(*void)str; 39 | }; 40 | -------------------------------------------------------------------------------- /lib/math.vo: -------------------------------------------------------------------------------- 1 | 2 | export func powi64(base: i64, exp: i64) i64 { 3 | result: i64 = 1; 4 | for { 5 | if exp & 1 { 6 | result *= base; 7 | } 8 | exp = exp >> 1; 9 | if !exp { 10 | break; 11 | } 12 | base *= base; 13 | } 14 | return result; 15 | }; 16 | 17 | export func powu32(base: u32, exp: u32) u32 { 18 | result: u32 = 1; 19 | for { 20 | if exp & 1 { 21 | result *= base; 22 | } 23 | exp = exp >> 1; 24 | if !exp { 25 | break; 26 | } 27 | base *= base; 28 | } 29 | return result; 30 | }; -------------------------------------------------------------------------------- /lib/mem.vo: -------------------------------------------------------------------------------- 1 | export func work copy(dest: *void, src: *void, length: size_t) { 2 | l, r := cast(*u8)dest, cast(*u8)src; 3 | for i: size_t = 0; i < length; l[i], i = r[i], i+1 {} 4 | }; 5 | 6 | export func work compare(first: *void, second: *void, length: size_t) i8 { 7 | l, r := cast(*i8)first, cast(*i8)second; 8 | for length-- != 0 && *l++ == *r++ {} 9 | return length != -1 ? *--l-*--r : 0; 10 | }; 11 | 12 | export func work set(ptr: *void, char: u8, length: size_t) { 13 | l := cast(*u8)ptr; 14 | for i: size_t = 0; i < length; l[i++] = char {} 15 | }; 16 | -------------------------------------------------------------------------------- /lib/num.vo: -------------------------------------------------------------------------------- 1 | import "io.vo"; 2 | 3 | export func revstr(str: *u8, len: size_t, temp: *u8) { 4 | i := len - 1; 5 | for ci: size_t = 0; ci < len; ci++ { 6 | temp[ci] = str[i--]; 7 | } 8 | for i = 0; i < len; i++ { 9 | str[i] = temp[i]; 10 | } 11 | }; 12 | 13 | export func itos(num: i32, buf: *u8) { 14 | i: u32 = 0; 15 | if num < 0 { 16 | *(buf++) = '-'; 17 | } 18 | for ; num > 1; i++ { 19 | buf[i] = num % 10 + '0'; 20 | num /= 10; 21 | } 22 | arr: [20]u8; 23 | revstr(buf, i, arr); 24 | }; 25 | 26 | export func utos(num: u32, buf: *u8) size_t { 27 | i: size_t; 28 | for i = 0; num >= 1; i++ { 29 | buf[i] = num % 10 + '0'; 30 | num /= 10; 31 | } 32 | if i == 0 { 33 | buf[0] = '0'; 34 | buf[1] = 0; 35 | return 1; 36 | } 37 | 38 | buf[i] = 0; 39 | arr: [10]u8; 40 | revstr(buf, i, arr); 41 | 42 | return i; 43 | }; -------------------------------------------------------------------------------- /lib/path.vo: -------------------------------------------------------------------------------- 1 | import "io.vo"; 2 | import "num.vo"; 3 | import "mem.vo"; 4 | import "string.vo"; 5 | import "vector.vo"; 6 | 7 | dotDotSlash := (string.String){mem: "../", length: 3}; 8 | dotSlash := (string.String){mem: "./", length: 2}; 9 | 10 | dotDot := (string.String){mem: "..", length: 2}; 11 | 12 | func print(str: string.String) { 13 | len: [10]u8; 14 | num.utos(str.length, len); 15 | io.print("Length: "); 16 | io.print(len); 17 | io.print(" Buff: "); 18 | io.println(str.raw()); 19 | }; 20 | 21 | export func normalizeVec(pathsv: *void) *void { 22 | paths := cast(vec string.String)pathsv; 23 | last := (vec string.String){}; 24 | curr: string.String; 25 | 26 | for i: size_t = 0; i < paths.length; ++i { 27 | curr = paths[i]; 28 | if curr.compare(dotDot) && last.length > 0 { 29 | last.pop(); 30 | } else if !(curr.length == 1 && curr.get(0) == '.') && curr.length != 1 { 31 | last.push(curr); 32 | } 33 | } 34 | 35 | paths.free(); 36 | return cast(*void)last; 37 | }; 38 | 39 | export func normalize(path: string.String) string.String { 40 | p := path.split('/'); 41 | x := cast(vec string.String)normalizeVec(p); 42 | y := string.join(x, '/'); 43 | 44 | p.free(); 45 | x.free(); 46 | 47 | return y; 48 | }; 49 | 50 | export func join(pathsv: *void) string.String { 51 | paths := cast(vec string.String)pathsv; 52 | path := string.from("", 0); 53 | 54 | last := (vec string.String){}; 55 | curr: string.String; 56 | 57 | for i: size_t = 0; i < paths.length; ++i { 58 | curr = paths[i]; 59 | for { 60 | if curr.get(0) == '/' { 61 | curr = curr.slice(1, curr.length); 62 | } else if curr.startsWith(dotDotSlash) { 63 | last.pop(); 64 | curr = curr.slice(3, curr.length); 65 | } else if curr.startsWith(dotSlash) { 66 | curr = curr.slice(2, curr.length); 67 | } else { 68 | break; 69 | } 70 | } 71 | if curr.length == 0 { 72 | continue; 73 | } 74 | if curr.get(curr.length-1) == '/' { 75 | curr = curr.slice(0, curr.length-1); 76 | } 77 | t := curr.split('/'); 78 | last.concat(t); 79 | t.free(); 80 | } 81 | path = string.join(last, '/'); 82 | last.free(); 83 | 84 | return path; 85 | }; 86 | 87 | export func relative(from: string.String, to: string.String) string.String { 88 | if to.get(0) == '/' { 89 | return normalize(to); 90 | } 91 | a, b, c := from.split('/'), to.split('/'), (vec string.String){}; 92 | 93 | for i: size_t = 0; i < b.length; ++i { 94 | if b[i].compare(dotDot) { 95 | a.pop(); 96 | } else if a.length == 0 || !b[i].compare(a[a.length - 1]) { 97 | break; 98 | } else { 99 | c.push(b[i]); 100 | } 101 | } 102 | x := a.concat(c); 103 | a.free(); 104 | b.free(); 105 | c.free(); 106 | 107 | y := cast(vec string.String)normalizeVec(x); 108 | x.free(); 109 | 110 | z := string.join(y, '/'); 111 | y.free(); 112 | 113 | return z; 114 | }; -------------------------------------------------------------------------------- /lib/string.vo: -------------------------------------------------------------------------------- 1 | import "io.vo"; 2 | import "mem.vo"; 3 | import "heap.vo"; 4 | 5 | export func from(buff: *u8, length: size_t) String { 6 | return (String){mem: buff, length: length}; 7 | }; 8 | 9 | export func alloc(length: size_t) String { 10 | return (String){length: length, mem: heap.malloc(length * sizeof(u8))}; 11 | }; 12 | 13 | export func join(strsv: *void, sep: u8) String { 14 | strs := cast(vec String)strsv; 15 | size := (strs.length-1); 16 | for i := 0; i < strs.length; ++i { 17 | size += strs[i].length; 18 | } 19 | str := alloc(size); 20 | b := str.mem; 21 | 22 | st := strs[0]; 23 | mem.copy(b, st.mem, st.length); 24 | b += st.length; 25 | 26 | for i := 1; i < strs.length; ++i { 27 | *(b++) = sep; 28 | st = strs[i]; 29 | mem.copy(b, st.mem, st.length); 30 | b += st.length; 31 | } 32 | return str; 33 | }; 34 | 35 | export func joinStr(strsv: *void, sep: String) String { 36 | strs := cast(vec String)strsv; 37 | m, l := sep.mem, sep.length; 38 | size := (strs.length-1)*sep.length; 39 | for i := 0; i < strs.length; ++i { 40 | size += strs[i].length; 41 | } 42 | str := alloc(size); 43 | s := 0; 44 | for i := 0; i < strs.length; ++i { 45 | st := strs[i]; 46 | mem.copy(str.mem+s, st.mem, st.length); 47 | s += st.length; 48 | mem.copy(str.mem+s, m, l); 49 | s += l; 50 | } 51 | return str; 52 | }; 53 | 54 | export struct String { 55 | mem: *u8; 56 | length: size_t; 57 | func raw(self: *String) *u8 { 58 | return self.mem; 59 | }; 60 | func get(self: *String, index: size_t) u8 { 61 | return self.mem[index]; 62 | }; 63 | func set(self: *String, index: size_t, value: u8) { 64 | self.mem[index] = value; 65 | }; 66 | func fill(self: *String, char: u8) { 67 | mem.set(self.mem, char, self.length); 68 | }; 69 | func compare(self: *String, str: String) i8 { 70 | return self.length == str.length ? mem.compare(self.mem, str.mem, self.length) : (self.length > str.length ? 1 : -1); 71 | }; 72 | func startsWith(self: *String, str: String) bool { 73 | return self.length > str.length ? mem.compare(self.mem, str.mem, str.length) == 0 : false; 74 | }; 75 | func endsWith(self: *String, str: String) bool { 76 | return self.length > str.length ? mem.compare((self.mem + self.length) - str.length, str.mem, str.length) == 0 : false; 77 | }; 78 | func clone(self: *String) String { 79 | str := alloc(self.length); 80 | mem.copy(str.mem, self.mem, self.length); 81 | return str; 82 | }; 83 | func slice(self: *String, start: size_t, end: size_t) String { 84 | str := (String){}; 85 | str.mem = self.mem + start; 86 | str.length = end - start; 87 | return str; 88 | }; 89 | func append(self: *String, char: u8) String { 90 | l := self.length; 91 | str := alloc(l+1); 92 | mem.copy(str.mem, self.mem, l); 93 | str.mem[l] = char; 94 | return str; 95 | }; 96 | func concat(str1: *String, str2: String) String { 97 | length := str1.length + str2.length; 98 | str := alloc(length); 99 | mem.copy(str.mem, str1.mem, str1.length); 100 | mem.copy(str.mem + str1.length, str2.mem, str2.length); 101 | return str; 102 | }; 103 | func repeat(self: *String, num: size_t) String { 104 | oldlength := self.length; 105 | length := num*oldlength; 106 | str := alloc(length); 107 | for i := 0; i < num; ++i { 108 | mem.copy(str.mem + i*(oldlength), self.mem, oldlength); 109 | } 110 | return str; 111 | }; 112 | func insert(self: *String, index: size_t, char: u8) String { 113 | str := alloc(self.length+1); 114 | str.mem[index] = char; 115 | mem.copy(str.mem, self.mem, index); 116 | mem.copy(str.mem + index + 1, self.mem + index, self.length - index); 117 | return str; 118 | }; 119 | func insertStr(self: *String, index: size_t, str2: String) String { 120 | str := alloc(self.length+str2.length); 121 | mem.copy(str.mem, self.mem, index); 122 | mem.copy(str.mem + index, str2.mem, str2.length); 123 | mem.copy(str.mem + index + str2.length, self.mem + index, self.length - index); 124 | return str; 125 | }; 126 | func search(self: *String, char: u8) size_t { 127 | i: size_t = 0; 128 | for ; self.mem[i] != char && i < self.length; ++i {} 129 | return i; 130 | }; 131 | func searchStr(self: *String, str: String) size_t { 132 | if self.length < str.length { 133 | return self.length; 134 | } 135 | i, n: size_t = 0, self.length - str.length + 1; 136 | for ; mem.compare(self.mem + i, str.mem, str.length) ! = 0 && i < n; ++i {} 137 | return i; 138 | }; 139 | func split(self: *String, sep: u8) vec String { 140 | s := *self; 141 | strs := (vec String){}; 142 | 143 | for i := s.search(sep); i != s.length; i = s.search(sep) { 144 | strs.push(s.slice(0, i)); 145 | s = s.slice(i+1, s.length); 146 | } 147 | strs.push(s); 148 | return strs; 149 | }; 150 | func splitStr(self: *String, sep: String) vec String { 151 | s, l := *self, sep.length; 152 | strs := (vec String){}; 153 | for i := s.searchStr(sep); i != s.length; i = s.searchStr(sep) { 154 | strs.push(s.slice(0, i)); 155 | s = s.slice(i+l, s.length); 156 | } 157 | strs.push(s); 158 | return strs; 159 | }; 160 | func free(self: *String) { 161 | heap.free(self.mem); 162 | }; 163 | }; -------------------------------------------------------------------------------- /lib/uv/libuv.h: -------------------------------------------------------------------------------- 1 | #ifndef VO_LUV 2 | #define VO_LUV 3 | 4 | #include "uv.h" 5 | 6 | typedef struct sockaddr_in sockaddr_in; 7 | 8 | typedef union uv_any_handle uv_any_handle; 9 | typedef union uv_any_req uv_any_req; 10 | 11 | struct Data { 12 | void *self; 13 | void *internal; 14 | void *user; 15 | }; 16 | 17 | struct StreamData { 18 | void (^read_cb)(void *, ssize_t, void *); 19 | void (^write_cb)(void *, int); 20 | void (^connect_cb)(void *, int); 21 | void (^shutdown_cb)(void *, int); 22 | void (^connection_cb)(void *, int); 23 | }; 24 | 25 | void vo_uv_alloc_cb(uv_handle_t *hanlde, size_t suggested_size, uv_buf_t *buf){ 26 | buf->base = (char *)malloc(suggested_size); 27 | buf->len = suggested_size; 28 | }; 29 | 30 | void vo_uv_close_cb(uv_handle_t *handle) { 31 | struct Data *data = (struct Data *)uv_handle_get_data(handle); 32 | ((void (^)(void *))data->internal)(data->self); 33 | }; 34 | 35 | void vo_uv_timer_cb(uv_timer_t *timer){ 36 | struct Data *data = (struct Data *)uv_handle_get_data((uv_handle_t *)timer); 37 | ((void (^)(void *))data->internal)(data->self); 38 | }; 39 | 40 | void vo_uv_check_cb(uv_check_t *check) { 41 | struct Data *data = (struct Data *)uv_handle_get_data((uv_handle_t *)check); 42 | ((void (^)(void *))data->internal)(data->self); 43 | }; 44 | 45 | void vo_uv_prepare_cb(uv_prepare_t *prepare) { 46 | struct Data *data = (struct Data *)uv_handle_get_data((uv_handle_t *)prepare); 47 | ((void (^)(void *))data->internal)(data->self); 48 | }; 49 | 50 | void vo_uv_idle_cb(uv_idle_t *idle) { 51 | struct Data *data = (struct Data *)uv_handle_get_data((uv_handle_t *)idle); 52 | ((void (^)(void *))data->internal)(data->self); 53 | }; 54 | 55 | void vo_uv_async_cb(uv_async_t *async) { 56 | struct Data *data = (struct Data *)uv_handle_get_data((uv_handle_t *)async); 57 | ((void (^)(void *))data->internal)(data->self); 58 | }; 59 | 60 | void vo_uv_process_exit_cb(uv_process_t *process) { 61 | struct Data *data = (struct Data *)uv_handle_get_data((uv_handle_t *)process); 62 | ((void (^)(void *))data->internal)(data->self); 63 | }; 64 | 65 | void vo_uv_signal_cb(uv_signal_t *handle, int signal) { 66 | struct Data *data = (struct Data *)uv_handle_get_data((uv_handle_t *)handle); 67 | ((void (^)(void *, int))data->internal)(data->self, signal); 68 | }; 69 | 70 | void vo_uv_read_cb(uv_stream_t *stream, ssize_t nread, const uv_buf_t* buf){ 71 | struct Data *data = (struct Data *)uv_handle_get_data((uv_handle_t *)stream); 72 | ((void (^)(void *, ssize_t, const uv_buf_t *))data->internal)(data->self, nread, buf); 73 | }; 74 | 75 | void vo_uv_write_cb(uv_write_t *req, int status){ 76 | struct Data *data = (struct Data *)uv_req_get_data((uv_req_t *)req); 77 | ((void (^)(void *, int))data->internal)(data->self, status); 78 | }; 79 | 80 | void vo_uv_shutdown_cb(uv_shutdown_t *req, int status){ 81 | struct Data *data = (struct Data *)uv_req_get_data((uv_req_t *)req); 82 | ((void (^)(void *, int))data->internal)(data->self, status); 83 | }; 84 | 85 | void vo_uv_connect_cb(uv_connect_t *req, int status){ 86 | struct Data *data = (struct Data *)uv_req_get_data((uv_req_t *)req); 87 | ((void (^)(void *, int))data->internal)(data->self, status); 88 | }; 89 | 90 | void vo_uv_connection_cb(uv_stream_t *stream, int status){ 91 | struct Data *data = (struct Data *)uv_handle_get_data((uv_handle_t *)stream); 92 | ((void (^)(void *, int))data->internal)(data->self, status); 93 | }; 94 | 95 | #endif -------------------------------------------------------------------------------- /lib/uv/uv.vo: -------------------------------------------------------------------------------- 1 | 2 | export struct SockAddr { 3 | sa_family: $sa_family_t; 4 | sa_data: [14]i8; 5 | }; 6 | 7 | import "libuv.h"; 8 | 9 | // Loop 10 | export enum RunMode { 11 | Default = 0, 12 | Once, 13 | NoWait 14 | }; 15 | 16 | export enum LoopOption { 17 | BlockSignal = 0 18 | }; 19 | 20 | export struct Loop { 21 | __loop: $uv_loop_t; 22 | 23 | func init(self: *Loop) { 24 | $uv_loop_init(&self.__loop); 25 | $uv_loop_set_data(&self.__loop, cast(*void)self); 26 | }; 27 | func close(self: *Loop) { 28 | $uv_loop_close(&self.__loop); 29 | }; 30 | func configure(self: *Loop, option: LoopOption) { 31 | $uv_loop_configure(&self.__loop, cast($uv_loop_option)option); 32 | }; 33 | func run(self: *Loop, mode: RunMode) i32 { 34 | return cast(i32)$uv_run(&self.__loop, cast($uv_run_mode)mode); 35 | }; 36 | func stop(self: *Loop) { 37 | $uv_stop(&self.__loop); 38 | }; 39 | func now(self: *Loop) u64 { 40 | return $uv_now(&self.__loop); 41 | }; 42 | func updateTime(self: *Loop){ 43 | $uv_update_time(&self.__loop); 44 | }; 45 | }; 46 | 47 | export func getDefaultLoop() *Loop { 48 | return cast(*Loop)$uv_default_loop(); // cast works cuz they have same size 49 | }; 50 | 51 | // Handle 52 | export enum HandleType { 53 | UnknownHandle = 0, 54 | Async, 55 | Check, 56 | FsEvent, 57 | FsPoll, 58 | Handle, 59 | Idle, 60 | NamedPipe, 61 | Poll, 62 | Prepare, 63 | Process, 64 | Stream, 65 | Tcp, 66 | Timer, 67 | Tty, 68 | Udp, 69 | Signal, 70 | File, 71 | HandleTypeMax 72 | }; 73 | 74 | export struct Buf { 75 | base: *u8; 76 | len: size_t; 77 | }; 78 | 79 | export struct Data { 80 | self: *void; 81 | internal: *void; 82 | user: *void; 83 | }; 84 | 85 | union _AnyHandle { 86 | handle: $uv_handle_t; 87 | stream: $uv_stream_t; 88 | process: $uv_process_t; 89 | signal: $uv_signal_t; 90 | tcp: $uv_tcp_t; 91 | pipe: $uv_pipe_t; 92 | prepare: $uv_prepare_t; 93 | check: $uv_check_t; 94 | idle: $uv_idle_t; 95 | async_: $uv_async_t; 96 | timer: $uv_timer_t; 97 | getaddrinfo: $uv_getaddrinfo_t; 98 | fs_event: $uv_fs_event_t; 99 | }; 100 | 101 | export struct Handle { 102 | loop: *Loop; 103 | __handle: _AnyHandle; 104 | _data: Data; 105 | 106 | func _init(self: *Handle) { 107 | self._data.self = cast(*void)self; 108 | $uv_handle_set_data(&self.__handle.handle, &self._data); 109 | }; 110 | func _setInternalData(self: *Handle, data: *void) { 111 | self._data.internal = data; 112 | }; 113 | func _getInternalData(self: *Handle) *void { 114 | return self._data.internal; 115 | }; 116 | func _setUserData(self: *Handle, data: *void) { 117 | self._data.user = data; 118 | }; 119 | func _getUserData(self: *Handle) *void { 120 | return self._data.user; 121 | }; 122 | func isActive(self: *Handle) bool { 123 | return $uv_is_active(&self.__handle.handle) != 0; 124 | }; 125 | func isClosing(self: *Handle) bool { 126 | return $uv_is_closing(&self.__handle.handle) != 0; 127 | }; 128 | func close(self: *Handle, cb: func(*Handle)) { 129 | if !self.isClosing() { 130 | self._setInternalData(cast(*void)cb); 131 | $uv_close(&self.__handle.handle, cast($uv_close_cb)$vo_uv_close_cb); 132 | } 133 | }; 134 | func ref(self: *Handle) { 135 | $uv_ref(&self.__handle.handle); 136 | }; 137 | func unref(self: *Handle) { 138 | $uv_unref(&self.__handle.handle); 139 | }; 140 | func setData(self: *Handle, data: *void) { 141 | self._setUserData(data); 142 | }; 143 | func getData(self: *Handle) *void { 144 | return self._getUserData(); 145 | }; 146 | }; 147 | 148 | // Timer 149 | export struct Timer { 150 | ..Handle; 151 | 152 | func init(self: *Timer, loop: *Loop){ 153 | self.loop = loop; 154 | $uv_timer_init(&loop.__loop, &self.__handle.timer); 155 | self._init(); 156 | }; 157 | func start(self: *Timer, cb: func(*Timer), timeout: u64, repeat: u64) { 158 | self._setInternalData(cast(*void)cb); 159 | $uv_timer_start(&self.__handle.timer, cast($uv_timer_cb)$vo_uv_timer_cb, timeout, repeat); 160 | }; 161 | func again(self: *Timer) { 162 | $uv_timer_again(&self.__handle.timer); 163 | }; 164 | func setRepeat(self: *Timer, repeat: u64) { 165 | $uv_timer_set_repeat(&self.__handle.timer, repeat); 166 | }; 167 | func getRepeat(self: *Timer) u64 { 168 | return cast(u64)$uv_timer_get_repeat(&self.__handle.timer); 169 | }; 170 | func stop(self: *Timer) { 171 | $uv_timer_stop(&self.__handle.timer); 172 | }; 173 | }; 174 | 175 | // Prepare 176 | export struct Prepare { 177 | ..Handle; 178 | 179 | func init(self: *Prepare, loop: *Loop){ 180 | self.loop = loop; 181 | $uv_prepare_init(&loop.__loop, &self.__handle.prepare); 182 | self._init(); 183 | }; 184 | func start(self: *Prepare, callback: func(*Prepare)) i32 { 185 | self._setInternalData(cast(*void)callback); 186 | return cast(i32)$uv_prepare_start(&self.__handle.prepare, cast($uv_prepare_cb)$vo_uv_prepare_cb); 187 | }; 188 | func stop(self: *Prepare){ 189 | $uv_prepare_stop(&self.__handle.prepare); 190 | }; 191 | }; 192 | 193 | // Idle 194 | export struct Idle { 195 | ..Handle; 196 | 197 | func init(self: *Idle, loop: *Loop){ 198 | self.loop = loop; 199 | $uv_idle_init(&loop.__loop, cast(*$uv_idle_t)&self.__handle); 200 | self._init(); 201 | }; 202 | func start(self: *Idle, callback: func(*Idle)) i32 { 203 | self._setInternalData(cast(*void)callback); 204 | return cast(i32)$uv_idle_start(&self.__handle.idle, cast($uv_idle_cb)$vo_uv_idle_cb); 205 | }; 206 | func stop(self: *Idle){ 207 | $uv_idle_stop(&self.__handle.idle); 208 | }; 209 | }; 210 | 211 | // Check 212 | export struct Check { 213 | ..Handle; 214 | 215 | func init(self: *Check, loop: *Loop){ 216 | self.loop = loop; 217 | $uv_check_init(&loop.__loop, &self.__handle.check); 218 | self._init(); 219 | }; 220 | func start(self: *Check, cb: *func(*Check)) i32 { 221 | self._setInternalData(cast(*void)cb); 222 | return cast(i32)$uv_check_start(&self.__handle.check, cast($uv_check_cb)$vo_uv_check_cb); 223 | }; 224 | func stop(self: *Check){ 225 | $uv_check_stop(&self.__handle.check); 226 | }; 227 | }; 228 | 229 | // Async 230 | export struct Async { 231 | ..Handle; 232 | 233 | func init(self: *Async, loop: *Loop, cb: *func(*Async)) i32 { 234 | self.loop = loop; 235 | self._init(); 236 | self._setInternalData(cast(*void)cb); 237 | return $uv_async_init(&loop.__loop, &self.__handle.async_, cast($uv_async_cb)$vo_uv_async_cb); 238 | }; 239 | func send(self: *Check) i32 { 240 | return cast(i32)$uv_async_send(&self.__handle.async_); 241 | }; 242 | }; 243 | 244 | // Process 245 | export typedef PID $uv_pid_t; 246 | export typedef GID $uv_gid_t; 247 | export typedef UID $uv_uid_t; 248 | 249 | export enum ProcessFlags { 250 | SETUID = (1 << 0), 251 | SETGID = (1 << 1), 252 | WINDOWS_VERBATIM_ARGUMENTS = (1 << 2), 253 | DETACHED = (1 << 3), 254 | WINDOWS_HIDE = (1 << 4), 255 | WINDOWS_HIDE_CONSOLE = (1 << 5), 256 | WINDOWS_HIDE_GUI = (1 << 6) 257 | }; 258 | export enum StdioFlags { 259 | IGNORE = 0x00, 260 | CREATE_PIPE = 0x01, 261 | INHERIT_FD = 0x02, 262 | INHERIT_STREAM = 0x04, 263 | READABLE_PIPE = 0x10, 264 | WRITABLE_PIPE = 0x20 265 | }; 266 | 267 | export struct ProcessOptions { 268 | exitCallback: func (*Process, i64, i32); 269 | file: const *i8; 270 | args: **i8; 271 | env: **i8; 272 | cwd: const *i8; 273 | flags: u32; 274 | stdioCount: i32; 275 | stdio: *StdioContainer; 276 | uid: UID; 277 | gid: GID; 278 | }; 279 | 280 | union StdioContainerData { 281 | stream: *Stream; 282 | fd: i32; 283 | }; 284 | 285 | export struct StdioContainer { 286 | flags: StdioFlags; 287 | data: StdioContainerData; 288 | }; 289 | 290 | export struct Process { 291 | ..Handle; 292 | 293 | func init(self: *Process, loop: *Loop){ 294 | self.loop = loop; 295 | self._init(); 296 | }; 297 | func spawn(self: *Process, options: ProcessOptions) i32 { 298 | self._setInternalData(options.exitCallback); 299 | newOpts := new ProcessOptions(options); 300 | newOpts.exitCallback = cast(func (*Process, i64, i32))$vo_uv_process_exit_cb; 301 | return cast(i32)$uv_spawn(&self.loop.__loop, &self.__handle.process, cast(*$uv_process_options_t)newOpts); 302 | }; 303 | func kill(self: *Process, signum: i32) i32 { 304 | return cast(i32)$uv_process_kill(&self.__handle.process, signum); 305 | }; 306 | func getPid(self: *Process) PID { 307 | return cast(PID)$uv_process_get_pid(&self.__handle.process); 308 | }; 309 | }; 310 | 311 | export func kill(pid: i32, signum: i32) i32 { 312 | return cast(i32)$uv_kill(pid, signum); 313 | }; 314 | 315 | export func disableStdioInheritence() { 316 | $uv_disable_stdio_inheritance(); 317 | }; 318 | 319 | // Signal 320 | export struct Signal { 321 | ..Handle; 322 | 323 | func init(self: *Signal, loop: *Loop) { 324 | self.loop = loop; 325 | $uv_signal_init(&loop.__loop, &self.__handle.signal); 326 | self._init(); 327 | }; 328 | func start(self: *Signal, cb: func(*Signal, i32), signal: i32) i32 { 329 | self._setInternalData(cast(*void)cb); 330 | return cast(i32)$uv_signal_start(&self.__handle.signal, cast($uv_signal_cb)$vo_uv_signal_cb, signal); 331 | }; 332 | func startOneshot(self: *Signal, cb: func(*Signal, i32), signal: i32) i32 { 333 | self._setInternalData(cast(*void)cb); 334 | return cast(i32)$uv_signal_start_oneshot(&self.__handle.signal, cast($uv_signal_cb)$vo_uv_signal_cb, signal); 335 | }; 336 | }; 337 | 338 | // Req 339 | export enum ReqType { 340 | UnknownReq = 0, 341 | Req, 342 | Connect, 343 | Write, 344 | Shutdown, 345 | UdpSend, 346 | Fs, 347 | Work, 348 | GetAddrInfo, 349 | GetNameInfo, 350 | ReqTypeMax 351 | }; 352 | 353 | union _AnyReq { 354 | req: $uv_req_t; 355 | write: $uv_write_t; 356 | connect: $uv_connect_t; 357 | shutdown: $uv_shutdown_t; 358 | fsReq: $uv_fs_t; 359 | workReq: $uv_work_t; 360 | }; 361 | 362 | export struct Req { 363 | __req: _AnyReq; 364 | _data: Data; 365 | 366 | func init(self: *Req){ 367 | self._data.self = self; 368 | $uv_req_set_data(&self.__req.req, cast(*void)&self._data); 369 | }; 370 | func cancel(self: *Req) bool { 371 | return $uv_cancel(&self.__req.req) == 0; 372 | }; 373 | func setData(self: *Req, data: *void) { 374 | self._data.user = data; 375 | }; 376 | func getData(self: *Req) *void { 377 | return self._data.user; 378 | }; 379 | func _setInternalData(self: *Req, data: *void){ 380 | self._data.internal = data; 381 | }; 382 | func _getInternalData(self: *Req) *void { 383 | return self._data.internal; 384 | }; 385 | }; 386 | 387 | // Stream 388 | 389 | export struct ShutdownReq { 390 | ..Req; 391 | func getHandle(self: *ShutdownReq) *Stream { 392 | return cast(*Stream)(self.__req.shutdown.handle); 393 | }; 394 | }; 395 | 396 | export struct ConnectReq { 397 | ..Req; 398 | func getHandle(self: *ConnectReq) *Stream { 399 | return cast(*Stream)(self.__req.connect.handle); 400 | }; 401 | }; 402 | 403 | export struct WriteReq { 404 | ..Req; 405 | func getHandle(self: *WriteReq) *Stream { 406 | return cast(*Stream)(&self.__req.write.handle); 407 | }; 408 | func getSendHandle(self: *WriteReq) *Stream { 409 | return cast(*Stream)(&self.__req.write.send_handle); 410 | }; 411 | }; 412 | 413 | export struct Stream { 414 | ..Handle; 415 | 416 | func shutdown(self: *Stream, req: *ShutdownReq, cb: func(*ShutdownReq, i32)) i32 { 417 | req._setInternalData(cb); 418 | return cast(i32)$uv_shutdown(&req.__req.shutdown, &self.__handle.stream, cast($uv_shutdown_cb)$vo_uv_shutdown_cb); 419 | }; 420 | func listen(self: *Stream, backlog: i32, cb: func(*Stream, i32)) i32 { 421 | // data := cast(*StreamData)self._getInternalData(); 422 | // data.connectionCb = cb; 423 | self._setInternalData(cast(*void)cb); 424 | return cast(i32)$uv_listen(&self.__handle.stream, backlog, cast($uv_connection_cb)$vo_uv_connection_cb); 425 | }; 426 | func accept(self: *Stream, client: *Stream) i32 { 427 | return cast(i32)$uv_accept(&self.__handle.stream, cast(*$uv_stream_t)&client.__handle); 428 | }; 429 | func readStart(self: *Stream, cb: func(*Stream, i64, *Buf)) i32 { 430 | self._setInternalData(cb); 431 | return cast(i32)$uv_read_start(&self.__handle.stream, cast($uv_alloc_cb)$vo_uv_alloc_cb, cast($uv_read_cb)$vo_uv_read_cb); 432 | }; 433 | func readStop(self: *Stream) i32 { 434 | return cast(i32)$uv_read_stop(&self.__handle.stream); 435 | }; 436 | func write(self: *Stream, req: *WriteReq, bufs: []Buf, nbufs: size_t, cb: func(*WriteReq, i32)) i32 { 437 | if cb != null { 438 | req._setInternalData(cast(*void)cb); 439 | return cast(i32)$uv_write(&req.__req.write, &self.__handle.stream, bufs, nbufs, cast($uv_write_cb)$vo_uv_write_cb); 440 | } else { 441 | return cast(i32)$uv_write(&req.__req.write, &self.__handle.stream, bufs, nbufs, null); 442 | } 443 | }; 444 | func write2(self: *Stream, req: *WriteReq, bufs: []Buf, nbufs: size_t, sendHandle: *Stream, cb: func(*WriteReq, i32)) i32 { 445 | req._setInternalData(cast(*void)cb); 446 | return cast(i32)$uv_write2(&req.__req.write, &self.__handle.stream, bufs, nbufs, &sendHandle.__handle.stream, cast($uv_write_cb)$vo_uv_write_cb); 447 | }; 448 | func tryWrite(self: *Stream, req: *WriteReq, bufs: []Buf, nbufs: size_t) i32 { 449 | return cast(i32)$uv_try_write(&self.__handle.stream, bufs, nbufs); 450 | }; 451 | func isReadable(self: *Stream) bool { 452 | return cast(bool)$uv_is_readable(&self.__handle.stream); 453 | }; 454 | func isWritable(self: *Stream) bool { 455 | return cast(bool)$uv_is_writable(&self.__handle.stream); 456 | }; 457 | func setBlocking(self: *Stream, blocking: i32) i32 { 458 | return cast(i32)$uv_stream_set_blocking(&self.__handle.stream, cast(i32)blocking); 459 | }; 460 | func getWriteQueueSize(self: *Stream) size_t { 461 | return cast(size_t)$uv_stream_get_write_queue_size(&self.__handle.stream); 462 | }; 463 | }; 464 | 465 | // Tcp 466 | export typedef OSSocket i32; 467 | 468 | export struct Tcp { 469 | ..Stream; 470 | 471 | func init(self: *Tcp, loop: *Loop) i32 { 472 | self.loop = loop; 473 | self._init(); 474 | return cast(i32)$uv_tcp_init(&loop.__loop, &self.__handle.tcp); 475 | }; 476 | func initEx(self: *Tcp, loop: *Loop, flags: u32) i32 { 477 | self.loop = loop; 478 | self._init(); 479 | return cast(i32)$uv_tcp_init_ex(&loop.__loop, &self.__handle.tcp, flags); 480 | }; 481 | func nodelay(self: *Tcp, enable: bool) i32 { 482 | return cast(i32)$uv_tcp_nodelay(&self.__handle.tcp, cast(i32)enable); 483 | }; 484 | func keepalive(self: *Tcp, enable: bool, delay: u32) i32 { 485 | return cast(i32)$uv_tcp_keepalive(&self.__handle.tcp, cast(i32)enable, delay); 486 | }; 487 | func simultaneousAccepts(self: *Tcp, enable: bool) i32 { 488 | return cast(i32)$uv_tcp_simultaneous_accepts(&self.__handle.tcp, cast(i32)enable); 489 | }; 490 | func bind(self: *Tcp, addr: *SockAddr, flags: u32) i32 { 491 | return cast(i32)$uv_tcp_bind(&self.__handle.tcp, addr, flags); 492 | }; 493 | func getSockName(self: *Tcp, name: *SockAddr, namelen: *i32) i32 { 494 | return cast(i32)$uv_tcp_getsockname(&self.__handle.tcp, name, namelen); 495 | }; 496 | func getPeerName(self: *Tcp, name: *SockAddr, namelen: *i32) i32 { 497 | return cast(i32)$uv_tcp_getpeername(&self.__handle.tcp, name, namelen); 498 | }; 499 | func connect(self: *Tcp, req: *ConnectReq, addr: *SockAddr, cb: func(*ConnectReq, i32)) i32 { 500 | req._setInternalData(cast(*void)cb); 501 | return cast(i32)$uv_tcp_connect(&req.__req.connect, &self.__handle.tcp, addr, cast($uv_connect_cb)$vo_uv_connect_cb); 502 | }; 503 | func closeReset(self: *Tcp, cb: func(*Stream)) i32 { 504 | self._setInternalData(cb); 505 | return cast(i32)$uv_tcp_close_reset(&self.__handle.tcp, cast($uv_close_cb)$vo_uv_close_cb); 506 | }; 507 | }; -------------------------------------------------------------------------------- /lib/vector.vo: -------------------------------------------------------------------------------- 1 | import "heap.vo"; 2 | 3 | struct VectorLayout { 4 | isOwner: bool; 5 | length: size_t; 6 | capacity: size_t; 7 | mem: *u8; 8 | }; 9 | 10 | func make(length: size_t, el_size: size_t) *void { 11 | vector := new VectorLayout; 12 | vector.mem = heap.malloc(length*el_size); 13 | vector.length = length; 14 | vector.capacity = length; 15 | vector.isOwner = true; 16 | return cast(*void)vector; 17 | }; -------------------------------------------------------------------------------- /src/compiler/formatter.go: -------------------------------------------------------------------------------- 1 | package compiler 2 | 3 | import ( 4 | "bytes" 5 | . "parser" 6 | "path" 7 | "strconv" 8 | ) 9 | 10 | type Formatter struct { 11 | Symbols *SymbolTable 12 | Imports map[string]*SymbolTable 13 | Prefixes map[string][]byte 14 | NameSp Namespace 15 | } 16 | 17 | func FormatFile(ast File, s *SymbolTable, n map[string]*SymbolTable, p map[string][]byte, num int) File { 18 | f := Formatter{s, n, p, Namespace{}} 19 | f.NameSp.Init(num) 20 | newAst := File{} 21 | newAst.Statements = make([]Statement, len(ast.Statements)) 22 | for i, statement := range ast.Statements { 23 | newAst.Statements[i] = f.statement(statement) 24 | } 25 | return newAst 26 | } 27 | 28 | func (f *Formatter) getSymbol(Ident Token, Curr bool) (Node, bool) { 29 | if Curr { 30 | return f.Symbols.Find(Ident) 31 | } 32 | return f.Symbols.FindInAll(Ident) 33 | } 34 | 35 | func (s *Formatter) pushScope() { 36 | s.Symbols.Flag++ 37 | s.Symbols = s.Symbols.Children[s.Symbols.Flag-1] 38 | } 39 | 40 | func (s *Formatter) popScope() { 41 | s.Symbols = s.Symbols.Parent 42 | } 43 | 44 | func (f *Formatter) statement(stmt Statement) Statement { 45 | switch stmt.(type) { 46 | case Typedef: 47 | return f.typedef(stmt.(Typedef)) 48 | case Import: 49 | return f.imprt(stmt.(Import)) 50 | case Declaration: 51 | return f.declaration(stmt.(Declaration)) 52 | case IfElseBlock: 53 | return f.ifElse(stmt.(IfElseBlock)) 54 | case Loop: 55 | return f.loop(stmt.(Loop)) 56 | case Switch: 57 | return f.swtch(stmt.(Switch)) 58 | case Block: 59 | f.pushScope() 60 | block := f.block(stmt.(Block)) 61 | f.popScope() 62 | return block 63 | case Assignment: 64 | return f.assignment(stmt.(Assignment)) 65 | case Return: 66 | return f.rturn(stmt.(Return)) 67 | case Delete: 68 | return f.delete(stmt.(Delete)) 69 | case ExportStatement: 70 | return ExportStatement{Stmt: f.statement(stmt.(ExportStatement).Stmt)} 71 | case Expression: 72 | return f.expr(stmt.(Expression)) 73 | case Label: 74 | return Label{Name: f.NameSp.getLabelName(stmt.(Label).Name)} 75 | case Goto: 76 | return Goto{Name: f.NameSp.getLabelName(stmt.(Goto).Name)} 77 | } 78 | return stmt 79 | } 80 | 81 | func (f *Formatter) ifElse(ifElse IfElseBlock) IfElseBlock { 82 | f.pushScope() 83 | if ifElse.HasInitStmt { 84 | ifElse.InitStatement = f.statement(ifElse.InitStatement) 85 | } 86 | ifElse.Conditions = f.exprArray(ifElse.Conditions) 87 | 88 | for x, block := range ifElse.Blocks { 89 | f.pushScope() 90 | ifElse.Blocks[x] = f.block(block) 91 | f.popScope() 92 | } 93 | ifElse.ElseBlock = f.block(ifElse.ElseBlock) 94 | f.popScope() 95 | return ifElse 96 | } 97 | 98 | func (f *Formatter) loop(loop Loop) Loop { 99 | f.pushScope() 100 | if loop.Type&InitLoop == InitLoop { 101 | loop.InitStatement = f.statement(loop.InitStatement) 102 | } 103 | if loop.Type&CondLoop == CondLoop { 104 | loop.Condition = f.expr(loop.Condition) 105 | } 106 | if loop.Type&LoopLoop == LoopLoop { 107 | loop.LoopStatement = f.statement(loop.LoopStatement) 108 | } 109 | loop.Block = f.block(loop.Block) 110 | f.popScope() 111 | return loop 112 | } 113 | 114 | func (f *Formatter) swtch(swtch Switch) Switch { 115 | newSwitch := Switch{Cases: make([]CaseStruct, len(swtch.Cases)), Type: swtch.Type} 116 | f.pushScope() 117 | 118 | if swtch.Type == InitCondSwitch { 119 | newSwitch.InitStatement = f.statement(swtch.InitStatement) 120 | newSwitch.Expr = f.expr(swtch.Expr) 121 | } else if swtch.Type == CondSwitch { 122 | newSwitch.Expr = f.expr(swtch.Expr) 123 | } 124 | 125 | for x, Case := range swtch.Cases { 126 | newSwitch.Cases[x].Condition = f.expr(Case.Condition) 127 | newSwitch.Cases[x].Block = f.block(Case.Block) 128 | } 129 | if swtch.HasDefaultCase { 130 | newSwitch.HasDefaultCase = true 131 | newSwitch.DefaultCase = f.block(swtch.DefaultCase) 132 | } 133 | f.popScope() 134 | return newSwitch 135 | } 136 | 137 | func (f *Formatter) imprt(stmt Import) Import { 138 | imprt := Import{} 139 | for _, Path := range stmt.Paths { 140 | pth := path.Clean(string(Path.Buff[1 : len(Path.Buff)-1])) 141 | if path.Ext(pth) != ".h" { 142 | pth += ".h" 143 | } 144 | imprt.Paths = append(imprt.Paths, Token{Buff: []byte(pth), PrimaryType: StringLiteral}) 145 | } 146 | return imprt 147 | } 148 | 149 | func (f *Formatter) enum(enum EnumType, Name Token) EnumType { 150 | newEnum := EnumType{Identifiers: make([]Token, len(enum.Identifiers)), Values: make([]Expression, len(enum.Values))} 151 | f.pushScope() 152 | for i, Ident := range enum.Identifiers { 153 | newEnum.Identifiers[i] = f.NameSp.getEnumProp(Name.Buff, Ident) 154 | newEnum.Values[i] = f.expr(enum.Values[i]) 155 | } 156 | f.popScope() 157 | return newEnum 158 | } 159 | 160 | func (f *Formatter) typedef(typedef Typedef) Typedef { 161 | Typ := typedef.Type 162 | DefaultName := Token{} 163 | 164 | switch Typ.(type) { 165 | case StructType: 166 | f.pushScope() 167 | Typ = f.strct(Typ.(StructType), typedef.Name) 168 | f.popScope() 169 | DefaultName = f.NameSp.getStrctDefaultName(typedef.Name) 170 | case EnumType: 171 | Typ = f.enum(Typ.(EnumType), typedef.Name) 172 | } 173 | return Typedef{Type: f.typ(Typ), Name: f.NameSp.getNewVarName(typedef.Name), DefaultName: DefaultName} 174 | } 175 | 176 | func (f *Formatter) tupl(typ TupleType) TupleType { 177 | return TupleType{Types: f.typeArray(typ.Types)} 178 | } 179 | 180 | func (f *Formatter) union(typ UnionType) UnionType { 181 | for x, prop := range typ.Identifiers { 182 | typ.Identifiers[x] = f.NameSp.getPropName(prop) 183 | } 184 | return UnionType{Identifiers: typ.Identifiers, Types: f.typeArray(typ.Types)} 185 | } 186 | 187 | func (f *Formatter) delete(delete Delete) Delete { 188 | return Delete{Exprs: f.exprArray(delete.Exprs)} 189 | } 190 | 191 | func (f *Formatter) rturn(rturn Return) Return { 192 | return Return{Values: f.exprArray(rturn.Values)} 193 | } 194 | 195 | func (f *Formatter) assignment(as Assignment) Assignment { 196 | return Assignment{Variables: f.exprArray(as.Variables), Op: as.Op, Values: f.exprArray(as.Values)} 197 | } 198 | 199 | func (f *Formatter) block(block Block) Block { 200 | newBlock := Block{} 201 | newBlock.Statements = make([]Statement, len(block.Statements)) 202 | for i, stmt := range block.Statements { 203 | newBlock.Statements[i] = f.statement(stmt) 204 | } 205 | return newBlock 206 | } 207 | 208 | func (f *Formatter) declaration(dec Declaration) Declaration { 209 | newDec := Declaration{} 210 | 211 | if len(dec.Types) == 1 { 212 | Type := f.typ(dec.Types[0]) 213 | for range dec.Identifiers { 214 | newDec.Types = append(newDec.Types, Type) 215 | } 216 | } else if len(dec.Types) == 0 { 217 | for _, val := range dec.Values { 218 | newDec.Types = append(newDec.Types, f.typ(f.getType(val))) 219 | } 220 | } else { 221 | for _, typ := range dec.Types { 222 | newDec.Types = append(newDec.Types, f.typ(typ)) 223 | } 224 | } 225 | for _, Val := range dec.Values { 226 | newDec.Values = append(newDec.Values, f.expr(Val)) 227 | } 228 | for _, Ident := range dec.Identifiers { 229 | newDec.Identifiers = append(newDec.Identifiers, f.NameSp.getNewVarName(Ident)) 230 | } 231 | return newDec 232 | } 233 | 234 | func (f *Formatter) strctProp(prop Declaration, Name Token) Declaration { 235 | newProp := Declaration{} 236 | 237 | if len(prop.Types) == 1 { 238 | Typ := f.typ(prop.Types[0]) 239 | for range prop.Identifiers { 240 | newProp.Types = append(newProp.Types, Typ) 241 | } 242 | } else if len(prop.Types) == 0 { 243 | for _, Val := range prop.Values { 244 | newProp.Types = append(newProp.Types, f.typ(f.getType(Val))) 245 | } 246 | } else { 247 | for _, Type := range prop.Types { 248 | newProp.Types = append(newProp.Types, f.typ(Type)) 249 | } 250 | } 251 | for _, val := range prop.Values { 252 | newProp.Values = append(newProp.Values, f.expr(val)) 253 | } 254 | for i, Ident := range prop.Identifiers { 255 | switch newProp.Types[i].(type) { 256 | case FuncType: 257 | if !newProp.Types[i].(FuncType).Mut { 258 | newProp.Identifiers = append(newProp.Identifiers, f.NameSp.getStrctMethodName(Ident, Name)) 259 | continue 260 | } 261 | } 262 | newProp.Identifiers = append(newProp.Identifiers, f.NameSp.getPropName(Ident)) 263 | } 264 | return newProp 265 | } 266 | 267 | func (f *Formatter) superStrctProp(superSt BasicType, prop Declaration, Name Token) Declaration { 268 | newProp := Declaration{} 269 | 270 | for _, val := range prop.Values { 271 | switch val.(type) { 272 | case FuncExpr: 273 | break 274 | default: 275 | newProp.Values = append(newProp.Values, f.expr(val)) 276 | continue 277 | } 278 | if val.(FuncExpr).Type.Mut { 279 | newProp.Values = append(newProp.Values, f.expr(val)) 280 | continue 281 | } 282 | 283 | fnc := val.(FuncExpr) 284 | argTypes := fnc.Type.ArgTypes 285 | first := argTypes[0] 286 | 287 | switch first.(type) { 288 | case PointerType: 289 | first2 := first.(PointerType).BaseType 290 | if f.compareTypes(first2, superSt) { 291 | newVal := FuncExpr{Type: FuncType{ReturnTypes: fnc.Type.ReturnTypes, ArgNames: fnc.Type.ArgNames, ArgTypes: append([]Type{PointerType{BaseType: BasicType{Expr: IdentExpr{Value: Name}}}}, argTypes[1:]...)}, Block: fnc.Block} 292 | newProp.Values = append(newProp.Values, f.expr(newVal)) 293 | continue 294 | } 295 | case BasicType: 296 | if f.compareTypes(first, superSt) { 297 | newVal := FuncExpr{Type: FuncType{ReturnTypes: fnc.Type.ReturnTypes, ArgNames: fnc.Type.ArgNames, ArgTypes: append([]Type{BasicType{Expr: IdentExpr{Value: Name}}}, argTypes[1:]...)}, Block: fnc.Block} 298 | newProp.Values = append(newProp.Values, f.expr(newVal)) 299 | continue 300 | } 301 | } 302 | newProp.Values = append(newProp.Values, f.expr(val)) 303 | } 304 | 305 | if len(prop.Types) == 1 { 306 | Typ := f.typ(prop.Types[0]) 307 | 308 | switch Typ.(type) { 309 | case FuncType: 310 | if len(prop.Values) > 0 { 311 | Typ = f.getType(newProp.Values[0]) 312 | } 313 | } 314 | 315 | for range prop.Identifiers { 316 | newProp.Types = append(newProp.Types, Typ) 317 | } 318 | } else if len(prop.Types) == 0 { 319 | for _, Val := range newProp.Values { 320 | newProp.Types = append(newProp.Types, f.typ(f.getType(Val))) 321 | } 322 | } else { 323 | for x, Type := range prop.Types { 324 | switch Type.(type) { 325 | case FuncType: 326 | newProp.Types = append(newProp.Types, f.typ(newProp.Values[x].(FuncExpr).Type)) 327 | continue 328 | } 329 | newProp.Types = append(newProp.Types, f.typ(Type)) 330 | } 331 | } 332 | /* 333 | for _, val := range prop.Values { 334 | newProp.Values = append(newProp.Values, f.expr(val)) 335 | } 336 | */ 337 | for i, Ident := range prop.Identifiers { 338 | switch newProp.Types[i].(type) { 339 | case FuncType: 340 | if !newProp.Types[i].(FuncType).Mut { 341 | newProp.Identifiers = append(newProp.Identifiers, f.NameSp.getStrctMethodName(Ident, Name)) 342 | continue 343 | } 344 | } 345 | newProp.Identifiers = append(newProp.Identifiers, f.NameSp.getPropName(Ident)) 346 | } 347 | 348 | return newProp 349 | } 350 | 351 | func (f *Formatter) superStrct(t BasicType, Typ StructType, Name Token) StructType { 352 | strct := StructType{} 353 | strct.Props = []Declaration{} 354 | 355 | for _, superStruct := range Typ.SuperStructs { 356 | l := f.getType(superStruct).(Typedef) 357 | s := f.superStrct(BasicType{Expr: IdentExpr{Value: l.Name}}, l.Type.(StructType), Name) 358 | 359 | for _, prop := range s.Props { 360 | strct.Props = append(strct.Props, prop) 361 | } 362 | } 363 | for _, prop := range Typ.Props { 364 | strct.Props = append(strct.Props, f.superStrctProp(t, prop, Name)) 365 | } 366 | return strct 367 | } 368 | 369 | func (f *Formatter) strct(Typ StructType, Name Token) StructType { 370 | strct := StructType{} 371 | strct.Props = []Declaration{} 372 | 373 | for _, superStruct := range Typ.SuperStructs { 374 | l := f.getType(superStruct).(Typedef) 375 | s := f.superStrct(BasicType{Expr: IdentExpr{Value: l.Name}}, l.Type.(StructType), Name) 376 | 377 | for _, prop := range s.Props { 378 | strct.Props = append(strct.Props, prop) 379 | } 380 | } 381 | for _, prop := range Typ.Props { 382 | strct.Props = append(strct.Props, f.strctProp(prop, Name)) 383 | } 384 | return strct 385 | } 386 | 387 | func (f *Formatter) expr(expr Expression) Expression { 388 | expr2 := expr 389 | 390 | switch expr.(type) { 391 | case IdentExpr: 392 | for _, buff := range Globals { 393 | if bytes.Compare([]byte(buff), expr.(IdentExpr).Value.Buff) == 0 { 394 | return expr 395 | } 396 | } 397 | expr2 = IdentExpr{Value: f.NameSp.getNewVarName(expr.(IdentExpr).Value)} 398 | case UnaryExpr: 399 | expr2 = UnaryExpr{Op: expr.(UnaryExpr).Op, Expr: f.expr(expr.(UnaryExpr).Expr)} 400 | case BinaryExpr: 401 | expr2 = BinaryExpr{Left: f.expr(expr.(BinaryExpr).Left), Op: expr.(BinaryExpr).Op, Right: f.expr(expr.(BinaryExpr).Right)} 402 | case PostfixUnaryExpr: 403 | expr2 = PostfixUnaryExpr{Op: expr.(PostfixUnaryExpr).Op, Expr: f.expr(expr.(PostfixUnaryExpr).Expr)} 404 | case TernaryExpr: 405 | expr2 = TernaryExpr{Cond: f.expr(expr.(TernaryExpr).Cond), Left: f.expr(expr.(TernaryExpr).Left), Right: f.expr(expr.(TernaryExpr).Right)} 406 | case ArrayLiteral: 407 | expr2 = ArrayLiteral{Exprs: f.exprArray(expr.(ArrayLiteral).Exprs)} 408 | case CallExpr: 409 | expr2 = f.callExpr(expr.(CallExpr)) 410 | case TypeCast: 411 | expr2 = f.typeCast(expr.(TypeCast)) 412 | case ArrayMemberExpr: 413 | expr2 = f.arrayMemberExpr(expr.(ArrayMemberExpr)) 414 | case MemberExpr: 415 | expr2 = f.memberExpr(expr.(MemberExpr)) 416 | case LenExpr: 417 | expr2 = f.lenExpr(expr.(LenExpr)) 418 | case SizeExpr: 419 | expr2 = f.sizeExpr(expr.(SizeExpr)) 420 | case CompoundLiteral: 421 | expr2 = f.compoundLiteral(expr.(CompoundLiteral)) 422 | case AwaitExpr: 423 | expr2 = AwaitExpr{Expr: f.expr(expr.(AwaitExpr).Expr)} 424 | case FuncExpr: 425 | f.pushScope() 426 | expr2 = FuncExpr{Type: f.typ(expr.(FuncExpr).Type).(FuncType), Block: f.block(expr.(FuncExpr).Block)} 427 | f.popScope() 428 | case HeapAlloc: 429 | expr2 = HeapAlloc{Type: f.typ(expr.(HeapAlloc).Type), Val: f.expr(expr.(HeapAlloc).Val)} 430 | } 431 | return expr2 432 | } 433 | 434 | func (f *Formatter) callExpr(expr CallExpr) CallExpr { 435 | Args := f.exprArray(expr.Args) 436 | Function := f.expr(expr.Function) 437 | 438 | isPointer := false 439 | Typ := f.getRootType(f.getType(expr.Function)) 440 | 441 | for { 442 | switch Typ.(type) { 443 | case PointerType: 444 | Typ = f.getRootType(Typ.(PointerType).BaseType) 445 | isPointer = true 446 | continue 447 | } 448 | break 449 | } 450 | 451 | switch expr.Function.(type) { 452 | case MemberExpr: 453 | Arg1 := Typ.(FuncType).ArgTypes[0] 454 | Base := expr.Function.(MemberExpr).Base 455 | 456 | oka := false 457 | switch Base.(type) { 458 | case IdentExpr: 459 | _, ok := f.Prefixes[string(Base.(IdentExpr).Value.Buff)] 460 | oka = ok 461 | } 462 | if !oka { 463 | BaseType := f.getRootType(f.getType(Base)) 464 | 465 | switch Arg1.(type) { 466 | case PointerType: 467 | switch BaseType.(type) { 468 | case PointerType: 469 | Args = append([]Expression{f.expr(Base)}, Args...) 470 | default: 471 | Args = append([]Expression{f.expr(UnaryExpr{Expr: Base, Op: Token{Buff: []byte("&"), PrimaryType: AirthmaticOperator, SecondaryType: Mul}})}, Args...) 472 | } 473 | default: 474 | switch BaseType.(type) { 475 | case PointerType: 476 | Args = append([]Expression{f.expr(UnaryExpr{Expr: Base, Op: Token{Buff: []byte("*"), PrimaryType: AirthmaticOperator, SecondaryType: Mul}})}, Args...) 477 | default: 478 | Args = append([]Expression{f.expr(Base)}, Args...) 479 | } 480 | } 481 | } 482 | } 483 | 484 | if isPointer { 485 | return CallExpr{Function: UnaryExpr{Op: Token{Buff: []byte("*"), PrimaryType: AirthmaticOperator, SecondaryType: Mul}, Expr: Function}, Args: Args} 486 | } 487 | return CallExpr{Function: Function, Args: Args} 488 | } 489 | 490 | func (f *Formatter) typ(typ Type) Type { 491 | switch typ.(type) { 492 | case BasicType: 493 | return BasicType{Expr: f.expr(typ.(BasicType).Expr)} 494 | case NumberType: 495 | return f.typ(I32Type.Type) 496 | case PointerType: 497 | return PointerType{BaseType: f.typ(typ.(PointerType).BaseType)} 498 | case VecType: 499 | return VecType{BaseType: f.typ(typ.(VecType).BaseType)} 500 | case PromiseType: 501 | return PromiseType{BaseType: f.typ(typ.(PromiseType).BaseType)} 502 | case ConstType: 503 | return ConstType{BaseType: f.typ(typ.(ConstType).BaseType)} 504 | case CaptureType: 505 | return CaptureType{BaseType: f.typ(typ.(CaptureType).BaseType)} 506 | case StaticType: 507 | return StaticType{BaseType: f.typ(typ.(StaticType).BaseType)} 508 | case ImplictArrayType: 509 | return ImplictArrayType{BaseType: f.typ(typ.(ImplictArrayType).BaseType)} 510 | case ArrayType: 511 | return ArrayType{Size: typ.(ArrayType).Size, BaseType: f.typ(typ.(ArrayType).BaseType)} 512 | case FuncType: 513 | ArgNames := typ.(FuncType).ArgNames 514 | ArgTypes := typ.(FuncType).ArgTypes 515 | 516 | NewArgNames := make([]Token, len(ArgNames)) 517 | NewArgTypes := make([]Type, len(ArgTypes)) 518 | 519 | for i, name := range ArgNames { 520 | NewArgNames[i] = f.NameSp.getNewVarName(name) 521 | } 522 | for i, Typ := range ArgTypes { 523 | NewArgTypes[i] = f.typ(Typ) 524 | } 525 | return FuncType{Type: typ.(FuncType).Type, ArgTypes: NewArgTypes, ArgNames: NewArgNames, ReturnTypes: f.typeArray(typ.(FuncType).ReturnTypes), Mut: typ.(FuncType).Mut} 526 | case TupleType: 527 | return f.tupl(typ.(TupleType)) 528 | case UnionType: 529 | f.pushScope() 530 | union := f.union(typ.(UnionType)) 531 | f.popScope() 532 | return union 533 | } 534 | 535 | return typ 536 | } 537 | 538 | func (f *Formatter) typeArray(types []Type) []Type { 539 | typs := make([]Type, len(types)) 540 | for i, typ := range types { 541 | typs[i] = f.typ(typ) 542 | } 543 | return typs 544 | } 545 | 546 | func (f *Formatter) typeCast(expr TypeCast) TypeCast { 547 | return TypeCast{Type: f.typ(expr.Type), Expr: f.expr(expr.Expr)} 548 | /* 549 | switch expr.Type.(type) { 550 | case BasicType: 551 | break 552 | default: 553 | return TypeCast{Type: f.typ(expr.Type), Expr: f.expr(expr.Expr)} 554 | } 555 | 556 | Typ := f.getType(expr.Type.(BasicType).Expr) 557 | 558 | switch Typ.(type) { 559 | case StructType: 560 | break 561 | default: 562 | return TypeCast{Type: f.typ(expr.Type), Expr: f.expr(expr.Expr)} 563 | } 564 | 565 | return TypeCast{ 566 | Type: expr.Type, 567 | Expr: UnaryExpr{ 568 | Op: Token{Buff: []byte("*"), PrimaryType: AirthmaticOperator, SecondaryType: Mul}, 569 | Expr: TypeCast{ 570 | Type: PointerType{BaseType: expr.Type}, 571 | Expr: BinaryExpr{ 572 | Left: UnaryExpr{Op: Token{Buff: []byte("&"), PrimaryType: BitwiseOperator, SecondaryType: And}, Expr: f.expr(expr)}, 573 | Op: Token{Buff: []byte("+"), PrimaryType: AirthmaticOperator, SecondaryType: Add}, 574 | Right: CallExpr{ 575 | Function: IdentExpr{Value: Token{Buff: []byte("offsetof"), PrimaryType: Identifier}}, 576 | Args: []Expression{expr.Type.(BasicType).Expr, Typ.(StructType).Props[0].Types[0]}, 577 | }, 578 | }, 579 | }, 580 | }, 581 | } 582 | */ 583 | } 584 | 585 | func (f *Formatter) compoundLiteral(expr CompoundLiteral) CompoundLiteral { 586 | Name := f.typ(expr.Name) 587 | Typ := expr.Name 588 | 589 | prefix := f.NameSp.Base 590 | 591 | switch Typ.(type) { 592 | case BasicType: 593 | t := Typ.(BasicType) 594 | switch t.Expr.(type) { 595 | case MemberExpr: 596 | Ident := t.Expr.(MemberExpr).Base.(IdentExpr).Value 597 | if t, ok := f.Prefixes[string(f.NameSp.getActualName(Ident).Buff)]; ok { 598 | prefix = string(t[1:]) 599 | } 600 | } 601 | default: 602 | return CompoundLiteral{Name: Name, Data: f.compoundLiteralData(expr.Data)} 603 | } 604 | 605 | Typ = f.getType(Typ.(BasicType).Expr) 606 | var StrctName Token 607 | 608 | switch Typ.(type) { 609 | case Typedef: 610 | StrctName = Typ.(Typedef).Name 611 | default: 612 | return CompoundLiteral{Name: Name, Data: f.compoundLiteralData(expr.Data)} 613 | } 614 | 615 | Typ = f.getRootType(Typ) 616 | 617 | switch Typ.(type) { 618 | case StructType: 619 | break 620 | default: 621 | return CompoundLiteral{Name: Name, Data: f.compoundLiteralData(expr.Data)} 622 | } 623 | 624 | strct := Typ.(StructType) 625 | data := f.compoundLiteralData(expr.Data) 626 | 627 | if len(data.Fields) == 0 && len(data.Values) > 0 { 628 | x := 1 629 | l := len(data.Values) 630 | 631 | for _, prop := range strct.Props { 632 | for j, Ident := range prop.Identifiers { 633 | t := prop.Types[j] 634 | 635 | switch t.(type) { 636 | case FuncType: 637 | if !t.(FuncType).Mut { 638 | continue 639 | } 640 | } 641 | 642 | if x <= l { 643 | data.Fields = append(data.Fields, f.NameSp.getPropName(Ident)) 644 | x++ 645 | } else if len(prop.Values) >= j || len(prop.Values) == 1 { 646 | data.Fields = append(data.Fields, f.NameSp.getPropName(Ident)) 647 | data.Values = append(data.Values, MemberExpr{ 648 | Base: IdentExpr{Value: f.NameSp.getStrctDefaultNameFromPrefix(prefix, StrctName)}, 649 | Prop: f.NameSp.getPropName(Ident), 650 | }) 651 | } 652 | } 653 | } 654 | for _, superSt := range strct.SuperStructs { 655 | superSt := f.getRootType(f.getType(superSt)).(StructType) 656 | 657 | for _, prop := range superSt.Props { 658 | for j, Ident := range prop.Identifiers { 659 | 660 | t := prop.Types[j] 661 | 662 | switch t.(type) { 663 | case FuncType: 664 | if !t.(FuncType).Mut { 665 | continue 666 | } 667 | } 668 | 669 | if x <= l { 670 | data.Fields = append(data.Fields, f.NameSp.getPropName(Ident)) 671 | x++ 672 | } else if len(prop.Values) >= j || len(prop.Values) == 1 { 673 | data.Fields = append(data.Fields, f.NameSp.getPropName(Ident)) 674 | data.Values = append(data.Values, MemberExpr{ 675 | Base: IdentExpr{Value: f.NameSp.getStrctDefaultNameFromPrefix(prefix, StrctName)}, 676 | Prop: f.NameSp.getPropName(Ident), 677 | }) 678 | } 679 | } 680 | } 681 | } 682 | } else { 683 | for _, prop := range strct.Props { 684 | label: 685 | for j, Ident := range prop.Identifiers { 686 | if len(prop.Values) <= j && len(prop.Values) != 1 { 687 | break 688 | } 689 | 690 | for _, tok := range data.Fields { 691 | if bytes.Compare(f.NameSp.getActualName(tok).Buff, f.NameSp.getActualName(Ident).Buff) == 0 { 692 | continue label 693 | } 694 | } 695 | 696 | t := prop.Types[j] 697 | 698 | switch t.(type) { 699 | case FuncType: 700 | if !t.(FuncType).Mut { 701 | continue 702 | } 703 | } 704 | 705 | data.Fields = append(data.Fields, f.NameSp.getPropName(Ident)) 706 | data.Values = append(data.Values, MemberExpr{ 707 | Base: IdentExpr{Value: f.NameSp.getStrctDefaultNameFromPrefix(prefix, StrctName)}, 708 | Prop: f.NameSp.getPropName(Ident), 709 | }) 710 | } 711 | } 712 | for _, superSt := range strct.SuperStructs { 713 | superSt := f.getRootType(f.getType(superSt)).(StructType) 714 | 715 | for _, prop := range superSt.Props { 716 | label2: 717 | for j, Ident := range prop.Identifiers { 718 | if len(prop.Values) <= j && len(prop.Values) != 1 { 719 | break 720 | } 721 | 722 | for _, tok := range data.Fields { 723 | if bytes.Compare(f.NameSp.getActualName(tok).Buff, f.NameSp.getActualName(Ident).Buff) == 0 { 724 | continue label2 725 | } 726 | } 727 | 728 | t := prop.Types[j] 729 | 730 | switch t.(type) { 731 | case FuncType: 732 | if !t.(FuncType).Mut { 733 | continue 734 | } 735 | } 736 | 737 | data.Fields = append(data.Fields, f.NameSp.getPropName(Ident)) 738 | data.Values = append(data.Values, MemberExpr{ 739 | Base: IdentExpr{Value: f.NameSp.getStrctDefaultNameFromPrefix(prefix, StrctName)}, 740 | Prop: f.NameSp.getPropName(Ident), 741 | }) 742 | } 743 | } 744 | } 745 | } 746 | return CompoundLiteral{Name: Name, Data: data} 747 | } 748 | 749 | func (f *Formatter) compoundLiteralData(data CompoundLiteralData) CompoundLiteralData { 750 | newData := CompoundLiteralData{Values: make([]Expression, len(data.Values)), Fields: make([]Token, len(data.Fields))} 751 | for i, Val := range data.Values { 752 | newData.Values[i] = f.expr(Val) 753 | } 754 | for i, Field := range data.Fields { 755 | newData.Fields[i] = f.NameSp.getPropName(Field) 756 | } 757 | return newData 758 | } 759 | 760 | func (f *Formatter) arrayMemberExpr(expr ArrayMemberExpr) Expression { 761 | Typ := f.getRootType(f.getType(expr.Parent)) 762 | 763 | switch Typ.(type) { 764 | case VecType: 765 | return ArrayMemberExpr{ 766 | Parent: PointerMemberExpr{ 767 | Base: f.expr(expr.Parent), 768 | Prop: Token{Buff: []byte("mem"), PrimaryType: Identifier}, 769 | }, 770 | Index: f.expr(expr.Index), 771 | } 772 | case TupleType: 773 | return MemberExpr{ 774 | Base: f.expr(expr.Parent), 775 | Prop: Token{Buff: []byte("_" + string(expr.Index.(BasicLit).Value.Buff)), PrimaryType: Identifier}, 776 | } 777 | default: 778 | return ArrayMemberExpr{Parent: f.expr(f.expr(expr.Parent)), Index: f.expr(expr.Index)} 779 | } 780 | } 781 | 782 | func (f *Formatter) lenExpr(expr LenExpr) Expression { 783 | // var Expr Expression 784 | Typ := expr.Type 785 | 786 | switch Typ.(type) { 787 | case BasicType: 788 | Typ = f.getType(Typ.(BasicType).Expr) 789 | // Expr = f.expr(Typ.(BasicType).Expr) 790 | } 791 | 792 | Typ = f.getRootType(Typ) 793 | /* 794 | switch Typ.(type) { 795 | case ArrayType: 796 | return CallExpr{Function: IdentExpr{Value: Token{Buff: []byte("len2")}}, Args: []Expression{Typ, Typ.(ArrayType).BaseType}} 797 | case DynamicType: 798 | switch Typ.(DynamicType).BaseType.(type) { 799 | case ImplictArrayType: 800 | return CallExpr{Function: IdentExpr{Value: Token{Buff: []byte("len")}}, Args: []Expression{Expr, Typ.(DynamicType).BaseType.(ImplictArrayType).BaseType}} 801 | case ArrayType: 802 | return CallExpr{Function: IdentExpr{Value: Token{Buff: []byte("len2")}}, Args: []Expression{Typ.(DynamicType).BaseType, Typ.(DynamicType).BaseType.(ArrayType).BaseType}} 803 | } 804 | } 805 | */ 806 | return CallExpr{Function: IdentExpr{Value: Token{Buff: []byte("len3")}}, Args: []Expression{Typ}} 807 | } 808 | 809 | func (f *Formatter) sizeExpr(expr SizeExpr) CallExpr { 810 | Expr := expr.Expr 811 | 812 | switch Expr.(type) { 813 | case Type: 814 | Expr = f.typ(Expr.(Type)) 815 | default: 816 | Expr = f.expr(Expr) 817 | } 818 | 819 | return CallExpr{Function: IdentExpr{Value: Token{Buff: []byte("sizeof")}}, Args: []Expression{Expr}} 820 | } 821 | 822 | func (f *Formatter) memberExpr(expr MemberExpr) Expression { 823 | Typ := f.getType(expr.Base) 824 | 825 | if Typ == nil { 826 | switch expr.Base.(type) { 827 | case IdentExpr: 828 | val, ok := f.Prefixes[string(f.NameSp.getActualName(expr.Base.(IdentExpr).Value).Buff)] 829 | if ok { 830 | return IdentExpr{Value: f.NameSp.joinName(val, f.NameSp.getActualName(expr.Prop))} 831 | } 832 | default: 833 | return MemberExpr{Base: f.expr(expr.Base), Prop: f.NameSp.getPropName(expr.Prop)} 834 | } 835 | } 836 | 837 | isPointer := false 838 | 839 | switch Typ.(type) { 840 | case PointerType: 841 | Typ = Typ.(PointerType).BaseType 842 | isPointer = true 843 | case InternalType: 844 | return MemberExpr{Base: f.expr(expr.Base), Prop: expr.Prop} 845 | } 846 | 847 | prefix := f.NameSp.Base 848 | isImported := false 849 | var table *SymbolTable = nil 850 | p2 := Expression(nil) 851 | 852 | switch Typ.(type) { 853 | case BasicType: 854 | switch Typ.(BasicType).Expr.(type) { 855 | case MemberExpr: 856 | Ident := Typ.(BasicType).Expr.(MemberExpr).Base.(IdentExpr).Value 857 | key := string(f.NameSp.getActualName(Ident).Buff) 858 | if t, ok := f.Prefixes[key]; ok { 859 | prefix = string(t[1:]) 860 | isImported = true 861 | table = f.Imports[key] 862 | p2 = Typ.(BasicType).Expr.(MemberExpr).Base 863 | } 864 | } 865 | Typ = f.getType(Typ.(BasicType).Expr) 866 | case Typedef: 867 | if Typ.(Typedef).NameSpace.Buff != nil { 868 | isImported = true 869 | key := string(Typ.(Typedef).NameSpace.Buff) 870 | prefix = string(f.Prefixes[key][1:]) 871 | table = f.Imports[key] 872 | } 873 | case InternalType: 874 | if isPointer { 875 | return PointerMemberExpr{Base: f.expr(expr.Base), Prop: expr.Prop} 876 | } 877 | return MemberExpr{Base: f.expr(expr.Base), Prop: expr.Prop} 878 | } 879 | 880 | switch Typ.(type) { 881 | case Typedef: 882 | switch Typ.(Typedef).Type.(type) { 883 | case EnumType: 884 | if isImported { 885 | return IdentExpr{Value: f.NameSp.getEnumPropFromPrefix(prefix, Typ.(Typedef).Name.Buff, expr.Prop)} 886 | } 887 | return IdentExpr{Value: f.NameSp.getEnumProp(Typ.(Typedef).Name.Buff, expr.Prop)} 888 | } 889 | case InternalType: 890 | if isPointer { 891 | return PointerMemberExpr{Base: f.expr(expr.Base), Prop: expr.Prop} 892 | } 893 | return MemberExpr{Base: f.expr(expr.Base), Prop: expr.Prop} 894 | } 895 | 896 | Typ99 := f.getRootType(Typ) 897 | var Typ2 StructType 898 | 899 | switch Typ99.(type) { 900 | case StructType: 901 | Typ2 = Typ99.(StructType) 902 | case VecType: 903 | return f.getVecProp(expr) 904 | case PromiseType: 905 | return f.getPromiseProp(expr) 906 | case InternalType: 907 | if isPointer { 908 | return PointerMemberExpr{Base: f.expr(expr.Base), Prop: expr.Prop} 909 | } 910 | return MemberExpr{Base: f.expr(expr.Base), Prop: expr.Prop} 911 | default: 912 | return MemberExpr{Base: f.expr(expr.Base), Prop: f.NameSp.getPropName(expr.Prop)} 913 | } 914 | 915 | ident := expr.Prop 916 | var Typ11 Type 917 | 918 | if isImported { 919 | Typ9 := StructType{} 920 | Typ9.Props = Typ2.Props 921 | Typ9.SuperStructs = make([]Expression, len(Typ2.SuperStructs)) 922 | 923 | for i, e := range Typ2.SuperStructs { 924 | switch e.(type) { 925 | case IdentExpr: 926 | Typ9.SuperStructs[i] = MemberExpr{Base: p2, Prop: e.(IdentExpr).Value} 927 | default: 928 | Typ9.SuperStructs[i] = e 929 | } 930 | } 931 | 932 | Typ11 = f.ofNamespace(f.getPropType(f.NameSp.getActualName(ident), Typ9), p2, table) 933 | } else { 934 | Typ11 = f.getPropType(f.NameSp.getActualName(ident), Typ2) 935 | } 936 | 937 | switch Typ11.(type) { 938 | case FuncType: 939 | if !Typ11.(FuncType).Mut { 940 | // fmt.Println(string(Typ.(Typedef).Name.Buff)) 941 | return IdentExpr{Value: f.NameSp.getStrctMethodNameFromPrefix(prefix, ident, Typ.(Typedef).Name)} 942 | } 943 | } 944 | 945 | if isPointer { 946 | return PointerMemberExpr{Base: f.expr(expr.Base), Prop: f.NameSp.getPropName(expr.Prop)} 947 | } 948 | return MemberExpr{Base: f.expr(expr.Base), Prop: f.NameSp.getPropName(expr.Prop)} 949 | } 950 | 951 | func (f *Formatter) getVecProp(expr MemberExpr) Expression { 952 | switch string(expr.Prop.Buff) { 953 | case "length": 954 | return PointerMemberExpr{ 955 | Base: f.expr(expr.Base), 956 | Prop: expr.Prop, 957 | } 958 | case "capacity": 959 | return PointerMemberExpr{ 960 | Base: f.expr(expr.Base), 961 | Prop: expr.Prop, 962 | } 963 | case "raw": 964 | return PointerMemberExpr{ 965 | Base: f.expr(expr.Base), 966 | Prop: Token{Buff: []byte("mem"), PrimaryType: Identifier}, 967 | } 968 | case "push": 969 | return IdentExpr{Value: Token{Buff: []byte("VECTOR_PUSH")}} 970 | case "pop": 971 | return IdentExpr{Value: Token{Buff: []byte("VECTOR_POP")}} 972 | case "concat": 973 | return IdentExpr{Value: Token{Buff: []byte("VECTOR_CONCAT")}} 974 | case "free": 975 | return IdentExpr{Value: Token{Buff: []byte("VECTOR_FREE")}} 976 | case "clone": 977 | return IdentExpr{Value: Token{Buff: []byte("VECTOR_CLONE")}} 978 | case "append": 979 | return IdentExpr{Value: Token{Buff: []byte("VECTOR_APPEND")}} 980 | case "slice": 981 | return IdentExpr{Value: Token{Buff: []byte("VECTOR_SLICE")}} 982 | } 983 | return nil 984 | } 985 | 986 | func (f *Formatter) getPromiseProp(expr MemberExpr) Expression { 987 | switch string(expr.Prop.Buff) { 988 | case "pending": 989 | return UnaryExpr{ 990 | Op: Token{Buff: []byte("!"), PrimaryType: LogicalOperator, SecondaryType: Not}, 991 | Expr: PointerMemberExpr{Base: f.expr(expr.Base), Prop: Token{Buff: []byte("state"), PrimaryType: Identifier}}, 992 | } 993 | case "resolved": 994 | return PointerMemberExpr{Base: f.expr(expr.Base), Prop: Token{Buff: []byte("state"), PrimaryType: Identifier}} 995 | case "resolve": 996 | return IdentExpr{Value: Token{Buff: []byte("PROMISE_RESOLVE")}} 997 | case "then": 998 | return IdentExpr{Value: Token{Buff: []byte("PROMISE_THEN")}} 999 | } 1000 | return nil 1001 | } 1002 | 1003 | func (f *Formatter) exprArray(array []Expression) []Expression { 1004 | Exprs := []Expression{} 1005 | for _, Expr := range array { 1006 | Exprs = append(Exprs, f.expr(Expr)) 1007 | } 1008 | return Exprs 1009 | } 1010 | 1011 | func (f *Formatter) getType(expr Expression) Type { 1012 | switch expr.(type) { 1013 | case BasicLit: 1014 | switch expr.(BasicLit).Value.PrimaryType { 1015 | case CharLiteral: 1016 | return NumberType{} 1017 | case NumberLiteral: 1018 | return NumberType{} 1019 | case StringLiteral: 1020 | return ArrayType{ 1021 | Size: Token{Buff: []byte(strconv.Itoa(expr.(BasicLit).Value.Flags)), PrimaryType: NumberLiteral, SecondaryType: DecimalRadix}, 1022 | BaseType: BasicType{Expr: IdentExpr{Value: Token{Buff: []byte("u8"), PrimaryType: Identifier}}}, 1023 | } 1024 | } 1025 | case IdentExpr: 1026 | Ident := expr.(IdentExpr).Value 1027 | if isInternal(Ident) { 1028 | return InternalType{} 1029 | } 1030 | sym, ok := f.getSymbol(Ident, false) 1031 | if ok { 1032 | return sym.Type 1033 | } 1034 | case BinaryExpr: 1035 | lt := f.getType(expr.(BinaryExpr).Left) 1036 | 1037 | switch lt.(type) { 1038 | case NumberType: 1039 | case InternalType: 1040 | break 1041 | default: 1042 | return lt 1043 | } 1044 | return f.getType(expr.(BinaryExpr).Right) 1045 | case TernaryExpr: 1046 | lt := f.getType(expr.(TernaryExpr).Left) 1047 | 1048 | switch lt.(type) { 1049 | case NumberType: 1050 | case InternalType: 1051 | break 1052 | default: 1053 | return lt 1054 | } 1055 | return f.getType(expr.(TernaryExpr).Right) 1056 | case TypeCast: 1057 | return expr.(TypeCast).Type 1058 | case UnaryExpr: 1059 | if expr.(UnaryExpr).Op.SecondaryType == Mul { 1060 | Typ := f.getType(expr.(UnaryExpr).Expr) 1061 | switch Typ.(type) { 1062 | case PointerType: 1063 | return Typ.(PointerType).BaseType 1064 | } 1065 | } else if expr.(UnaryExpr).Op.SecondaryType == And { 1066 | return PointerType{BaseType: f.getType(expr.(UnaryExpr).Expr)} 1067 | } else { 1068 | return f.getType(expr.(UnaryExpr).Expr) 1069 | } 1070 | case PostfixUnaryExpr: 1071 | return f.getType(expr.(PostfixUnaryExpr).Expr) 1072 | case CallExpr: 1073 | Typ := f.getType(expr.(CallExpr).Function) 1074 | 1075 | switch Typ.(type) { 1076 | case InternalType: 1077 | return InternalType{} 1078 | } 1079 | return Typ.(FuncType).ReturnTypes[0] 1080 | case ArrayMemberExpr: 1081 | Typ := f.getType(expr.(ArrayMemberExpr).Parent) 1082 | 1083 | switch Typ.(type) { 1084 | case ArrayType: 1085 | return Typ.(ArrayType).BaseType 1086 | case ImplictArrayType: 1087 | return Typ.(ImplictArrayType).BaseType 1088 | case PointerType: 1089 | return Typ.(PointerType).BaseType 1090 | case VecType: 1091 | return Typ.(VecType).BaseType 1092 | } 1093 | return Typ 1094 | case FuncExpr: 1095 | return expr.(FuncExpr).Type 1096 | case HeapAlloc: 1097 | return PointerType{BaseType: expr.(HeapAlloc).Type} 1098 | case CompoundLiteral: 1099 | return expr.(CompoundLiteral).Name 1100 | case SizeExpr: 1101 | return BasicType{Expr: IdentExpr{Value: Token{Buff: []byte("size_t"), PrimaryType: Identifier}}} 1102 | case AwaitExpr: 1103 | return f.getType(expr.(AwaitExpr).Expr).(PromiseType).BaseType 1104 | case MemberExpr: 1105 | Typ := f.getType(expr.(MemberExpr).Base) 1106 | 1107 | if Typ == nil { 1108 | switch expr.(MemberExpr).Base.(type) { 1109 | case IdentExpr: 1110 | Ident := expr.(MemberExpr).Base.(IdentExpr).Value 1111 | if t, ok := f.Imports[string(Ident.Buff)]; ok { 1112 | sym, _ := t.Find(expr.(MemberExpr).Prop) 1113 | return f.ofNamespace(sym.Type, expr.(MemberExpr).Base, t) 1114 | } 1115 | } 1116 | } 1117 | 1118 | isImported := false 1119 | var base Expression 1120 | var table *SymbolTable 1121 | 1122 | switch Typ.(type) { 1123 | case PointerType: 1124 | Typ = Typ.(PointerType).BaseType 1125 | case Typedef: 1126 | return BasicType{Expr: expr.(MemberExpr).Base} 1127 | case InternalType: 1128 | return InternalType{} 1129 | } 1130 | 1131 | Typ7 := f.getRootType(Typ) 1132 | 1133 | switch Typ7.(type) { 1134 | case BasicType: 1135 | switch Typ7.(BasicType).Expr.(type) { 1136 | case MemberExpr: 1137 | t, ok := f.Imports[string(Typ.(BasicType).Expr.(MemberExpr).Base.(IdentExpr).Value.Buff)] 1138 | if !ok { 1139 | break 1140 | } 1141 | isImported = true 1142 | table = t 1143 | base = Typ7.(BasicType).Expr.(MemberExpr).Base 1144 | } 1145 | case InternalType: 1146 | return InternalType{} 1147 | } 1148 | 1149 | switch Typ7.(type) { 1150 | case StructType: 1151 | if !isImported { 1152 | return f.getPropType(expr.(MemberExpr).Prop, Typ7.(StructType)) 1153 | } 1154 | Typ8 := Typ7.(StructType) 1155 | Typ9 := StructType{} 1156 | Typ9.Props = Typ8.Props 1157 | Typ9.SuperStructs = make([]Expression, len(Typ8.SuperStructs)) 1158 | 1159 | for i, e := range Typ8.SuperStructs { 1160 | switch e.(type) { 1161 | case IdentExpr: 1162 | Typ9.SuperStructs[i] = MemberExpr{Base: base, Prop: e.(IdentExpr).Value} 1163 | default: 1164 | Typ9.SuperStructs[i] = e 1165 | } 1166 | } 1167 | return f.ofNamespace(f.getPropType(expr.(MemberExpr).Prop, Typ9), base, table) 1168 | case UnionType: 1169 | for x, prop := range Typ7.(UnionType).Identifiers { 1170 | if bytes.Compare(prop.Buff, expr.(MemberExpr).Prop.Buff) == 0 { 1171 | return Typ7.(UnionType).Types[x] 1172 | } 1173 | } 1174 | case VecType: 1175 | return f.getVectorPropType(Typ.(VecType), expr.(MemberExpr).Prop) 1176 | case PromiseType: 1177 | return f.getPromisePropType(Typ.(PromiseType), expr.(MemberExpr).Prop) 1178 | case InternalType: 1179 | return InternalType{} 1180 | } 1181 | } 1182 | return nil 1183 | } 1184 | 1185 | func (f *Formatter) getPromisePropType(prom PromiseType, prop Token) Type { 1186 | switch string(prop.Buff) { 1187 | case "then": 1188 | return FuncType{ 1189 | Type: OrdFunction, 1190 | ReturnTypes: []Type{VoidType.Type}, 1191 | ArgTypes: []Type{prom, FuncType{Type: OrdFunction, ReturnTypes: []Type{VoidType.Type}, ArgTypes: []Type{prom.BaseType}}}, 1192 | } 1193 | case "resolve": 1194 | return FuncType{ 1195 | Type: OrdFunction, 1196 | ReturnTypes: []Type{VoidType.Type}, 1197 | ArgTypes: []Type{prom, prom.BaseType}, 1198 | } 1199 | case "pending": 1200 | return BasicType{Expr: IdentExpr{Value: Token{Buff: []byte("bool"), PrimaryType: Identifier}}} 1201 | case "resolved": 1202 | return BasicType{Expr: IdentExpr{Value: Token{Buff: []byte("bool"), PrimaryType: Identifier}}} 1203 | } 1204 | return nil 1205 | } 1206 | 1207 | func (f *Formatter) getVectorPropType(vec VecType, prop Token) Type { 1208 | switch string(prop.Buff) { 1209 | case "push": 1210 | return FuncType{ 1211 | Type: OrdFunction, 1212 | ReturnTypes: []Type{vec.BaseType}, 1213 | ArgTypes: []Type{vec, vec.BaseType}, 1214 | } 1215 | case "pop": 1216 | return FuncType{ 1217 | Type: OrdFunction, 1218 | ReturnTypes: []Type{vec.BaseType}, 1219 | ArgTypes: []Type{vec}, 1220 | } 1221 | case "concat": 1222 | return FuncType{ 1223 | Type: OrdFunction, 1224 | ReturnTypes: []Type{vec}, 1225 | ArgTypes: []Type{vec, vec}, 1226 | } 1227 | case "free": 1228 | return FuncType{ 1229 | Type: OrdFunction, 1230 | ReturnTypes: []Type{VoidType}, 1231 | ArgTypes: []Type{vec}, 1232 | } 1233 | case "clone": 1234 | return FuncType{ 1235 | Type: OrdFunction, 1236 | ReturnTypes: []Type{vec}, 1237 | ArgTypes: []Type{vec}, 1238 | } 1239 | case "append": 1240 | return FuncType{ 1241 | Type: OrdFunction, 1242 | ReturnTypes: []Type{vec}, 1243 | ArgTypes: []Type{vec, PointerType{BaseType: vec.BaseType}, BasicType{Expr: IdentExpr{Value: Token{Buff: []byte("size_t"), PrimaryType: Identifier}}}}, 1244 | } 1245 | case "slice": 1246 | return FuncType{ 1247 | Type: OrdFunction, 1248 | ReturnTypes: []Type{vec}, 1249 | ArgTypes: []Type{vec, BasicType{Expr: IdentExpr{Value: Token{Buff: []byte("size_t"), PrimaryType: Identifier}}}, BasicType{Expr: IdentExpr{Value: Token{Buff: []byte("size_t"), PrimaryType: Identifier}}}}, 1250 | } 1251 | case "length": 1252 | return BasicType{Expr: IdentExpr{Value: Token{Buff: []byte("size_t"), PrimaryType: Identifier}}} 1253 | case "capacity": 1254 | return BasicType{Expr: IdentExpr{Value: Token{Buff: []byte("size_t"), PrimaryType: Identifier}}} 1255 | } 1256 | return nil 1257 | } 1258 | 1259 | func (f *Formatter) getPropType(Prop Token, strct StructType) Type { 1260 | for _, prop := range strct.Props { 1261 | for x, ident := range prop.Identifiers { 1262 | if bytes.Compare(ident.Buff, Prop.Buff) != 0 { 1263 | continue 1264 | } 1265 | if len(prop.Types) == 0 { 1266 | return f.getType(prop.Values[x]) 1267 | } else if len(prop.Types) == 1 { 1268 | return prop.Types[0] 1269 | } else { 1270 | return prop.Types[x] 1271 | } 1272 | } 1273 | } 1274 | for _, superSt := range strct.SuperStructs { 1275 | return f.getPropType(Prop, f.getRootType(f.getType(superSt)).(StructType)) 1276 | } 1277 | return nil 1278 | } 1279 | 1280 | func (f *Formatter) getRootType(typ Type) Type { 1281 | Typ := typ 1282 | 1283 | switch typ.(type) { 1284 | case BasicType: 1285 | switch typ.(BasicType).Expr.(type) { 1286 | case IdentExpr: 1287 | b := typ.(BasicType).Expr.(IdentExpr).Value.Buff 1288 | if b[0] == '$' { 1289 | return InternalType{} 1290 | } 1291 | } 1292 | Typ = f.getType(typ.(BasicType).Expr) 1293 | case Typedef: 1294 | break 1295 | default: 1296 | return typ 1297 | } 1298 | 1299 | switch Typ.(type) { 1300 | case Typedef: 1301 | break 1302 | default: 1303 | return Typ 1304 | } 1305 | 1306 | return f.getRootType(Typ.(Typedef).Type) 1307 | } 1308 | 1309 | func (f *Formatter) compareTypes(Type1 Type, Type2 Type) bool { 1310 | switch Type2.(type) { 1311 | case InternalType: 1312 | return true 1313 | case NumberType: 1314 | root := f.getRootType(Type1) 1315 | 1316 | switch root.(type) { 1317 | case NumberType: 1318 | return true 1319 | case InternalType: 1320 | return true 1321 | case BasicType: 1322 | switch root.(BasicType).Expr.(type) { 1323 | case IdentExpr: 1324 | for _, buff := range GlobalTypes { 1325 | if bytes.Compare([]byte(buff), f.NameSp.getActualName(root.(BasicType).Expr.(IdentExpr).Value).Buff) == 0 { 1326 | return true 1327 | } 1328 | } 1329 | } 1330 | } 1331 | return false 1332 | case CaptureType: 1333 | switch Type1.(type) { 1334 | case CaptureType: 1335 | return f.compareTypes(Type1.(CaptureType).BaseType, Type2.(CaptureType).BaseType) 1336 | } 1337 | return f.compareTypes(Type1, Type2.(CaptureType).BaseType) 1338 | case StaticType: 1339 | switch Type1.(type) { 1340 | case StaticType: 1341 | return f.compareTypes(Type1.(StaticType).BaseType, Type2.(StaticType).BaseType) 1342 | } 1343 | return f.compareTypes(Type1, Type2.(StaticType).BaseType) 1344 | case ConstType: 1345 | switch Type1.(type) { 1346 | case ConstType: 1347 | break 1348 | default: 1349 | return f.compareTypes(Type1, Type2.(ConstType).BaseType) 1350 | } 1351 | return f.compareTypes(Type1.(ConstType).BaseType, Type2.(ConstType).BaseType) 1352 | } 1353 | 1354 | switch Type1.(type) { 1355 | case InternalType: 1356 | return true 1357 | case NumberType: 1358 | root := f.getRootType(Type2) 1359 | 1360 | switch root.(type) { 1361 | case NumberType: 1362 | return true 1363 | case InternalType: 1364 | return true 1365 | case BasicType: 1366 | switch root.(BasicType).Expr.(type) { 1367 | case IdentExpr: 1368 | for _, buff := range GlobalTypes { 1369 | if bytes.Compare([]byte(buff), f.NameSp.getActualName(root.(BasicType).Expr.(IdentExpr).Value).Buff) == 0 { 1370 | return true 1371 | } 1372 | } 1373 | } 1374 | } 1375 | return false 1376 | case BasicType: 1377 | switch Type2.(type) { 1378 | case BasicType: 1379 | break 1380 | default: 1381 | return false 1382 | } 1383 | switch Type1.(BasicType).Expr.(type) { 1384 | case IdentExpr: 1385 | switch Type2.(BasicType).Expr.(type) { 1386 | case IdentExpr: 1387 | break 1388 | default: 1389 | return false 1390 | } 1391 | return bytes.Compare(f.NameSp.getActualName(Type1.(BasicType).Expr.(IdentExpr).Value).Buff, f.NameSp.getActualName(Type2.(BasicType).Expr.(IdentExpr).Value).Buff) == 0 1392 | } 1393 | switch Type2.(BasicType).Expr.(type) { 1394 | case MemberExpr: 1395 | switch Type1.(BasicType).Expr.(type) { 1396 | case MemberExpr: 1397 | break 1398 | default: 1399 | return false 1400 | } 1401 | } 1402 | return f.compareTypes(BasicType{Expr: Type2.(BasicType).Expr.(MemberExpr).Base}, BasicType{Expr: Type1.(BasicType).Expr.(MemberExpr).Base}) && bytes.Compare(Type2.(BasicType).Expr.(MemberExpr).Prop.Buff, Type1.(BasicType).Expr.(MemberExpr).Prop.Buff) == 0 1403 | case PointerType: 1404 | switch Type2.(type) { 1405 | case PointerType: 1406 | return f.compareTypes(Type1.(PointerType).BaseType, Type2.(PointerType).BaseType) 1407 | default: 1408 | return false 1409 | } 1410 | case VecType: 1411 | switch Type2.(type) { 1412 | case VecType: 1413 | return f.compareTypes(Type1.(VecType).BaseType, Type2.(VecType).BaseType) 1414 | default: 1415 | return false 1416 | } 1417 | case PromiseType: 1418 | switch Type2.(type) { 1419 | case PromiseType: 1420 | return f.compareTypes(Type1.(PromiseType).BaseType, Type2.(PromiseType).BaseType) 1421 | default: 1422 | return false 1423 | } 1424 | case ArrayType: 1425 | switch Type2.(type) { 1426 | case ArrayType: 1427 | break 1428 | default: 1429 | return false 1430 | } 1431 | return f.compareTypes(Type1.(ArrayType).BaseType, Type2.(ArrayType).BaseType) 1432 | case ConstType: 1433 | switch Type2.(type) { 1434 | case ConstType: 1435 | break 1436 | default: 1437 | return f.compareTypes(Type1.(ConstType).BaseType, Type2) 1438 | } 1439 | return f.compareTypes(Type1.(ConstType).BaseType, Type2.(ConstType).BaseType) 1440 | case FuncType: 1441 | switch Type2.(type) { 1442 | case FuncType: 1443 | break 1444 | default: 1445 | return false 1446 | } 1447 | type1 := Type1.(FuncType) 1448 | type2 := Type2.(FuncType) 1449 | 1450 | if len(type1.ArgTypes) != len(type2.ArgTypes) { 1451 | return false 1452 | } 1453 | if type1.Type != type2.Type { 1454 | return false 1455 | } 1456 | for x, arg := range type1.ArgTypes { 1457 | if !f.compareTypes(arg, type2.ArgTypes[x]) { 1458 | return false 1459 | } 1460 | } 1461 | return f.compareTypes(type1.ReturnTypes[0], type2.ReturnTypes[0]) 1462 | case CaptureType: 1463 | switch Type2.(type) { 1464 | case CaptureType: 1465 | return f.compareTypes(Type1.(CaptureType).BaseType, Type2.(CaptureType).BaseType) 1466 | } 1467 | return f.compareTypes(Type1.(CaptureType).BaseType, Type2) 1468 | case StaticType: 1469 | switch Type2.(type) { 1470 | case StaticType: 1471 | return f.compareTypes(Type1.(StaticType).BaseType, Type2.(StaticType).BaseType) 1472 | } 1473 | return f.compareTypes(Type1.(StaticType).BaseType, Type2) 1474 | } 1475 | 1476 | return false 1477 | } 1478 | 1479 | func (f *Formatter) appendBase(expr Expression, base Expression) Expression { 1480 | switch expr.(type) { 1481 | case IdentExpr: 1482 | return MemberExpr{Base: base, Prop: expr.(IdentExpr).Value} 1483 | case MemberExpr: 1484 | return MemberExpr{Base: f.appendBase(expr.(MemberExpr).Base.(MemberExpr), base), Prop: expr.(MemberExpr).Prop} 1485 | } 1486 | return nil 1487 | } 1488 | 1489 | func (f *Formatter) ofNamespace(typ Type, name Expression, t *SymbolTable) Type { 1490 | switch typ.(type) { 1491 | case BasicType: 1492 | switch typ.(BasicType).Expr.(type) { 1493 | case IdentExpr: 1494 | if typ.(BasicType).Expr.(IdentExpr).Value.Buff[0] == '$' { 1495 | return typ 1496 | } 1497 | for _, buff := range Globals { 1498 | if bytes.Compare([]byte(buff), typ.(BasicType).Expr.(IdentExpr).Value.Buff) == 0 { 1499 | return typ 1500 | } 1501 | } 1502 | return BasicType{Expr: f.appendBase(typ.(BasicType).Expr, name), Line: typ.LineM(), Column: typ.ColumnM()} 1503 | } 1504 | case PointerType: 1505 | return PointerType{BaseType: f.ofNamespace(typ.(PointerType).BaseType, name, t), Line: typ.LineM(), Column: typ.ColumnM()} 1506 | case VecType: 1507 | return VecType{BaseType: f.ofNamespace(typ.(VecType).BaseType, name, t), Line: typ.LineM(), Column: typ.ColumnM()} 1508 | case PromiseType: 1509 | return VecType{BaseType: f.ofNamespace(typ.(PromiseType).BaseType, name, t), Line: typ.LineM(), Column: typ.ColumnM()} 1510 | case ArrayType: 1511 | return ArrayType{BaseType: f.ofNamespace(typ.(ArrayType).BaseType, name, t), Size: typ.(ArrayType).Size, Line: typ.LineM(), Column: typ.ColumnM()} 1512 | case ImplictArrayType: 1513 | return ImplictArrayType{BaseType: f.ofNamespace(typ.(ImplictArrayType).BaseType, name, t), Line: typ.LineM(), Column: typ.ColumnM()} 1514 | case ConstType: 1515 | return ConstType{BaseType: f.ofNamespace(typ.(ConstType).BaseType, name, t), Line: typ.LineM(), Column: typ.ColumnM()} 1516 | case FuncType: 1517 | fnc := typ.(FuncType) 1518 | return FuncType{Type: fnc.Type, ArgNames: fnc.ArgNames, ArgTypes: f.ofNamespaceArray(fnc.ArgTypes, name, t), ReturnTypes: f.ofNamespaceArray(fnc.ReturnTypes, name, t), Line: typ.LineM(), Column: typ.ColumnM()} 1519 | case TupleType: 1520 | return TupleType{Types: f.ofNamespaceArray(typ.(TupleType).Types, name, t), Line: typ.LineM(), Column: typ.ColumnM()} 1521 | case StructType: 1522 | newProps := make([]Declaration, len(typ.(StructType).Props)) 1523 | newSuperStructs := make([]Expression, len(typ.(StructType).SuperStructs)) 1524 | 1525 | for i, prop := range typ.(StructType).Props { 1526 | newProps[i] = Declaration{Types: f.ofNamespaceArray(prop.Types, name, t), Identifiers: prop.Identifiers, Values: prop.Values} 1527 | } 1528 | for i, superStruct := range typ.(StructType).SuperStructs { 1529 | newSuperStructs[i] = f.ofNamespace(BasicType{Expr: superStruct}, name, t).(BasicType).Expr 1530 | } 1531 | return StructType{Props: newProps, SuperStructs: newSuperStructs, Name: typ.(StructType).Name} 1532 | case Typedef: 1533 | for _, buff := range Globals { 1534 | if bytes.Compare([]byte(buff), typ.(Typedef).Name.Buff) == 0 { 1535 | return typ 1536 | } 1537 | } 1538 | return Typedef{Name: typ.(Typedef).Name, DefaultName: typ.(Typedef).DefaultName, Type: f.ofNamespace(typ.(Typedef).Type, name, t), NameSpace: name.(IdentExpr).Value} 1539 | case UnionType: 1540 | return UnionType{Identifiers: typ.(UnionType).Identifiers, Types: f.ofNamespaceArray(typ.(UnionType).Types, name, t), Line: typ.LineM(), Column: typ.ColumnM()} 1541 | } 1542 | return typ 1543 | } 1544 | 1545 | func (f *Formatter) ofNamespaceArray(types []Type, name Expression, t *SymbolTable) []Type { 1546 | newTypes := make([]Type, len(types)) 1547 | for i, typ := range types { 1548 | newTypes[i] = f.ofNamespace(typ, name, t) 1549 | } 1550 | return newTypes 1551 | } 1552 | -------------------------------------------------------------------------------- /src/compiler/importer.go: -------------------------------------------------------------------------------- 1 | package compiler 2 | 3 | import ( 4 | "error" 5 | "io/ioutil" 6 | "os" 7 | . "parser" 8 | "path" 9 | Path "path/filepath" 10 | "strconv" 11 | ) 12 | 13 | var exPath, _ = os.Executable() 14 | var libPath = Path.Join(Path.Dir(exPath), "../lib") 15 | 16 | var wd, _ = os.Getwd() 17 | 18 | var dfPath = path.Join(libPath, "internal/default.h") 19 | var DefaultC = []byte(` 20 | int main() { 21 | return v0_main(); 22 | }`) 23 | 24 | var ProjectDir string 25 | 26 | type file struct { 27 | exports *SymbolTable 28 | index int 29 | } 30 | 31 | var files = map[string]file{} 32 | 33 | func ImportFile(dir string, base string, isMain bool) (*SymbolTable, int) { 34 | t := num 35 | n := strconv.Itoa(num) 36 | 37 | if isMain { 38 | ProjectDir = dir 39 | } 40 | 41 | path := Path.Join(dir, base) 42 | rel, err := Path.Rel(ProjectDir, path) 43 | 44 | if err != nil { 45 | rel, _ = Path.Rel(libPath, path) 46 | } 47 | 48 | if f, ok := files[rel]; ok { 49 | return f.exports, f.index 50 | } 51 | 52 | OutPath := Path.Join(ProjectDir, "_build", rel) 53 | 54 | if isMain { 55 | OutPath += ".c" 56 | } else if Path.Ext(OutPath) != ".h" { 57 | OutPath += ".h" 58 | } 59 | 60 | Code, err := ioutil.ReadFile(path) 61 | 62 | if err != nil { 63 | path = Path.Join(libPath, base) 64 | Code, err = ioutil.ReadFile(path) 65 | } 66 | if err != nil { 67 | error.NewGenError("error finding import: " + err.Error()) 68 | } 69 | 70 | buildDir := Path.Dir(OutPath) 71 | 72 | os.MkdirAll(buildDir, os.ModeDir) 73 | os.Chmod(buildDir, 0777) 74 | 75 | f, err := os.Create(OutPath) 76 | 77 | if err != nil { 78 | error.NewGenError("error creating files: " + err.Error()) 79 | } 80 | 81 | if Path.Ext(path) == ".h" { 82 | f.Write(Code) 83 | } else { 84 | ast := ParseFile(&Lexer{Buffer: Code, Line: 1, Column: 1, Path: path}) 85 | symbols, imports, prefixes, exports, numm := AnalyzeFile(ast, path) 86 | newAst := FormatFile(ast, symbols, imports, prefixes, numm) 87 | 88 | if !isMain { 89 | f.Write([]byte("#ifndef H_" + n + "\n#define H_" + n + "\n")) 90 | } 91 | f.Write([]byte("#include \"internal/default.h\"\n")) 92 | 93 | f.Write(CompileImports(newAst)) 94 | f.Write(CompileTypedefs(newAst)) 95 | f.Write(CompileOnlyDeclarations(newAst)) 96 | f.Write(CompileOnlyInitializations(newAst)) 97 | 98 | if isMain { 99 | f.Write(DefaultC) 100 | } else { 101 | f.Write([]byte("\n#endif")) 102 | } 103 | f.Close() 104 | 105 | files[rel] = file{exports: exports, index: t} 106 | return exports, t 107 | } 108 | return &SymbolTable{}, t 109 | } 110 | -------------------------------------------------------------------------------- /src/compiler/names.go: -------------------------------------------------------------------------------- 1 | package compiler 2 | 3 | import ( 4 | "bytes" 5 | . "parser" 6 | "strconv" 7 | ) 8 | 9 | var num int = 0 10 | 11 | type Namespace struct { 12 | Base string 13 | BasePath string 14 | Num int 15 | } 16 | 17 | func (n *Namespace) Init(nm int) { 18 | n.Base = strconv.Itoa(nm) + "_" 19 | n.Num = nm 20 | } 21 | 22 | func (n *Namespace) getEnumProp(enumName []byte, prop Token) Token { 23 | return Token{Buff: []byte("e" + n.Base + string(enumName) + "_" + string(prop.Buff)), PrimaryType: Identifier, SecondaryType: SecondaryNullType, Line: prop.Line, Column: prop.Column, Flags: 3} 24 | } 25 | 26 | func (n *Namespace) getNewVarName(token Token) Token { 27 | if token.Flags != 0 { 28 | return token 29 | } 30 | if isGlobal(token.Buff) { 31 | return token 32 | } 33 | if isInternal(token) { 34 | return Token{Buff: token.Buff[1:], PrimaryType: Identifier, SecondaryType: SecondaryNullType, Line: token.Line, Column: token.Column, Flags: 2} 35 | } 36 | return Token{Buff: []byte("v" + n.Base + string(token.Buff)), PrimaryType: Identifier, SecondaryType: SecondaryNullType, Line: token.Line, Column: token.Column, Flags: 1} 37 | } 38 | 39 | func isGlobal(buf []byte) bool { 40 | for _, buff := range []string{"u8", "u16", "u32", "u64", "i8", "i16", "132", "i64", "float", "double", "void", "true", "false"} { 41 | if bytes.Compare([]byte(buff), buf) == 0 { 42 | return true 43 | } 44 | } 45 | return false 46 | } 47 | 48 | func getImportPrefix(n int) string { 49 | return "v" + strconv.Itoa(n) + "_" 50 | } 51 | 52 | func getPropName(prop Token) Token { 53 | return Token{Buff: []byte("p_" + string(prop.Buff)), PrimaryType: prop.PrimaryType, SecondaryType: prop.SecondaryType, Line: prop.Line, Column: prop.Column, Flags: 7} 54 | } 55 | 56 | func (n *Namespace) getVecPropName(prop Token) Token { 57 | newToken := Token{Line: prop.Line, Column: prop.Column, PrimaryType: Identifier, SecondaryType: SecondaryNullType, Flags: 10} 58 | 59 | switch string(prop.Buff) { 60 | case "push": 61 | newToken.Buff = []byte("VECTOR_PUSH") 62 | case "pop": 63 | newToken.Buff = []byte("VECTOR_POP") 64 | default: 65 | newToken.Buff = prop.Buff 66 | } 67 | return newToken 68 | } 69 | 70 | func (n *Namespace) getActualName(token Token) Token { 71 | if token.Flags == 0 { 72 | return token 73 | } 74 | newToken := Token{Line: token.Line, Column: token.Column, PrimaryType: token.PrimaryType, SecondaryType: token.SecondaryType, Flags: 0} 75 | newToken.Buff = make([]byte, len(token.Buff)+1) 76 | 77 | switch token.Flags { 78 | case 2: 79 | copy(newToken.Buff, []byte("$"+string(token.Buff))) 80 | case 7: 81 | copy(newToken.Buff, token.Buff[2:]) 82 | case 8: 83 | copy(newToken.Buff, token.Buff[2:]) 84 | default: 85 | copy(newToken.Buff, token.Buff[1+len(n.Base):]) 86 | } 87 | return newToken 88 | } 89 | 90 | func (n *Namespace) getStrctDefaultName(strct Token) Token { 91 | if strct.Flags != 0 { 92 | return strct 93 | } 94 | return Token{Line: strct.Line, Column: strct.Column, PrimaryType: strct.PrimaryType, SecondaryType: strct.SecondaryType, Flags: 4, Buff: []byte("d" + n.Base + string(strct.Buff))} 95 | } 96 | 97 | func (n *Namespace) getStrctMethodName(name Token, strct Token) Token { 98 | return Token{Line: strct.Line, Column: strct.Column, PrimaryType: strct.PrimaryType, SecondaryType: strct.SecondaryType, Flags: 5, Buff: []byte("m" + n.Base + string(name.Buff) + "_" + string(strct.Buff))} 99 | } 100 | 101 | func (n *Namespace) getLabelName(name Token) Token { 102 | return Token{Line: name.Line, Column: name.Column, PrimaryType: name.PrimaryType, SecondaryType: name.SecondaryType, Flags: 10, Buff: []byte("l_" + string(name.Buff))} 103 | } 104 | 105 | func (n *Namespace) joinName(prefix []byte, name Token) Token { 106 | return Token{Line: name.Line, Column: name.Column, PrimaryType: name.PrimaryType, SecondaryType: name.SecondaryType, Flags: 6, Buff: []byte(string(prefix) + string(name.Buff))} 107 | } 108 | 109 | func isInternal(tok Token) bool { 110 | buff := tok.Buff 111 | return len(buff) > 1 && bytes.Compare(buff[:1], []byte("$")) == 0 112 | } 113 | 114 | func (n *Namespace) getStrctDefaultNameFromPrefix(prefix string, strct Token) Token { 115 | if strct.Flags != 0 { 116 | return strct 117 | } 118 | return Token{Line: strct.Line, Column: strct.Column, PrimaryType: strct.PrimaryType, SecondaryType: strct.SecondaryType, Flags: 4, Buff: []byte("d" + prefix + string(strct.Buff))} 119 | } 120 | 121 | func (n *Namespace) getPropName(token Token) Token { 122 | if token.Flags != 0 { 123 | return token 124 | } 125 | return Token{Buff: []byte("p_" + string(token.Buff)), PrimaryType: Identifier, SecondaryType: SecondaryNullType, Line: token.Line, Column: token.Column, Flags: 8} 126 | } 127 | 128 | func (n *Namespace) getStrctMethodNameFromPrefix(prefix string, name Token, strct Token) Token { 129 | return Token{Line: strct.Line, Column: strct.Column, PrimaryType: strct.PrimaryType, SecondaryType: strct.SecondaryType, Flags: 5, Buff: []byte("m" + prefix + string(name.Buff) + "_" + string(strct.Buff))} 130 | } 131 | 132 | func (n *Namespace) getEnumPropFromPrefix(prefix string, enumName []byte, prop Token) Token { 133 | return Token{Buff: []byte("e" + prefix + string(enumName) + "_" + string(prop.Buff)), PrimaryType: Identifier, SecondaryType: SecondaryNullType, Line: prop.Line, Column: prop.Column, Flags: 3} 134 | } 135 | -------------------------------------------------------------------------------- /src/compiler/symbolTable.go: -------------------------------------------------------------------------------- 1 | package compiler 2 | 3 | import ( 4 | "bytes" 5 | . "parser" 6 | ) 7 | 8 | type SymbolTable struct { 9 | Nodes []Node 10 | Parent *SymbolTable 11 | Flag int 12 | Children []*SymbolTable 13 | } 14 | 15 | type Node struct { 16 | Identifier Token 17 | Type Type 18 | } 19 | 20 | func (t *SymbolTable) Add(node Node) { 21 | /* 22 | if bytes.Compare(node.Identifier.Buff, []byte("self")) == 0 { 23 | // fmt.Print("here") 24 | fmt.Println() 25 | fmt.Println(string(node.Type.(PointerType).BaseType.(BasicType).Expr.(IdentExpr).Value.Buff)) 26 | fmt.Printf("\n%#v\n\n", node.Type) 27 | debug.PrintStack() 28 | } 29 | */ 30 | t.Nodes = append(t.Nodes, node) 31 | } 32 | 33 | func (t *SymbolTable) Find(Ident Token) (Node, bool) { 34 | for _, node := range t.Nodes { 35 | // print(string(Ident.Buff), "\t", string(node.Identifier.Buff), "\n") 36 | if bytes.Compare(node.Identifier.Buff, Ident.Buff) == 0 { 37 | return node, true 38 | } 39 | } 40 | return Node{}, false 41 | } 42 | 43 | func (t *SymbolTable) NewChild() *SymbolTable { 44 | s := SymbolTable{Parent: t} 45 | t.Children = append(t.Children, &s) 46 | return &s 47 | } 48 | 49 | func (t *SymbolTable) FindInAll(Ident Token) (Node, bool) { 50 | // print("\n") 51 | node, ok := t.Find(Ident) 52 | if ok { 53 | return node, true 54 | } 55 | parent := t.Parent 56 | 57 | for parent != nil { 58 | node, ok := parent.Find(Ident) 59 | if ok { 60 | return node, true 61 | } 62 | parent = parent.Parent 63 | } 64 | // print("\n") 65 | return Node{}, false 66 | } 67 | -------------------------------------------------------------------------------- /src/error/error.go: -------------------------------------------------------------------------------- 1 | package error 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | ) 7 | 8 | type langError string 9 | 10 | func New(message string, line int, column int) { 11 | log.Fatal(fmt.Sprintf("Error: line %d column %d: %s\n", line, column, message)) 12 | } 13 | 14 | // for general (non-code) errors 15 | func NewGenError(message string) { 16 | log.Fatal(message) 17 | } 18 | -------------------------------------------------------------------------------- /src/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | . "compiler" 5 | "flag" 6 | "fmt" 7 | "os" 8 | "os/exec" 9 | "path" 10 | ) 11 | 12 | var exPath, _ = os.Executable() 13 | var libPath = path.Join(path.Dir(exPath), "../lib") 14 | var defaultH = path.Join(libPath, "internal/default.h") 15 | 16 | func main() { 17 | if len(os.Args) < 2 { 18 | fmt.Println("no arguments given") 19 | os.Exit(1) 20 | } 21 | switch os.Args[1] { 22 | case "compile": 23 | if len(os.Args) < 3 { 24 | fmt.Println("file name not given") 25 | } 26 | 27 | cmd := flag.NewFlagSet("compile", flag.ExitOnError) 28 | clang := cmd.String("clang", "", "pass arguments to the clang compiler") 29 | 30 | file := path.Clean(os.Args[2]) 31 | cmd.Parse(os.Args[3:]) 32 | 33 | ImportFile(path.Dir(file), path.Base(file), true) 34 | 35 | out, err := exec.Command("clang", path.Join(path.Dir(file), "_build", path.Base(file)+".c"), "-pthread", "-luv", "-fblocks", "-lBlocksRuntime", "-lgc", "-I"+libPath, *clang, "-o", path.Join(path.Dir(file), "a.out")).CombinedOutput() 36 | 37 | if err != nil { 38 | fmt.Println(string(out)) 39 | os.Exit(1) 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/parser/ast.go: -------------------------------------------------------------------------------- 1 | package parser 2 | 3 | type FunctionType byte 4 | 5 | // Never change these numbers, they are very sepcific 6 | const ( 7 | OrdFunction FunctionType = 1 8 | AsyncFunction FunctionType = 2 9 | WorkFunction FunctionType = 3 10 | ) 11 | 12 | type LoopType byte 13 | 14 | const ( 15 | InitLoop LoopType = 1 16 | CondLoop LoopType = 2 17 | LoopLoop LoopType = 4 18 | NoneLoop LoopType = 8 19 | ) 20 | 21 | type SwitchType byte 22 | 23 | const ( 24 | InitCondSwitch SwitchType = 1 25 | CondSwitch SwitchType = 2 26 | NoneSwtch SwitchType = 3 27 | ) 28 | 29 | type CaseStruct struct { 30 | Condition Expression 31 | Block Block 32 | Line int 33 | Column int 34 | } 35 | 36 | func (c CaseStruct) LineM() int { 37 | return c.Line 38 | } 39 | func (c CaseStruct) ColumnM() int { 40 | return c.Column 41 | } 42 | 43 | type Statement interface { 44 | isStatement() 45 | LineM() int 46 | ColumnM() int 47 | } 48 | 49 | type Expression interface { 50 | isExpression() 51 | isStatement() 52 | LineM() int 53 | ColumnM() int 54 | } 55 | 56 | type Type interface { 57 | isType() 58 | isExpression() 59 | isStatement() 60 | LineM() int 61 | ColumnM() int 62 | } 63 | 64 | type File struct { 65 | Path string 66 | Statements []Statement 67 | } 68 | 69 | type ( 70 | Block struct { 71 | Statements []Statement 72 | Line int 73 | Column int 74 | } 75 | Declaration struct { 76 | Identifiers []Token 77 | Types []Type 78 | Values []Expression 79 | Line int 80 | Column int 81 | } 82 | Import struct { 83 | Paths []Token 84 | Line int 85 | Column int 86 | } 87 | Loop struct { 88 | Type LoopType 89 | InitStatement Statement 90 | Condition Expression 91 | LoopStatement Statement 92 | Block Block 93 | Line int 94 | Column int 95 | } 96 | Switch struct { 97 | Type SwitchType 98 | InitStatement Statement 99 | Expr Expression 100 | Cases []CaseStruct 101 | HasDefaultCase bool 102 | DefaultCase Block 103 | Line int 104 | Column int 105 | } 106 | IfElseBlock struct { 107 | HasInitStmt bool 108 | InitStatement Statement 109 | Conditions []Expression 110 | Blocks []Block 111 | ElseBlock Block 112 | Line int 113 | Column int 114 | } 115 | Return struct { 116 | Values []Expression 117 | Line int 118 | Column int 119 | } 120 | Assignment struct { 121 | Variables []Expression 122 | Op Token 123 | Values []Expression 124 | Line int 125 | Column int 126 | } 127 | Defer struct { 128 | Stmt Statement 129 | Line int 130 | Column int 131 | } 132 | Delete struct { 133 | Exprs []Expression 134 | Line int 135 | Column int 136 | } 137 | Typedef struct { 138 | Name Token 139 | DefaultName Token 140 | Type Type 141 | NameSpace Token 142 | Line int 143 | Column int 144 | } 145 | Label struct { 146 | Name Token 147 | Line int 148 | Column int 149 | } 150 | Goto struct { 151 | Name Token 152 | Line int 153 | Column int 154 | } 155 | Break struct { 156 | Line int 157 | Column int 158 | } 159 | Continue struct { 160 | Line int 161 | Column int 162 | } 163 | NullStatement struct { 164 | Line int 165 | Column int 166 | } 167 | ExportStatement struct { 168 | Stmt Statement 169 | Line int 170 | Column int 171 | } 172 | ) 173 | 174 | type ( 175 | BasicLit struct { 176 | Value Token 177 | Line int 178 | Column int 179 | } 180 | 181 | BinaryExpr struct { 182 | Left Expression 183 | Op Token 184 | Right Expression 185 | Line int 186 | Column int 187 | } 188 | 189 | UnaryExpr struct { 190 | Op Token 191 | Expr Expression 192 | Line int 193 | Column int 194 | } 195 | 196 | PostfixUnaryExpr struct { 197 | Op Token 198 | Expr Expression 199 | Line int 200 | Column int 201 | } 202 | 203 | TernaryExpr struct { 204 | Cond Expression 205 | Left Expression 206 | Right Expression 207 | Line int 208 | Column int 209 | } 210 | 211 | FuncExpr struct { 212 | Type FuncType 213 | Block Block 214 | Line int 215 | Column int 216 | } 217 | 218 | CallExpr struct { 219 | Function Expression 220 | Args []Expression 221 | Line int 222 | Column int 223 | } 224 | 225 | TypeCast struct { 226 | Type Type 227 | Expr Expression 228 | Line int 229 | Column int 230 | } 231 | 232 | IdentExpr struct { 233 | Value Token 234 | Line int 235 | Column int 236 | } 237 | 238 | MemberExpr struct { 239 | Base Expression 240 | Prop Token 241 | Line int 242 | Column int 243 | } 244 | 245 | PointerMemberExpr struct { 246 | Base Expression 247 | Prop Token 248 | Line int 249 | Column int 250 | } 251 | 252 | ArrayMemberExpr struct { 253 | Parent Expression 254 | Index Expression 255 | Line int 256 | Column int 257 | } 258 | 259 | CompoundLiteral struct { 260 | Name Type 261 | Data CompoundLiteralData 262 | Line int 263 | Column int 264 | } 265 | 266 | CompoundLiteralData struct { 267 | Fields []Token 268 | Values []Expression 269 | Line int 270 | Column int 271 | } 272 | 273 | ArrayLiteral struct { 274 | Exprs []Expression 275 | Line int 276 | Column int 277 | } 278 | 279 | HeapAlloc struct { 280 | Type Type 281 | Val Expression 282 | Line int 283 | Column int 284 | } 285 | 286 | LenExpr struct { 287 | Type Type 288 | Line int 289 | Column int 290 | } 291 | 292 | SizeExpr struct { 293 | Expr Expression 294 | Line int 295 | Column int 296 | } 297 | 298 | AwaitExpr struct { 299 | Expr Expression 300 | Line int 301 | Column int 302 | } 303 | ) 304 | 305 | type ( 306 | FuncType struct { 307 | Type FunctionType 308 | ArgTypes []Type 309 | ArgNames []Token 310 | ReturnTypes []Type 311 | Mut bool 312 | Line int 313 | Column int 314 | } 315 | 316 | StructType struct { 317 | Name Token 318 | Props []Declaration 319 | SuperStructs []Expression 320 | Line int 321 | Column int 322 | } 323 | 324 | TupleType struct { 325 | Types []Type 326 | Line int 327 | Column int 328 | } 329 | 330 | EnumType struct { 331 | Identifiers []Token 332 | Values []Expression 333 | Line int 334 | Column int 335 | } 336 | 337 | UnionType struct { 338 | Identifiers []Token 339 | Types []Type 340 | Line int 341 | Column int 342 | } 343 | 344 | BasicType struct { 345 | Expr Expression 346 | Line int 347 | Column int 348 | } 349 | 350 | PointerType struct { 351 | BaseType Type 352 | Line int 353 | Column int 354 | } 355 | 356 | VecType struct { 357 | BaseType Type 358 | Line int 359 | Column int 360 | } 361 | 362 | ConstType struct { 363 | BaseType Type 364 | Line int 365 | Column int 366 | } 367 | 368 | CaptureType struct { 369 | BaseType Type 370 | Line int 371 | Column int 372 | } 373 | 374 | PromiseType struct { 375 | BaseType Type 376 | Line int 377 | Column int 378 | } 379 | 380 | ImplictArrayType struct { 381 | BaseType Type 382 | Line int 383 | Column int 384 | } 385 | 386 | ArrayType struct { 387 | Size Token 388 | BaseType Type 389 | Line int 390 | Column int 391 | } 392 | 393 | StaticType struct { 394 | BaseType Type 395 | Line int 396 | Column int 397 | } 398 | 399 | InternalType struct{} 400 | NumberType struct{} 401 | LabelType struct{} 402 | ) 403 | 404 | func (Block) isStatement() {} 405 | func (Declaration) isStatement() {} 406 | func (Import) isStatement() {} 407 | func (Loop) isStatement() {} 408 | func (Switch) isStatement() {} 409 | func (IfElseBlock) isStatement() {} 410 | func (Return) isStatement() {} 411 | func (Assignment) isStatement() {} 412 | func (NullStatement) isStatement() {} 413 | func (Break) isStatement() {} 414 | func (Continue) isStatement() {} 415 | func (Defer) isStatement() {} 416 | func (Delete) isStatement() {} 417 | func (ExportStatement) isStatement() {} 418 | func (Label) isStatement() {} 419 | func (Goto) isStatement() {} 420 | 421 | func (BasicLit) isExpression() {} 422 | func (BinaryExpr) isExpression() {} 423 | func (UnaryExpr) isExpression() {} 424 | func (CallExpr) isExpression() {} 425 | func (FuncExpr) isExpression() {} 426 | func (TernaryExpr) isExpression() {} 427 | func (PostfixUnaryExpr) isExpression() {} 428 | func (TypeCast) isExpression() {} 429 | func (IdentExpr) isExpression() {} 430 | func (MemberExpr) isExpression() {} 431 | func (ArrayMemberExpr) isExpression() {} 432 | func (CompoundLiteral) isExpression() {} 433 | func (CompoundLiteralData) isExpression() {} 434 | func (HeapAlloc) isExpression() {} 435 | func (ArrayLiteral) isExpression() {} 436 | func (LenExpr) isExpression() {} 437 | func (SizeExpr) isExpression() {} 438 | func (PointerMemberExpr) isExpression() {} 439 | func (AwaitExpr) isExpression() {} 440 | 441 | func (BasicLit) isStatement() {} 442 | func (BinaryExpr) isStatement() {} 443 | func (UnaryExpr) isStatement() {} 444 | func (CallExpr) isStatement() {} 445 | func (FuncExpr) isStatement() {} 446 | func (TernaryExpr) isStatement() {} 447 | func (PostfixUnaryExpr) isStatement() {} 448 | func (TypeCast) isStatement() {} 449 | func (IdentExpr) isStatement() {} 450 | func (MemberExpr) isStatement() {} 451 | func (ArrayMemberExpr) isStatement() {} 452 | func (CompoundLiteral) isStatement() {} 453 | func (CompoundLiteralData) isStatement() {} 454 | func (HeapAlloc) isStatement() {} 455 | func (ArrayLiteral) isStatement() {} 456 | func (LenExpr) isStatement() {} 457 | func (SizeExpr) isStatement() {} 458 | func (PointerMemberExpr) isStatement() {} 459 | func (AwaitExpr) isStatement() {} 460 | 461 | func (BasicType) isType() {} 462 | func (StructType) isType() {} 463 | func (EnumType) isType() {} 464 | func (TupleType) isType() {} 465 | func (UnionType) isType() {} 466 | func (FuncType) isType() {} 467 | func (ConstType) isType() {} 468 | func (PointerType) isType() {} 469 | func (ArrayType) isType() {} 470 | func (VecType) isType() {} 471 | func (ImplictArrayType) isType() {} 472 | func (Typedef) isType() {} 473 | func (InternalType) isType() {} 474 | func (NumberType) isType() {} 475 | func (CaptureType) isType() {} 476 | func (StaticType) isType() {} 477 | func (PromiseType) isType() {} 478 | func (LabelType) isType() {} 479 | 480 | func (BasicType) isExpression() {} 481 | func (StructType) isExpression() {} 482 | func (EnumType) isExpression() {} 483 | func (TupleType) isExpression() {} 484 | func (UnionType) isExpression() {} 485 | func (FuncType) isExpression() {} 486 | func (ConstType) isExpression() {} 487 | func (PointerType) isExpression() {} 488 | func (ArrayType) isExpression() {} 489 | func (VecType) isExpression() {} 490 | func (ImplictArrayType) isExpression() {} 491 | func (Typedef) isExpression() {} 492 | func (InternalType) isExpression() {} 493 | func (NumberType) isExpression() {} 494 | func (CaptureType) isExpression() {} 495 | func (StaticType) isExpression() {} 496 | func (PromiseType) isExpression() {} 497 | func (LabelType) isExpression() {} 498 | 499 | func (BasicType) isStatement() {} 500 | func (StructType) isStatement() {} 501 | func (EnumType) isStatement() {} 502 | func (TupleType) isStatement() {} 503 | func (UnionType) isStatement() {} 504 | func (FuncType) isStatement() {} 505 | func (ConstType) isStatement() {} 506 | func (PointerType) isStatement() {} 507 | func (ArrayType) isStatement() {} 508 | func (VecType) isStatement() {} 509 | func (ImplictArrayType) isStatement() {} 510 | func (Typedef) isStatement() {} 511 | func (InternalType) isStatement() {} 512 | func (NumberType) isStatement() {} 513 | func (CaptureType) isStatement() {} 514 | func (StaticType) isStatement() {} 515 | func (PromiseType) isStatement() {} 516 | func (LabelType) isStatement() {} 517 | 518 | func (s Block) LineM() int { 519 | return s.Line 520 | } 521 | func (s Declaration) LineM() int { 522 | return s.Line 523 | } 524 | func (s Import) LineM() int { 525 | return s.Line 526 | } 527 | func (s Loop) LineM() int { 528 | return s.Line 529 | } 530 | func (s Switch) LineM() int { 531 | return s.Line 532 | } 533 | func (s IfElseBlock) LineM() int { 534 | return s.Line 535 | } 536 | func (s Return) LineM() int { 537 | return s.Line 538 | } 539 | func (s Assignment) LineM() int { 540 | return s.Line 541 | } 542 | func (s NullStatement) LineM() int { 543 | return s.Line 544 | } 545 | func (s Break) LineM() int { 546 | return s.Line 547 | } 548 | func (s Continue) LineM() int { 549 | return s.Line 550 | } 551 | func (s Defer) LineM() int { 552 | return s.Line 553 | } 554 | func (s Delete) LineM() int { 555 | return s.Line 556 | } 557 | func (s ExportStatement) LineM() int { 558 | return s.Line 559 | } 560 | func (s Label) LineM() int { 561 | return s.Line 562 | } 563 | func (s Goto) LineM() int { 564 | return s.Line 565 | } 566 | 567 | func (s Block) ColumnM() int { 568 | return s.Column 569 | } 570 | func (s Declaration) ColumnM() int { 571 | return s.Column 572 | } 573 | func (s Import) ColumnM() int { 574 | return s.Column 575 | } 576 | func (s Loop) ColumnM() int { 577 | return s.Column 578 | } 579 | func (s Switch) ColumnM() int { 580 | return s.Column 581 | } 582 | func (s IfElseBlock) ColumnM() int { 583 | return s.Column 584 | } 585 | func (s Return) ColumnM() int { 586 | return s.Column 587 | } 588 | func (s Assignment) ColumnM() int { 589 | return s.Column 590 | } 591 | func (s NullStatement) ColumnM() int { 592 | return s.Column 593 | } 594 | func (s Break) ColumnM() int { 595 | return s.Column 596 | } 597 | func (s Continue) ColumnM() int { 598 | return s.Column 599 | } 600 | func (s Defer) ColumnM() int { 601 | return s.Column 602 | } 603 | func (s Delete) ColumnM() int { 604 | return s.Column 605 | } 606 | func (s ExportStatement) ColumnM() int { 607 | return s.Column 608 | } 609 | func (s Label) ColumnM() int { 610 | return s.Line 611 | } 612 | func (s Goto) ColumnM() int { 613 | return s.Line 614 | } 615 | 616 | func (e BasicLit) LineM() int { 617 | return e.Line 618 | } 619 | func (e BinaryExpr) LineM() int { 620 | return e.Line 621 | } 622 | func (e UnaryExpr) LineM() int { 623 | return e.Line 624 | } 625 | func (e CallExpr) LineM() int { 626 | return e.Line 627 | } 628 | func (e FuncExpr) LineM() int { 629 | return e.Line 630 | } 631 | func (e TernaryExpr) LineM() int { 632 | return e.Line 633 | } 634 | func (e PostfixUnaryExpr) LineM() int { 635 | return e.Line 636 | } 637 | func (e TypeCast) LineM() int { 638 | return e.Line 639 | } 640 | func (e IdentExpr) LineM() int { 641 | return e.Line 642 | } 643 | func (e MemberExpr) LineM() int { 644 | return e.Line 645 | } 646 | func (e ArrayMemberExpr) LineM() int { 647 | return e.Line 648 | } 649 | func (e CompoundLiteral) LineM() int { 650 | return e.Line 651 | } 652 | func (e CompoundLiteralData) LineM() int { 653 | return e.Line 654 | } 655 | func (e HeapAlloc) LineM() int { 656 | return e.Line 657 | } 658 | func (e ArrayLiteral) LineM() int { 659 | return e.Line 660 | } 661 | func (e LenExpr) LineM() int { 662 | return e.Line 663 | } 664 | func (e SizeExpr) LineM() int { 665 | return e.Line 666 | } 667 | func (e PointerMemberExpr) LineM() int { 668 | return e.Line 669 | } 670 | func (e AwaitExpr) LineM() int { 671 | return e.Line 672 | } 673 | 674 | func (e BasicLit) ColumnM() int { 675 | return e.Column 676 | } 677 | func (e BinaryExpr) ColumnM() int { 678 | return e.Column 679 | } 680 | func (e UnaryExpr) ColumnM() int { 681 | return e.Column 682 | } 683 | func (e CallExpr) ColumnM() int { 684 | return e.Column 685 | } 686 | func (e FuncExpr) ColumnM() int { 687 | return e.Column 688 | } 689 | func (e TernaryExpr) ColumnM() int { 690 | return e.Column 691 | } 692 | func (e PostfixUnaryExpr) ColumnM() int { 693 | return e.Column 694 | } 695 | func (e TypeCast) ColumnM() int { 696 | return e.Column 697 | } 698 | func (e IdentExpr) ColumnM() int { 699 | return e.Column 700 | } 701 | func (e MemberExpr) ColumnM() int { 702 | return e.Column 703 | } 704 | func (e ArrayMemberExpr) ColumnM() int { 705 | return e.Column 706 | } 707 | func (e CompoundLiteral) ColumnM() int { 708 | return e.Column 709 | } 710 | func (e CompoundLiteralData) ColumnM() int { 711 | return e.Column 712 | } 713 | func (e HeapAlloc) ColumnM() int { 714 | return e.Column 715 | } 716 | func (e ArrayLiteral) ColumnM() int { 717 | return e.Column 718 | } 719 | func (e LenExpr) ColumnM() int { 720 | return e.Column 721 | } 722 | func (e SizeExpr) ColumnM() int { 723 | return e.Column 724 | } 725 | func (e PointerMemberExpr) ColumnM() int { 726 | return e.Column 727 | } 728 | func (e AwaitExpr) ColumnM() int { 729 | return e.Column 730 | } 731 | 732 | func (t BasicType) LineM() int { 733 | return t.Line 734 | } 735 | func (t StructType) LineM() int { 736 | return t.Line 737 | } 738 | func (t EnumType) LineM() int { 739 | return t.Line 740 | } 741 | func (t TupleType) LineM() int { 742 | return t.Line 743 | } 744 | func (t UnionType) LineM() int { 745 | return t.Line 746 | } 747 | func (t FuncType) LineM() int { 748 | return t.Line 749 | } 750 | func (t ConstType) LineM() int { 751 | return t.Line 752 | } 753 | func (t PointerType) LineM() int { 754 | return t.Line 755 | } 756 | func (t ArrayType) LineM() int { 757 | return t.Line 758 | } 759 | func (t VecType) LineM() int { 760 | return t.Line 761 | } 762 | func (t ImplictArrayType) LineM() int { 763 | return t.Line 764 | } 765 | func (t Typedef) LineM() int { 766 | return t.Line 767 | } 768 | func (t InternalType) LineM() int { 769 | return -1 770 | } 771 | func (t NumberType) LineM() int { 772 | return -1 773 | } 774 | func (t LabelType) LineM() int { 775 | return -1 776 | } 777 | func (t CaptureType) LineM() int { 778 | return t.Line 779 | } 780 | func (t StaticType) LineM() int { 781 | return t.Line 782 | } 783 | func (t PromiseType) LineM() int { 784 | return t.Line 785 | } 786 | 787 | func (t BasicType) ColumnM() int { 788 | return t.Column 789 | } 790 | func (t StructType) ColumnM() int { 791 | return t.Column 792 | } 793 | func (t EnumType) ColumnM() int { 794 | return t.Column 795 | } 796 | func (t TupleType) ColumnM() int { 797 | return t.Column 798 | } 799 | func (t UnionType) ColumnM() int { 800 | return t.Column 801 | } 802 | func (t FuncType) ColumnM() int { 803 | return t.Column 804 | } 805 | func (t ConstType) ColumnM() int { 806 | return t.Column 807 | } 808 | func (t PointerType) ColumnM() int { 809 | return t.Column 810 | } 811 | func (t ArrayType) ColumnM() int { 812 | return t.Column 813 | } 814 | func (t VecType) ColumnM() int { 815 | return t.Column 816 | } 817 | func (t ImplictArrayType) ColumnM() int { 818 | return t.Column 819 | } 820 | func (t Typedef) ColumnM() int { 821 | return t.Column 822 | } 823 | func (t InternalType) ColumnM() int { 824 | return -1 825 | } 826 | func (t NumberType) ColumnM() int { 827 | return -1 828 | } 829 | func (t LabelType) ColumnM() int { 830 | return -1 831 | } 832 | func (t CaptureType) ColumnM() int { 833 | return t.Column 834 | } 835 | func (t StaticType) ColumnM() int { 836 | return t.Column 837 | } 838 | func (t PromiseType) ColumnM() int { 839 | return t.Column 840 | } 841 | 842 | var VoidToken = Token{Buff: []byte("void"), PrimaryType: Identifier} 843 | var VoidType = Typedef{Name: VoidToken, Type: BasicType{Expr: IdentExpr{Value: Token{Buff: []byte("$void"), PrimaryType: Identifier}}}} 844 | 845 | var BoolToken = Token{Buff: []byte("bool"), PrimaryType: Identifier} 846 | var BoolType = Typedef{Name: BoolToken, Type: BasicType{Expr: IdentExpr{Value: Token{Buff: []byte("$bool"), PrimaryType: Identifier}}}} 847 | 848 | var U8Token = Token{Buff: []byte("u8"), PrimaryType: Identifier} 849 | var U8Type = Typedef{Name: U8Token, Type: BasicType{Expr: IdentExpr{Value: Token{Buff: []byte("$u8"), PrimaryType: Identifier}}}} 850 | 851 | var U16Token = Token{Buff: []byte("u16"), PrimaryType: Identifier} 852 | var U16Type = Typedef{Name: U16Token, Type: BasicType{Expr: IdentExpr{Value: Token{Buff: []byte("$u16"), PrimaryType: Identifier}}}} 853 | 854 | var U32Token = Token{Buff: []byte("u32"), PrimaryType: Identifier} 855 | var U32Type = Typedef{Name: U32Token, Type: BasicType{Expr: IdentExpr{Value: Token{Buff: []byte("$u32"), PrimaryType: Identifier}}}} 856 | 857 | var U64Token = Token{Buff: []byte("u64"), PrimaryType: Identifier} 858 | var U64Type = Typedef{Name: U64Token, Type: BasicType{Expr: IdentExpr{Value: Token{Buff: []byte("$u64"), PrimaryType: Identifier}}}} 859 | 860 | var I8Token = Token{Buff: []byte("i8"), PrimaryType: Identifier} 861 | var I8Type = Typedef{Name: I8Token, Type: BasicType{Expr: IdentExpr{Value: Token{Buff: []byte("$i8"), PrimaryType: Identifier}}}} 862 | 863 | var I16Token = Token{Buff: []byte("i16"), PrimaryType: Identifier} 864 | var I16Type = Typedef{Name: I16Token, Type: BasicType{Expr: IdentExpr{Value: Token{Buff: []byte("$i16"), PrimaryType: Identifier}}}} 865 | 866 | var I32Token = Token{Buff: []byte("i32"), PrimaryType: Identifier} 867 | var I32Type = Typedef{Name: I32Token, Type: BasicType{Expr: IdentExpr{Value: Token{Buff: []byte("$i32"), PrimaryType: Identifier}}}} 868 | 869 | var I64Token = Token{Buff: []byte("i64"), PrimaryType: Identifier} 870 | var I64Type = Typedef{Name: I64Token, Type: BasicType{Expr: IdentExpr{Value: Token{Buff: []byte("$i64"), PrimaryType: Identifier}}}} 871 | 872 | var F32Token = Token{Buff: []byte("f32"), PrimaryType: Identifier} 873 | var F32Type = Typedef{Name: F32Token, Type: BasicType{Expr: IdentExpr{Value: Token{Buff: []byte("$f32"), PrimaryType: Identifier}}}} 874 | 875 | var F64Token = Token{Buff: []byte("f64"), PrimaryType: Identifier} 876 | var F64Type = Typedef{Name: F64Token, Type: BasicType{Expr: IdentExpr{Value: Token{Buff: []byte("$f64"), PrimaryType: Identifier}}}} 877 | 878 | var True = IdentExpr{Value: Token{Buff: []byte("true"), PrimaryType: Identifier}} 879 | var False = IdentExpr{Value: Token{Buff: []byte("false"), PrimaryType: Identifier}} 880 | 881 | var SizeTToken = Token{Buff: []byte("size_t"), PrimaryType: Identifier} 882 | var SizeTType = Typedef{Name: I64Token, Type: BasicType{Expr: IdentExpr{Value: Token{Buff: []byte("$size_t"), PrimaryType: Identifier}}}} 883 | 884 | var UptrToken = Token{Buff: []byte("uptr"), PrimaryType: Identifier} 885 | var UptrType = Typedef{Name: I64Token, Type: BasicType{Expr: IdentExpr{Value: Token{Buff: []byte("$uptr"), PrimaryType: Identifier}}}} 886 | 887 | var Null = IdentExpr{Value: Token{Buff: []byte("null"), PrimaryType: Identifier}} 888 | 889 | var Globals = []string{"u8", "u16", "u32", "u64", "i8", "i16", "i32", "i64", "uptr", "f32", "f64", "void", "bool", "size_t", "true", "false", "null"} 890 | var GlobalTypes = []string{"u8", "u16", "u32", "u64", "i8", "i16", "i32", "i64", "uptr", "f32", "f64", "void", "bool", "size_t"} 891 | -------------------------------------------------------------------------------- /src/parser/lexer.go: -------------------------------------------------------------------------------- 1 | package parser 2 | 3 | import ( 4 | "error" 5 | "math" 6 | "strconv" 7 | ) 8 | 9 | //Lexer does stuff 10 | type Lexer struct { 11 | Buffer []byte // code read from some file or something 12 | Position int // position of char to process next in Buffer 13 | 14 | // for error messages and all 15 | Line int // line count of the current char in code 16 | Column int // column count of the current char in the current line 17 | 18 | Path string // path of current file 19 | } 20 | 21 | func (lexer *Lexer) readToBuffer() byte { 22 | // read few bytes from a file or command line or whatever 23 | // lexer.Buffer = append(lexer.Buffer, 'a') // just for now 24 | return 0 // eof 25 | } 26 | 27 | func (lexer *Lexer) nextChar() (byte, bool) { 28 | character, ok := lexer.peek() 29 | if !ok { 30 | return 0, false 31 | } 32 | lexer.eatLastByte() 33 | return character, true 34 | } 35 | 36 | // get the next character without incrementing the position counter of lexer 37 | func (lexer *Lexer) peek() (byte, bool) { 38 | // if no more characters to read in the Buffer 39 | if lexer.Position == len(lexer.Buffer) { 40 | // read few bytes from the source file and push it to Buffer 41 | // return 0 if eof reached 42 | if lexer.readToBuffer() == 0 { 43 | return 0, false // marks eof (tells the Lexer to stop lexing) 44 | } 45 | } 46 | 47 | // reached only when the Buffer has more bytes to read 48 | return lexer.Buffer[lexer.Position], true 49 | } 50 | 51 | // increment the position counter of Lexer by 1 52 | func (lexer *Lexer) eatLastByte() { 53 | lexer.Position++ 54 | lexer.Column++ 55 | } 56 | 57 | // increment the line count and zero the column count when a newline is reached 58 | func (lexer *Lexer) shiftLine() { 59 | lexer.Position++ 60 | lexer.Line++ 61 | lexer.Column = 0 62 | } 63 | 64 | func (lexer *Lexer) skipSpaces() { 65 | // no need to check for eof 66 | for next, _ := lexer.peek(); ; next, _ = lexer.peek() { 67 | if next == '\n' { 68 | lexer.shiftLine() 69 | } else if next == ' ' || next == '\t' || next == '\r' { 70 | lexer.eatLastByte() 71 | } else { // eof handled here 72 | break 73 | } 74 | } 75 | } 76 | 77 | func (lexer *Lexer) skipUntilNewline() { 78 | for next, ok := lexer.peek(); ok && next != '\n'; next, _ = lexer.peek() { 79 | lexer.eatLastByte() 80 | } 81 | } 82 | 83 | func (lexer *Lexer) multilineComment() { 84 | for { 85 | lexer.skipSpaces() 86 | 87 | if next, ok := lexer.peek(); !ok { 88 | error.New("Expected end of multiline comment, got eof.", lexer.Line, lexer.Column) 89 | } else if next != '*' { 90 | lexer.eatLastByte() 91 | continue 92 | } 93 | lexer.eatLastByte() 94 | 95 | if next, ok := lexer.peek(); !ok { 96 | error.New("Expected end of multiline comment, got eof.", lexer.Line, lexer.Column) 97 | } else if next != '/' { 98 | continue 99 | } 100 | 101 | lexer.eatLastByte() 102 | break 103 | } 104 | } 105 | 106 | func (lexer *Lexer) skipComments() { 107 | if next, _ := lexer.peek(); next != byte('/') { 108 | return 109 | } 110 | lexer.eatLastByte() 111 | if next, _ := lexer.peek(); next == byte('/') { 112 | lexer.skipUntilNewline() 113 | } else if next == '*' { 114 | lexer.eatLastByte() 115 | lexer.multilineComment() 116 | } else { 117 | lexer.Position-- 118 | lexer.Column-- 119 | } 120 | } 121 | 122 | func (lexer *Lexer) PrepNext() { 123 | for { 124 | if next, _ := lexer.peek(); IsSpace(next) { 125 | lexer.skipSpaces() // skiping spaces/tabs/newlines 126 | } 127 | if next, _ := lexer.peek(); next == byte('/') { 128 | lexer.eatLastByte() 129 | } else { 130 | break 131 | } 132 | if next, _ := lexer.peek(); next == '/' { 133 | lexer.skipUntilNewline() 134 | } else if next == '*' { 135 | lexer.multilineComment() 136 | } else { 137 | lexer.Position-- 138 | lexer.Column-- 139 | break 140 | } 141 | } 142 | } 143 | 144 | // NextToken returns next token 145 | func (lexer *Lexer) NextToken() Token { 146 | lexer.PrepNext() 147 | character, ok := lexer.peek() 148 | if !ok { 149 | // return eof token (tell the parser to stop further parsing) 150 | return Token{PrimaryType: EOF, SecondaryType: SecondaryNullType, Buff: nil, Line: lexer.Line, Column: lexer.Column} 151 | } else if IsIdentifierBegining(character) { 152 | return lexer.lexWord() // identifier or keyword or macros 153 | } else if IsNumDec(character) { 154 | return lexer.lexNumber() // number, hex starting with 0x, octals with 0o, decimals either directly or with 0d, and binary with 0b 155 | } else if IsStringDelimiter(character) { // string delimiter is " 156 | lexer.eatLastByte() 157 | return lexer.lexString() 158 | } else if IsCharDelimiter(character) { // char delimiter is ' 159 | lexer.eatLastByte() 160 | return lexer.lexChar() // just a single byte 161 | } else { 162 | if op := lexer.lexOperator(); op.SecondaryType != NotFound { 163 | return op 164 | } else if op = lexer.lexDelimiter(); op.SecondaryType != NotFound { 165 | return op 166 | } 167 | } 168 | error.New("Unknown character.", lexer.Line, lexer.Column) 169 | return Token{PrimaryType: ErrorToken, SecondaryType: UnknownChar, Buff: nil} 170 | } 171 | 172 | func (lexer *Lexer) lexNumber() Token { 173 | var radix SecondaryTokenType = DecimalRadix 174 | num := []byte{} 175 | 176 | line := lexer.Line 177 | column := lexer.Column 178 | 179 | // already checked for eof in NextToken() 180 | if character, _ := lexer.nextChar(); character == '0' { 181 | 182 | // check either the number has a base specified or we have to implictly assume it 183 | // no need to check for eof 184 | if next, _ := lexer.peek(); next == 'd' { // decimal 185 | radix = DecimalRadix 186 | lexer.eatLastByte() 187 | lexer.eatLastByte() 188 | 189 | if n3, _ := lexer.peek(); n3 == '0' || n3 == '_' { 190 | lexer.eatLastByte() 191 | for n, _ := lexer.peek(); n == '0' || n == '_'; n, _ = lexer.peek() { 192 | lexer.eatLastByte() 193 | } 194 | } else if !IsNumDec(n3) { 195 | num = append(num, '0') 196 | } 197 | } else if next == 'b' { // binary 198 | radix = BinaryRadix 199 | lexer.eatLastByte() 200 | num = append(num, '0') 201 | num = append(num, next) 202 | } else if next == 'o' { // octal 203 | radix = OctalRadix 204 | lexer.eatLastByte() 205 | num = append(num, '0') 206 | } else if next == 'x' { // hexadecimal 207 | radix = HexadecimalRadix 208 | lexer.eatLastByte() 209 | num = append(num, '0') 210 | num = append(num, next) 211 | } else if next == '0' { 212 | lexer.eatLastByte() 213 | if n3, _ := lexer.peek(); n3 == '0' || n3 == '_' { 214 | lexer.eatLastByte() 215 | for n, _ := lexer.peek(); n == '0' || n == '_'; n, _ = lexer.peek() { 216 | lexer.eatLastByte() 217 | } 218 | } else if !IsNumDec(n3) { 219 | num = append(num, '0') 220 | } 221 | } else { 222 | num = append(num, '0') 223 | } 224 | } else { 225 | num = append(num, character) 226 | } 227 | 228 | for m, _ := lexer.peek(); m == '_'; m, _ = lexer.peek() { 229 | lexer.eatLastByte() 230 | } 231 | 232 | switch radix { 233 | case DecimalRadix: 234 | for n, _ := lexer.peek(); IsNumDec(n) || n == '.'; n, _ = lexer.peek() { 235 | num = append(num, n) 236 | lexer.eatLastByte() 237 | for n2, _ := lexer.peek(); n2 == '_'; n2, _ = lexer.peek() { 238 | lexer.eatLastByte() 239 | } 240 | } 241 | case BinaryRadix: 242 | for n, _ := lexer.peek(); IsNumBi(n) || n == '.'; n, _ = lexer.peek() { 243 | num = append(num, n) 244 | lexer.eatLastByte() 245 | for n2, _ := lexer.peek(); n2 == '_'; n2, _ = lexer.peek() { 246 | lexer.eatLastByte() 247 | } 248 | } 249 | case OctalRadix: 250 | for n, _ := lexer.peek(); IsNumOct(n) || n == '.'; n, _ = lexer.peek() { 251 | num = append(num, n) 252 | lexer.eatLastByte() 253 | for n2, _ := lexer.peek(); n2 == '_'; n2, _ = lexer.peek() { 254 | lexer.eatLastByte() 255 | } 256 | } 257 | case HexadecimalRadix: 258 | for n, _ := lexer.peek(); IsNumHex(n) || n == '.'; n, _ = lexer.peek() { 259 | num = append(num, n) 260 | lexer.eatLastByte() 261 | for n2, _ := lexer.peek(); n2 == '_'; n2, _ = lexer.peek() { 262 | lexer.eatLastByte() 263 | } 264 | } 265 | } 266 | 267 | return Token{Buff: num, PrimaryType: NumberLiteral, SecondaryType: radix, Line: line, Column: column} 268 | } 269 | 270 | func (lexer *Lexer) lexChar() Token { 271 | 272 | // stores the utf32 code of char 273 | num := 0 274 | 275 | var encoding SecondaryTokenType 276 | 277 | line := lexer.Line 278 | column := lexer.Column 279 | 280 | character, ok := lexer.peek() 281 | 282 | if !ok { 283 | // Error: Expected char, got eof 284 | return Token{PrimaryType: ErrorToken, SecondaryType: UnexpectedEOF, Buff: nil, Line: lexer.Line, Column: lexer.Column} 285 | } else if character == '\n' { 286 | // Error: Expected char, got end of line 287 | return Token{PrimaryType: ErrorToken, SecondaryType: UnexpectedEOF, Buff: nil, Line: lexer.Line, Column: lexer.Column} 288 | } 289 | 290 | lexer.eatLastByte() 291 | 292 | if character == '\\' { 293 | next, ok := lexer.peek() 294 | 295 | if !ok { // Error: Expected char, got eof 296 | return Token{PrimaryType: ErrorToken, SecondaryType: UnexpectedEOF, Buff: nil, Line: lexer.Line, Column: lexer.Column} 297 | } else if character == '\n' { 298 | // Error: Expected char, got end of line 299 | return Token{PrimaryType: ErrorToken, SecondaryType: UnexpectedEOF, Buff: nil, Line: lexer.Line, Column: lexer.Column} 300 | } 301 | 302 | lexer.eatLastByte() 303 | 304 | switch next { 305 | case 't': 306 | num = '\t' 307 | case 'n': 308 | num = '\n' 309 | case 'r': 310 | num = '\r' 311 | case '\'': 312 | num = '\'' 313 | case '\\': 314 | num = '\\' 315 | case 'u': // 2 byte char 316 | for i := 0; i < 4; i++ { 317 | chr, ok := lexer.peek() 318 | 319 | if !ok { // Error: Expected escape sequence, got eof 320 | error.New("exprected escape sequence, got eof.", line, column) 321 | } else if IsNumHex(chr) { 322 | num += HexToInt(chr) * Pow(16, (3-i)) 323 | lexer.eatLastByte() 324 | } else { // Error: Invalid character in escape sequence, expected (0-9|A-F|a-f) 325 | error.New("invalid character in escape sequence.", line, column) 326 | } 327 | } 328 | 329 | encoding = Byte2Char 330 | case 'U': // 4 byte char 331 | for i := 0; i < 8; i++ { 332 | chr, ok := lexer.peek() 333 | 334 | if !ok { // Error: Expected escape sequence, got eof 335 | error.New("exprected escape sequence, got eof.", line, column) 336 | } else if IsNumHex(chr) { 337 | num += HexToInt(chr) * Pow(16, (7-i)) 338 | lexer.eatLastByte() 339 | } else { // Error: Invalid character in escape sequence, expected (0-9|A-F|a-f) 340 | error.New("invalid character in escape sequence.", line, column) 341 | } 342 | } 343 | encoding = Byte4Char 344 | default: 345 | // idk we can prob throw an error here saying that its an invalid escape sequence? 346 | num = int(next) 347 | } 348 | if nextChar, _ := lexer.peek(); nextChar == '\'' { 349 | lexer.eatLastByte() // increament the positon as `nextChar` was `'` as expected 350 | return Token{PrimaryType: CharLiteral, SecondaryType: encoding, Buff: []byte(strconv.Itoa(num)), Line: line, Column: column} 351 | } 352 | error.New("exprected ', got eof.", line, column) 353 | } else if character>>7 == 0 { // 1 byte char 354 | encoding = Byte1Char 355 | } else if character>>5 == 0b110 { // 2 byte char 356 | encoding = Byte2Char 357 | } else if character>>4 == 0b1110 { // 3 byte char 358 | encoding = Byte3Char 359 | } else if character>>3 == 0b11110 { // 4 byte char 360 | encoding = Byte4Char 361 | } else { 362 | // Error: Unsupported/Invalid character encoding 363 | return Token{PrimaryType: ErrorToken, SecondaryType: UnknownChar, Buff: nil, Line: lexer.Line, Column: lexer.Column} 364 | } 365 | 366 | num = int(character) 367 | len := int(encoding) - int(Byte1Char) + 1 368 | 369 | for i := 1; i < len; i++ { 370 | if chr, ok := lexer.peek(); !ok { 371 | // Error: expected char, got eof 372 | return Token{PrimaryType: ErrorToken, SecondaryType: UnexpectedEOF, Buff: nil, Line: lexer.Line, Column: lexer.Column} 373 | } else if chr>>6 == 0b10 { 374 | lexer.eatLastByte() 375 | num += int(math.Pow(float64(chr), 16*float64(i))) 376 | } else { 377 | // Error: Invalid char 378 | return Token{PrimaryType: ErrorToken, SecondaryType: SecondaryNullType, Buff: nil, Line: lexer.Line, Column: lexer.Column} 379 | } 380 | } 381 | 382 | if nextChar, ok := lexer.peek(); !ok { 383 | // Error: Expected char demlimiter, got eof 384 | return Token{PrimaryType: ErrorToken, SecondaryType: UnexpectedEOF, Buff: nil, Line: lexer.Line, Column: lexer.Column} 385 | } else if nextChar == '\'' { 386 | lexer.eatLastByte() // increament the positon as `nextChar` was `'` as expected 387 | return Token{PrimaryType: CharLiteral, SecondaryType: encoding, Buff: []byte(strconv.Itoa(num)), Line: line, Column: column} 388 | } 389 | 390 | // Error: Invalid character {nedxtChar} at {Lexer.line}:{Lexer.column}. Expected `'`. 391 | // print error and all (maybe use the Buff property for storing error message?) 392 | return Token{PrimaryType: ErrorToken, SecondaryType: SecondaryNullType, Buff: nil, Line: lexer.Line, Column: lexer.Column} 393 | } 394 | 395 | func (lexer *Lexer) lexString() Token { 396 | str := []byte{'"'} 397 | 398 | line := lexer.Line 399 | column := lexer.Column 400 | size := 1 401 | 402 | for character, ok := lexer.peek(); !IsStringDelimiter(character); character, ok = lexer.peek() { 403 | 404 | if !ok { 405 | // Error: Expected end of string literal, got eof 406 | error.New("expected \", got eof.", lexer.Line, lexer.Column) 407 | } else if character == '\n' { 408 | // Error: Expected end of string literal, got end of line 409 | error.New("expected \", got end of line.", lexer.Line, lexer.Column) 410 | } 411 | 412 | str = append(str, character) 413 | lexer.eatLastByte() 414 | 415 | if character == '\\' { 416 | next, ok := lexer.peek() 417 | 418 | if !ok { 419 | // Error: Expected end of string literal, got eof 420 | return Token{PrimaryType: ErrorToken, SecondaryType: UnexpectedEOF, Buff: nil, Line: lexer.Line, Column: lexer.Column} 421 | } else if character == '\n' { 422 | // Error: Expected end of string literal, got end of line 423 | return Token{PrimaryType: ErrorToken, SecondaryType: UnexpectedEOF, Buff: nil, Line: lexer.Line, Column: lexer.Column} 424 | } 425 | 426 | if chr, _ := lexer.peek(); chr == 'u' { 427 | size += 3 428 | } else if chr == 'U' { 429 | size += 7 430 | } 431 | 432 | str = append(str, next) 433 | character = next 434 | lexer.eatLastByte() 435 | } 436 | size++ 437 | } 438 | 439 | lexer.eatLastByte() // eat '"' 440 | str = append(str, '"') 441 | return Token{PrimaryType: StringLiteral, SecondaryType: SecondaryNullType, Flags: size, Buff: str, Line: line, Column: column} 442 | } 443 | 444 | func (lexer *Lexer) lexWord() Token { 445 | word := []byte{} 446 | 447 | column := lexer.Column 448 | line := lexer.Line 449 | 450 | character, _ := lexer.nextChar() 451 | word = append(word, character) 452 | 453 | for w, _ := lexer.peek(); IsIdentifierPart(w); w, _ = lexer.peek() { 454 | word = append(word, w) 455 | lexer.eatLastByte() 456 | } 457 | 458 | return Token{PrimaryType: GetWordType(string(word)), SecondaryType: SecondaryNullType, Buff: word, Line: line, Column: column} 459 | } 460 | 461 | func (lexer *Lexer) lexOperator() Token { 462 | line := lexer.Line 463 | column := lexer.Column 464 | 465 | switch character, _ := lexer.peek(); character { 466 | case '*': 467 | lexer.eatLastByte() 468 | switch next, _ := lexer.peek(); next { 469 | case '=': 470 | lexer.eatLastByte() 471 | return Token{PrimaryType: AssignmentOperator, SecondaryType: MulEqual, Buff: []byte("*="), Line: line, Column: column} 472 | default: 473 | return Token{PrimaryType: AirthmaticOperator, SecondaryType: Mul, Buff: []byte("*"), Line: line, Column: column} 474 | } 475 | case '/': 476 | lexer.eatLastByte() 477 | switch next, _ := lexer.peek(); next { 478 | case '=': 479 | lexer.eatLastByte() 480 | return Token{PrimaryType: AssignmentOperator, SecondaryType: DivEqual, Buff: []byte("/="), Line: line, Column: column} 481 | default: 482 | return Token{PrimaryType: AirthmaticOperator, SecondaryType: Div, Buff: []byte("/"), Line: line, Column: column} 483 | } 484 | case '%': 485 | lexer.eatLastByte() 486 | switch next, _ := lexer.peek(); next { 487 | case '=': 488 | lexer.eatLastByte() 489 | return Token{PrimaryType: AssignmentOperator, SecondaryType: ModulusEqual, Buff: []byte("%="), Line: line, Column: column} 490 | default: 491 | return Token{PrimaryType: AirthmaticOperator, SecondaryType: Modulus, Buff: []byte("%"), Line: line, Column: column} 492 | } 493 | case '+': 494 | lexer.eatLastByte() 495 | switch next, _ := lexer.peek(); next { 496 | case '=': 497 | lexer.eatLastByte() 498 | return Token{PrimaryType: AssignmentOperator, SecondaryType: AddEqual, Buff: []byte("+="), Line: line, Column: column} 499 | case '+': 500 | lexer.eatLastByte() 501 | return Token{PrimaryType: AssignmentOperator, SecondaryType: AddAdd, Buff: []byte("++"), Line: line, Column: column} 502 | default: 503 | return Token{PrimaryType: AirthmaticOperator, SecondaryType: Add, Buff: []byte("+"), Line: line, Column: column} 504 | } 505 | case '-': 506 | lexer.eatLastByte() 507 | switch next, _ := lexer.peek(); next { 508 | case '=': 509 | lexer.eatLastByte() 510 | return Token{PrimaryType: AssignmentOperator, SecondaryType: SubEqual, Buff: []byte("-="), Line: line, Column: column} 511 | case '-': 512 | lexer.eatLastByte() 513 | return Token{PrimaryType: AssignmentOperator, SecondaryType: SubSub, Buff: []byte("--"), Line: line, Column: column} 514 | default: 515 | return Token{PrimaryType: AirthmaticOperator, SecondaryType: Sub, Buff: []byte("-"), Line: line, Column: column} 516 | } 517 | case '=': 518 | lexer.eatLastByte() 519 | switch next, _ := lexer.peek(); next { 520 | case '=': 521 | lexer.eatLastByte() 522 | return Token{PrimaryType: RelationalOperator, SecondaryType: EqualEqual, Buff: []byte("=="), Line: line, Column: column} 523 | default: 524 | return Token{PrimaryType: AssignmentOperator, SecondaryType: Equal, Buff: []byte("="), Line: line, Column: column} 525 | } 526 | case '!': 527 | lexer.eatLastByte() 528 | switch next, _ := lexer.peek(); next { 529 | case '=': 530 | lexer.eatLastByte() 531 | return Token{PrimaryType: RelationalOperator, SecondaryType: NotEqual, Buff: []byte("!="), Line: line, Column: column} 532 | default: 533 | return Token{PrimaryType: LogicalOperator, SecondaryType: Not, Buff: []byte("!"), Line: line, Column: column} 534 | } 535 | case '>': 536 | lexer.eatLastByte() 537 | switch next, _ := lexer.peek(); next { 538 | case '=': 539 | lexer.eatLastByte() 540 | return Token{PrimaryType: RelationalOperator, SecondaryType: GreaterEqual, Buff: []byte(">="), Line: line, Column: column} 541 | case '>': 542 | lexer.eatLastByte() 543 | return Token{PrimaryType: BitwiseOperator, SecondaryType: RightShift, Buff: []byte(">>"), Line: line, Column: column} 544 | default: 545 | return Token{PrimaryType: RelationalOperator, SecondaryType: Greater, Buff: []byte(">"), Line: line, Column: column} 546 | } 547 | case '<': 548 | lexer.eatLastByte() 549 | switch next, _ := lexer.peek(); next { 550 | case '=': 551 | lexer.eatLastByte() 552 | return Token{PrimaryType: RelationalOperator, SecondaryType: LessEqual, Buff: []byte("<="), Line: line, Column: column} 553 | case '<': 554 | lexer.eatLastByte() 555 | return Token{PrimaryType: BitwiseOperator, SecondaryType: LeftShift, Buff: []byte("<<"), Line: line, Column: column} 556 | default: 557 | return Token{PrimaryType: RelationalOperator, SecondaryType: Less, Buff: []byte("<"), Line: line, Column: column} 558 | } 559 | case '&': 560 | lexer.eatLastByte() 561 | switch next, _ := lexer.peek(); next { 562 | case '&': 563 | lexer.eatLastByte() 564 | return Token{PrimaryType: LogicalOperator, SecondaryType: AndAnd, Buff: []byte("&&"), Line: line, Column: column} 565 | default: 566 | return Token{PrimaryType: BitwiseOperator, SecondaryType: And, Buff: []byte("&"), Line: line, Column: column} 567 | } 568 | case '|': 569 | lexer.eatLastByte() 570 | switch next, _ := lexer.peek(); next { 571 | case '|': 572 | lexer.eatLastByte() 573 | return Token{PrimaryType: LogicalOperator, SecondaryType: OrOr, Buff: []byte("||"), Line: line, Column: column} 574 | default: 575 | return Token{PrimaryType: BitwiseOperator, SecondaryType: Or, Buff: []byte("|"), Line: line, Column: column} 576 | } 577 | case '.': 578 | lexer.eatLastByte() 579 | switch next, _ := lexer.peek(); next { 580 | case '.': 581 | lexer.eatLastByte() 582 | return Token{PrimaryType: SpecialOperator, SecondaryType: DotDot, Buff: []byte(".."), Line: line, Column: column} 583 | default: 584 | return Token{PrimaryType: SpecialOperator, SecondaryType: Dot, Buff: []byte("."), Line: line, Column: column} 585 | } 586 | case '^': 587 | lexer.eatLastByte() 588 | return Token{PrimaryType: BitwiseOperator, SecondaryType: ExclusiveOr, Buff: []byte("^"), Line: line, Column: column} 589 | case '~': 590 | lexer.eatLastByte() 591 | return Token{PrimaryType: BitwiseOperator, SecondaryType: BitwiseNot, Buff: []byte("~"), Line: line, Column: column} 592 | case ':': 593 | lexer.eatLastByte() 594 | return Token{PrimaryType: SpecialOperator, SecondaryType: Colon, Buff: []byte(":"), Line: line, Column: column} 595 | case '?': 596 | lexer.eatLastByte() 597 | return Token{PrimaryType: SpecialOperator, SecondaryType: QuesMark, Buff: []byte("?"), Line: line, Column: column} 598 | } 599 | 600 | return Token{PrimaryType: ErrorToken, SecondaryType: NotFound, Buff: nil, Line: line, Column: column} 601 | } 602 | 603 | func (lexer *Lexer) lexDelimiter() Token { 604 | line := lexer.Line 605 | column := lexer.Column 606 | 607 | switch character, _ := lexer.peek(); character { 608 | case '(': 609 | lexer.eatLastByte() 610 | return Token{Buff: []byte("("), PrimaryType: LeftParen, SecondaryType: SecondaryNullType, Line: line, Column: column} 611 | case ')': 612 | lexer.eatLastByte() 613 | return Token{Buff: []byte(")"), PrimaryType: RightParen, SecondaryType: SecondaryNullType, Line: line, Column: column} 614 | case '{': 615 | lexer.eatLastByte() 616 | return Token{Buff: []byte("{"), PrimaryType: LeftCurlyBrace, SecondaryType: SecondaryNullType, Line: line, Column: column} 617 | case '}': 618 | lexer.eatLastByte() 619 | return Token{Buff: []byte("}"), PrimaryType: RightCurlyBrace, SecondaryType: SecondaryNullType, Line: line, Column: column} 620 | case '[': 621 | lexer.eatLastByte() 622 | return Token{Buff: []byte("["), PrimaryType: LeftBrace, SecondaryType: SecondaryNullType, Line: line, Column: column} 623 | case ']': 624 | lexer.eatLastByte() 625 | return Token{Buff: []byte("]"), PrimaryType: RightBrace, SecondaryType: SecondaryNullType, Line: line, Column: column} 626 | case ';': 627 | lexer.eatLastByte() 628 | return Token{Buff: []byte(";"), PrimaryType: SemiColon, SecondaryType: SecondaryNullType, Line: line, Column: column} 629 | case ',': 630 | lexer.eatLastByte() 631 | return Token{Buff: []byte(","), PrimaryType: Comma, SecondaryType: SecondaryNullType, Line: line, Column: column} 632 | } 633 | 634 | return Token{PrimaryType: ErrorToken, SecondaryType: NotFound, Buff: nil, Line: line, Column: column} 635 | } 636 | -------------------------------------------------------------------------------- /src/parser/parser.go: -------------------------------------------------------------------------------- 1 | package parser 2 | 3 | import "error" 4 | 5 | type Parser struct { 6 | Lexer *Lexer 7 | tokens []Token 8 | position int 9 | Forks map[byte]int 10 | } 11 | 12 | func ParseFile(inputStream *Lexer) File { 13 | parser := Parser{} 14 | 15 | parser.Lexer = inputStream 16 | parser.position = 0 17 | parser.tokens = []Token{} 18 | parser.Forks = map[byte]int{} 19 | 20 | file := File{} 21 | 22 | for parser.ReadToken().PrimaryType != EOF { 23 | file.Statements = append(file.Statements, parser.parseGlobalStatement()) 24 | } 25 | 26 | return file 27 | } 28 | 29 | func (parser *Parser) pos() (int, int) { 30 | parser.Lexer.PrepNext() 31 | return parser.Lexer.Line, parser.Lexer.Column 32 | } 33 | 34 | func (parser *Parser) error(message string, line, column int) { 35 | error.New(parser.Lexer.Path+": "+message, line, column) 36 | } 37 | 38 | func (parser *Parser) ReadToken() Token { 39 | for parser.position >= len(parser.tokens) { 40 | parser.tokens = append(parser.tokens, parser.Lexer.NextToken()) 41 | } 42 | return parser.tokens[parser.position] 43 | } 44 | 45 | func (parser *Parser) eatLastToken() { 46 | parser.position++ 47 | } 48 | 49 | func (parser *Parser) fork(num byte) { 50 | parser.Forks[num] = parser.position 51 | } 52 | 53 | func (parser *Parser) moveToFork(num byte) { 54 | parser.position = parser.Forks[num] 55 | } 56 | 57 | func (parser *Parser) expect(primary PrimaryTokenType, secondary SecondaryTokenType) Token { 58 | token := parser.ReadToken() 59 | 60 | if primary == PrimaryNullType { 61 | if token.SecondaryType != secondary { 62 | parser.error("expected '"+SecondaryTypes[secondary]+"', got '"+token.Serialize()+"'.", token.Line, token.Column) 63 | } 64 | } else if secondary == SecondaryNullType { 65 | if token.PrimaryType != primary { 66 | parser.error("expected '"+PrimaryTypes[primary]+"', got '"+token.Serialize()+"'.", token.Line, token.Column) 67 | } 68 | } else { 69 | if token.PrimaryType != primary || token.SecondaryType != secondary { 70 | parser.error("expected '"+SecondaryTypes[secondary]+"', got '"+token.Serialize()+"'.", token.Line, token.Column) 71 | } 72 | } 73 | 74 | return token 75 | } 76 | 77 | func (parser *Parser) parseGlobalStatementNoSemicolon() Statement { 78 | var statement Statement 79 | 80 | switch token := parser.ReadToken(); token.PrimaryType { 81 | case ImportKeyword: 82 | parser.eatLastToken() 83 | statement = parser.parseImport() 84 | case StructKeyword: 85 | parser.eatLastToken() 86 | statement = parser.parseStructTypedef(false) 87 | case EnumKeyword: 88 | parser.eatLastToken() 89 | statement = parser.parseEnumTypedef() 90 | case TupleKeyword: 91 | parser.eatLastToken() 92 | statement = parser.parseTupleTypedef(false) 93 | case UnionKeyword: 94 | parser.eatLastToken() 95 | statement = parser.parseUnionTypedef() 96 | case TypedefKeyword: 97 | parser.eatLastToken() 98 | statement = parser.parseTypedef() 99 | case ExportKeyword: 100 | parser.eatLastToken() 101 | statement = ExportStatement{Stmt: parser.parseGlobalStatementNoSemicolon()} 102 | case FunctionKeyword: 103 | parser.eatLastToken() 104 | statement = parser.parseFunctionDec() 105 | case Identifier: 106 | statement = parser.parseGlobalDeclaration() 107 | default: 108 | // Error: Invalid token {token} 109 | } 110 | return statement 111 | } 112 | 113 | func (parser *Parser) parseGlobalStatement() Statement { 114 | var statement Statement 115 | 116 | switch token := parser.ReadToken(); token.PrimaryType { 117 | case ImportKeyword: 118 | parser.eatLastToken() 119 | return parser.parseImport() 120 | case StructKeyword: 121 | parser.eatLastToken() 122 | return parser.parseStructTypedef(false) 123 | case EnumKeyword: 124 | parser.eatLastToken() 125 | return parser.parseEnumTypedef() 126 | case TupleKeyword: 127 | parser.eatLastToken() 128 | return parser.parseTupleTypedef(false) 129 | case UnionKeyword: 130 | parser.eatLastToken() 131 | return parser.parseUnionTypedef() 132 | case TypedefKeyword: 133 | parser.eatLastToken() 134 | return parser.parseTypedef() 135 | case ExportKeyword: 136 | parser.eatLastToken() 137 | return ExportStatement{Stmt: parser.parseGlobalStatement()} 138 | case FunctionKeyword: 139 | parser.eatLastToken() 140 | return parser.parseFunctionDec() 141 | case Identifier: 142 | statement = parser.parseGlobalDeclaration() 143 | case SemiColon: 144 | parser.eatLastToken() 145 | return NullStatement{} 146 | default: 147 | // Error: Invalid token {token} 148 | } 149 | parser.expect(SemiColon, SecondaryNullType) 150 | parser.eatLastToken() 151 | return statement 152 | } 153 | 154 | func (parser *Parser) parseStatementNoSemicolon() Statement { 155 | line, column := parser.pos() 156 | var st Statement = NullStatement{Line: line, Column: column} 157 | 158 | switch parser.ReadToken().PrimaryType { 159 | case IfKeyword: 160 | st = parser.parseIfElse() 161 | case SwitchKeyword: 162 | st = parser.parseSwitch() 163 | case ForKeyword: 164 | st = parser.parseLoop() 165 | case LeftCurlyBrace: 166 | st = parser.parseBlock() 167 | case ReturnKeyword: 168 | st = parser.parseReturn() 169 | case BreakKeyword: 170 | parser.eatLastToken() 171 | st = Break{Line: line, Column: column} 172 | case StructKeyword: 173 | parser.eatLastToken() 174 | st = parser.parseStructTypedef(false) 175 | case EnumKeyword: 176 | parser.eatLastToken() 177 | st = parser.parseEnumTypedef() 178 | case TupleKeyword: 179 | parser.eatLastToken() 180 | st = parser.parseTupleTypedef(false) 181 | case UnionKeyword: 182 | parser.eatLastToken() 183 | st = parser.parseUnionTypedef() 184 | case TypedefKeyword: 185 | parser.eatLastToken() 186 | st = parser.parseTypedef() 187 | case ContinueKeyword: 188 | parser.eatLastToken() 189 | st = Continue{Line: line, Column: column} 190 | case DeleteKeyword: 191 | parser.eatLastToken() 192 | st = Delete{Exprs: parser.parseExpressionArray(), Line: line, Column: column} 193 | case FunctionKeyword: 194 | parser.eatLastToken() 195 | st = parser.parseFunctionDec() 196 | case LabelKeyword: 197 | parser.eatLastToken() 198 | st = Label{Line: line, Column: column, Name: parser.expect(Identifier, SecondaryNullType)} 199 | parser.eatLastToken() 200 | parser.expect(PrimaryNullType, Colon) 201 | parser.eatLastToken() 202 | case GotoKeyword: 203 | parser.eatLastToken() 204 | st = Goto{Line: line, Column: column, Name: parser.expect(Identifier, SecondaryNullType)} 205 | parser.eatLastToken() 206 | default: 207 | parser.fork(0) 208 | expr := parser.parseExpression() 209 | 210 | if expr == nil { 211 | break 212 | } 213 | 214 | if token := parser.ReadToken(); token.PrimaryType == AssignmentOperator { 215 | parser.moveToFork(0) 216 | st = parser.parseAssignment() 217 | } else if token.SecondaryType == Colon { 218 | parser.moveToFork(0) 219 | st = parser.parseDeclaration() 220 | } else if token.PrimaryType == Comma { 221 | parser.moveToFork(0) 222 | st = parser.parseDeclarationOrAssignment() 223 | } else { 224 | st = expr 225 | } 226 | } 227 | 228 | return st 229 | } 230 | 231 | func (parser *Parser) parseStatement() Statement { 232 | line, column := parser.pos() 233 | var st Statement = NullStatement{Line: line, Column: column} 234 | 235 | switch parser.ReadToken().PrimaryType { 236 | case IfKeyword: 237 | return parser.parseIfElse() 238 | case SwitchKeyword: 239 | return parser.parseSwitch() 240 | case ForKeyword: 241 | return parser.parseLoop() 242 | case LeftCurlyBrace: 243 | return parser.parseBlock() 244 | case FunctionKeyword: 245 | parser.eatLastToken() 246 | return parser.parseFunctionDec() 247 | case ReturnKeyword: 248 | st = parser.parseReturn() 249 | case StructKeyword: 250 | parser.eatLastToken() 251 | return parser.parseStructTypedef(false) 252 | case EnumKeyword: 253 | parser.eatLastToken() 254 | return parser.parseEnumTypedef() 255 | case TupleKeyword: 256 | parser.eatLastToken() 257 | return parser.parseTupleTypedef(false) 258 | case UnionKeyword: 259 | parser.eatLastToken() 260 | return parser.parseUnionTypedef() 261 | case TypedefKeyword: 262 | parser.eatLastToken() 263 | return parser.parseTypedef() 264 | case BreakKeyword: 265 | parser.eatLastToken() 266 | st = Break{Line: line, Column: column} 267 | case ContinueKeyword: 268 | parser.eatLastToken() 269 | st = Continue{Line: line, Column: column} 270 | case DeleteKeyword: 271 | parser.eatLastToken() 272 | st = Delete{Exprs: parser.parseExpressionArray(), Line: line, Column: column} 273 | case LabelKeyword: 274 | parser.eatLastToken() 275 | st = Label{Line: line, Column: column, Name: parser.expect(Identifier, SecondaryNullType)} 276 | parser.eatLastToken() 277 | parser.expect(PrimaryNullType, Colon) 278 | parser.eatLastToken() 279 | return st 280 | case GotoKeyword: 281 | parser.eatLastToken() 282 | st = Goto{Line: line, Column: column, Name: parser.expect(Identifier, SecondaryNullType)} 283 | parser.eatLastToken() 284 | case SemiColon: 285 | parser.eatLastToken() 286 | return NullStatement{} 287 | default: 288 | parser.fork(0) 289 | expr := parser.parseExpression() 290 | 291 | if token := parser.ReadToken(); token.PrimaryType == AssignmentOperator { 292 | parser.moveToFork(0) 293 | st = parser.parseAssignment() 294 | } else if token.SecondaryType == Colon { 295 | parser.moveToFork(0) 296 | st = parser.parseDeclaration() 297 | } else if token.PrimaryType == Comma { 298 | parser.moveToFork(0) 299 | st = parser.parseDeclarationOrAssignment() 300 | } else { 301 | st = expr 302 | } 303 | } 304 | 305 | parser.expect(SemiColon, SecondaryNullType) 306 | parser.eatLastToken() 307 | return st 308 | } 309 | 310 | func (parser *Parser) parseTypedef() Typedef { 311 | line, column := parser.pos() 312 | 313 | Name := parser.expect(Identifier, SecondaryNullType) 314 | parser.eatLastToken() 315 | 316 | return Typedef{Name: Name, Type: parser.parseType(), Line: line, Column: column} 317 | } 318 | 319 | func (parser *Parser) parseUnionTypedef() Typedef { 320 | line, column := parser.pos() 321 | union := Typedef{Line: line, Column: column} 322 | 323 | union.Name = parser.expect(Identifier, SecondaryNullType) 324 | parser.eatLastToken() 325 | 326 | union.Type = parser.parseUnionType() 327 | return union 328 | } 329 | 330 | func (parser *Parser) parseStructTypedef(allowUnnamed bool) Typedef { 331 | line, column := parser.pos() 332 | strct := Typedef{Line: line, Column: column} 333 | 334 | if token := parser.ReadToken(); token.PrimaryType == Identifier { 335 | parser.eatLastToken() 336 | strct.Name = token 337 | } else if !allowUnnamed { 338 | // Error: expected identifier, got {token} 339 | } 340 | 341 | strct.Type = parser.parseStructType() 342 | return strct 343 | } 344 | 345 | func (parser *Parser) parseTupleTypedef(allowUnnamed bool) Typedef { 346 | line, column := parser.pos() 347 | tupl := Typedef{Line: line, Column: column} 348 | 349 | if token := parser.ReadToken(); token.PrimaryType == Identifier { 350 | parser.eatLastToken() 351 | tupl.Name = token 352 | } else if !allowUnnamed { 353 | // Error: expected identifier, got {token} 354 | } 355 | 356 | tupl.Type = parser.parseTupleType() 357 | return tupl 358 | } 359 | 360 | func (parser *Parser) parseEnumTypedef() Typedef { 361 | line, column := parser.pos() 362 | enum := Typedef{Line: line, Column: column} 363 | 364 | enum.Name = parser.expect(Identifier, SecondaryNullType) 365 | parser.eatLastToken() 366 | 367 | enum.Type = parser.parseEnumType() 368 | return enum 369 | } 370 | 371 | func (parser *Parser) parseImport() Import { 372 | line, column := parser.pos() 373 | imprt := Import{Line: line, Column: column} 374 | 375 | if token := parser.ReadToken(); token.PrimaryType == LeftParen { 376 | parser.eatLastToken() 377 | 378 | imprt.Paths = append(imprt.Paths, parser.expect(StringLiteral, SecondaryNullType)) 379 | parser.eatLastToken() 380 | 381 | for token2 := parser.ReadToken(); token2.PrimaryType == Comma; token2 = parser.ReadToken() { 382 | parser.eatLastToken() 383 | imprt.Paths = append(imprt.Paths, parser.expect(StringLiteral, SecondaryNullType)) 384 | parser.eatLastToken() 385 | } 386 | 387 | parser.expect(RightParen, SecondaryNullType) 388 | parser.eatLastToken() 389 | 390 | } else if token.PrimaryType == StringLiteral { 391 | imprt.Paths = append(imprt.Paths, token) 392 | parser.eatLastToken() 393 | } else { 394 | // Error: expected string literal, got {token} 395 | } 396 | 397 | return imprt 398 | } 399 | 400 | func (parser *Parser) parseType() Type { 401 | return parser.parseTypeAHH(0) 402 | } 403 | 404 | func (parser *Parser) parseTypeArray() []Type { 405 | if token := parser.ReadToken(); token.PrimaryType == RightParen { 406 | return []Type{VoidType.Type} 407 | } 408 | 409 | types := []Type{parser.parseType()} 410 | 411 | for token := parser.ReadToken(); token.PrimaryType == Comma; token = parser.ReadToken() { 412 | parser.eatLastToken() 413 | types = append(types, parser.parseType()) 414 | } 415 | 416 | return types 417 | } 418 | 419 | func (parser *Parser) parseFunctionType() FuncType { 420 | line, column := parser.pos() 421 | function := FuncType{Line: line, Column: column} 422 | function.Type = OrdFunction 423 | function.Mut = true 424 | 425 | if token := parser.ReadToken(); token.PrimaryType == AsyncKeyword { 426 | function.Type = AsyncFunction 427 | parser.eatLastToken() 428 | } else if token.PrimaryType == WorkKeyword { 429 | function.Type = WorkFunction 430 | parser.eatLastToken() 431 | } 432 | 433 | // parse arguments 434 | parser.expect(LeftParen, SecondaryNullType) 435 | parser.eatLastToken() 436 | 437 | function.ArgTypes = parser.parseTypeArray() 438 | 439 | parser.expect(RightParen, SecondaryNullType) 440 | parser.eatLastToken() 441 | 442 | // parse return types 443 | if token := parser.ReadToken(); token.PrimaryType != Comma && token.PrimaryType != SemiColon && token.SecondaryType != Equal && token.PrimaryType != RightParen && token.PrimaryType != LeftCurlyBrace { 444 | function.ReturnTypes = []Type{parser.parseType()} 445 | } else { 446 | function.ReturnTypes = []Type{VoidType.Type} 447 | } 448 | 449 | return function 450 | } 451 | 452 | func (parser *Parser) parseStructType() StructType { 453 | line, column := parser.pos() 454 | strct := StructType{Line: line, Column: column} 455 | 456 | parser.expect(LeftCurlyBrace, SecondaryNullType) 457 | parser.eatLastToken() 458 | 459 | for { 460 | if parser.ReadToken().SecondaryType == DotDot { 461 | parser.eatLastToken() 462 | strct.SuperStructs = append(strct.SuperStructs, parser.parseExpression()) 463 | } else { 464 | strct.Props = append(strct.Props, parser.parseDeclaration()) 465 | } 466 | 467 | if parser.ReadToken().PrimaryType == SemiColon { 468 | parser.eatLastToken() 469 | } 470 | 471 | if parser.ReadToken().PrimaryType == RightCurlyBrace { 472 | parser.eatLastToken() 473 | break 474 | } 475 | } 476 | 477 | return strct 478 | } 479 | 480 | func (parser *Parser) parseTupleType() TupleType { 481 | line, column := parser.pos() 482 | tupl := TupleType{Line: line, Column: column} 483 | 484 | parser.expect(LeftCurlyBrace, SecondaryNullType) 485 | parser.eatLastToken() 486 | 487 | tupl.Types = []Type{parser.parseType()} 488 | 489 | for token := parser.ReadToken(); token.PrimaryType == Comma; token = parser.ReadToken() { 490 | parser.eatLastToken() 491 | 492 | if parser.ReadToken().PrimaryType == RightCurlyBrace { 493 | parser.eatLastToken() 494 | return tupl 495 | } 496 | tupl.Types = append(tupl.Types, parser.parseType()) 497 | } 498 | 499 | parser.expect(RightCurlyBrace, SecondaryNullType) 500 | parser.eatLastToken() 501 | 502 | return tupl 503 | } 504 | 505 | func (parser *Parser) parseUnionType() UnionType { 506 | line, column := parser.pos() 507 | union := UnionType{Line: line, Column: column} 508 | 509 | parser.expect(LeftCurlyBrace, SecondaryNullType) 510 | parser.eatLastToken() 511 | 512 | for tok := parser.ReadToken(); tok.PrimaryType != RightCurlyBrace; tok = parser.ReadToken() { 513 | union.Identifiers = append(union.Identifiers, parser.expect(Identifier, SecondaryNullType)) 514 | parser.eatLastToken() 515 | 516 | parser.expect(PrimaryNullType, Colon) 517 | parser.eatLastToken() 518 | 519 | union.Types = append(union.Types, parser.parseType()) 520 | 521 | if parser.ReadToken().PrimaryType == SemiColon { 522 | parser.eatLastToken() 523 | } 524 | } 525 | 526 | parser.eatLastToken() 527 | return union 528 | } 529 | 530 | func (parser *Parser) parseEnumType() EnumType { 531 | line, column := parser.pos() 532 | enum := EnumType{Line: line, Column: column} 533 | 534 | parser.expect(LeftCurlyBrace, SecondaryNullType) 535 | parser.eatLastToken() 536 | 537 | enum.Identifiers = append(enum.Identifiers, parser.expect(Identifier, SecondaryNullType)) 538 | parser.eatLastToken() 539 | 540 | if parser.ReadToken().SecondaryType == Equal { 541 | parser.eatLastToken() 542 | enum.Values = append(enum.Values, parser.parseExpression()) 543 | } else { 544 | enum.Values = append(enum.Values, nil) 545 | } 546 | 547 | for parser.ReadToken().PrimaryType == Comma { 548 | parser.eatLastToken() 549 | 550 | if parser.ReadToken().PrimaryType == RightCurlyBrace { 551 | parser.eatLastToken() 552 | return enum 553 | } 554 | 555 | enum.Identifiers = append(enum.Identifiers, parser.expect(Identifier, SecondaryNullType)) 556 | parser.eatLastToken() 557 | 558 | if parser.ReadToken().SecondaryType == Equal { 559 | parser.eatLastToken() 560 | enum.Values = append(enum.Values, parser.parseExpression()) 561 | } else { 562 | enum.Values = append(enum.Values, nil) 563 | } 564 | } 565 | 566 | parser.expect(RightCurlyBrace, SecondaryNullType) 567 | parser.eatLastToken() 568 | 569 | return enum 570 | } 571 | 572 | func (parser *Parser) parseExpressionArray() []Expression { 573 | exprs := []Expression{} 574 | exprs = append(exprs, parser.parseExpression()) 575 | 576 | for token := parser.ReadToken(); token.PrimaryType == Comma; token = parser.ReadToken() { 577 | parser.eatLastToken() 578 | exprs = append(exprs, parser.parseExpression()) 579 | } 580 | 581 | return exprs 582 | } 583 | 584 | // var1, var2, ...varn :[type1, type2, ...typen][= val1, val2, ...valn] 585 | func (parser *Parser) parseDeclaration() Declaration { 586 | if token := parser.ReadToken(); token.PrimaryType == FunctionKeyword { 587 | parser.eatLastToken() 588 | return parser.parseFunctionDec() 589 | } 590 | 591 | line, column := parser.pos() 592 | declaration := Declaration{Line: line, Column: column} 593 | 594 | declaration.Identifiers = append(declaration.Identifiers, parser.expect(Identifier, SecondaryNullType)) 595 | parser.eatLastToken() 596 | 597 | for parser.ReadToken().PrimaryType == Comma { 598 | parser.eatLastToken() 599 | 600 | declaration.Identifiers = append(declaration.Identifiers, parser.expect(Identifier, SecondaryNullType)) 601 | parser.eatLastToken() 602 | } 603 | 604 | parser.expect(PrimaryNullType, Colon) 605 | parser.eatLastToken() 606 | 607 | if next := parser.ReadToken(); next.SecondaryType != Equal { 608 | declaration.Types = parser.parseTypeArray() 609 | } else { 610 | declaration.Types = []Type{} 611 | } 612 | 613 | if next := parser.ReadToken(); next.SecondaryType == Equal { 614 | parser.eatLastToken() 615 | declaration.Values = parser.parseExpressionArray() 616 | } 617 | return declaration 618 | } 619 | 620 | func (parser *Parser) parseGlobalDeclaration() Declaration { 621 | line, column := parser.pos() 622 | declaration := Declaration{Line: line, Column: column} 623 | 624 | if token := parser.ReadToken(); token.PrimaryType == FunctionKeyword { 625 | return parser.parseFunctionDec() 626 | } 627 | 628 | declaration.Identifiers = append(declaration.Identifiers, parser.expect(Identifier, SecondaryNullType)) 629 | parser.eatLastToken() 630 | 631 | for parser.ReadToken().PrimaryType == Comma { 632 | parser.eatLastToken() 633 | 634 | declaration.Identifiers = append(declaration.Identifiers, parser.expect(Identifier, SecondaryNullType)) 635 | parser.eatLastToken() 636 | } 637 | 638 | parser.expect(PrimaryNullType, Colon) 639 | parser.eatLastToken() 640 | 641 | if next := parser.ReadToken(); next.SecondaryType != Equal { 642 | declaration.Types = parser.parseTypeArray() 643 | } else { 644 | declaration.Types = []Type{} 645 | } 646 | 647 | if next := parser.ReadToken(); next.SecondaryType == Equal { 648 | parser.eatLastToken() 649 | declaration.Values = parser.parseExpressionArray() 650 | } 651 | return declaration 652 | } 653 | 654 | func (parser *Parser) parseFunctionDec() Declaration { 655 | line, column := parser.pos() 656 | function := FuncExpr{Line: line, Column: column} 657 | typ := FuncType{Line: line, Column: column, Mut: false} 658 | 659 | typ.Type = OrdFunction 660 | 661 | if token := parser.ReadToken(); token.PrimaryType == AsyncKeyword { 662 | typ.Type = AsyncFunction 663 | parser.eatLastToken() 664 | } else if token.PrimaryType == WorkKeyword { 665 | typ.Type = WorkFunction 666 | parser.eatLastToken() 667 | } 668 | 669 | Name := parser.expect(Identifier, SecondaryNullType) 670 | parser.eatLastToken() 671 | 672 | // parse arguments 673 | parser.expect(LeftParen, SecondaryNullType) 674 | parser.eatLastToken() 675 | 676 | if token := parser.ReadToken(); token.PrimaryType != RightParen { 677 | typ.ArgNames = append(typ.ArgNames, parser.expect(Identifier, SecondaryNullType)) 678 | parser.eatLastToken() 679 | 680 | parser.expect(PrimaryNullType, Colon) 681 | parser.eatLastToken() 682 | 683 | typ.ArgTypes = append(typ.ArgTypes, parser.parseType()) 684 | 685 | for token := parser.ReadToken(); token.PrimaryType == Comma; token = parser.ReadToken() { 686 | parser.eatLastToken() 687 | typ.ArgNames = append(typ.ArgNames, parser.expect(Identifier, SecondaryNullType)) 688 | parser.eatLastToken() 689 | 690 | parser.expect(PrimaryNullType, Colon) 691 | parser.eatLastToken() 692 | 693 | typ.ArgTypes = append(typ.ArgTypes, parser.parseType()) 694 | } 695 | } else { 696 | typ.ArgTypes = []Type{VoidType.Type} 697 | } 698 | 699 | parser.expect(RightParen, SecondaryNullType) 700 | parser.eatLastToken() 701 | 702 | // parse return type 703 | if token := parser.ReadToken(); token.PrimaryType != LeftCurlyBrace { 704 | typ.ReturnTypes = []Type{parser.parseType()} 705 | } else { 706 | typ.ReturnTypes = []Type{VoidType.Type} 707 | } 708 | 709 | // parse code block 710 | function.Block = parser.parseBlock() 711 | function.Type = typ 712 | 713 | return Declaration{Identifiers: []Token{Name}, Types: []Type{typ}, Values: []Expression{function}, Line: line, Column: column} 714 | } 715 | 716 | func (parser *Parser) parseIfElse() IfElseBlock { 717 | line, column := parser.pos() 718 | ifelseblock := IfElseBlock{Line: line, Column: column} 719 | 720 | parser.eatLastToken() 721 | statement := parser.parseStatementNoSemicolon() 722 | 723 | if parser.ReadToken().PrimaryType == SemiColon { 724 | parser.eatLastToken() 725 | ifelseblock.InitStatement = statement 726 | ifelseblock.HasInitStmt = true 727 | ifelseblock.Conditions = append(ifelseblock.Conditions, parser.parseExpression()) 728 | } else { 729 | switch statement.(type) { 730 | case Expression: 731 | ifelseblock.Conditions = append(ifelseblock.Conditions, statement.(Expression)) 732 | default: 733 | // Error: expected an expression, got {statement} 734 | } 735 | } 736 | 737 | ifelseblock.Blocks = append(ifelseblock.Blocks, parser.parseBlock()) 738 | 739 | for token := parser.ReadToken(); token.PrimaryType == ElseKeyword; token = parser.ReadToken() { 740 | parser.eatLastToken() 741 | if next := parser.ReadToken(); next.PrimaryType == IfKeyword { 742 | parser.eatLastToken() 743 | ifelseblock.Conditions = append(ifelseblock.Conditions, parser.parseExpression()) 744 | ifelseblock.Blocks = append(ifelseblock.Blocks, parser.parseBlock()) 745 | } else { 746 | ifelseblock.ElseBlock = parser.parseBlock() 747 | } 748 | } 749 | 750 | return ifelseblock 751 | } 752 | 753 | func (parser *Parser) parseLoop() Loop { 754 | line, column := parser.pos() 755 | loop := Loop{Line: line, Column: column} 756 | loop.Type = 0 757 | 758 | parser.eatLastToken() 759 | 760 | if parser.ReadToken().PrimaryType == LeftCurlyBrace { 761 | loop.Type = loop.Type | NoneLoop 762 | loop.Block = parser.parseBlock() 763 | return loop 764 | } 765 | 766 | statement := parser.parseStatementNoSemicolon() 767 | 768 | if parser.ReadToken().PrimaryType == SemiColon { 769 | parser.eatLastToken() 770 | 771 | loop.Type = InitLoop 772 | loop.InitStatement = statement 773 | 774 | st := parser.parseStatementNoSemicolon() 775 | 776 | switch st.(type) { 777 | case Expression: 778 | loop.Condition = st.(Expression) 779 | loop.Type = loop.Type | CondLoop 780 | case NullStatement: 781 | break 782 | default: 783 | // Error: expected expression, got {st} 784 | } 785 | 786 | if parser.ReadToken().PrimaryType == SemiColon { 787 | parser.eatLastToken() 788 | } 789 | if parser.ReadToken().PrimaryType == LeftCurlyBrace { 790 | loop.Block = parser.parseBlock() 791 | return loop 792 | } 793 | 794 | loop.LoopStatement = parser.parseStatementNoSemicolon() 795 | loop.Type = loop.Type | LoopLoop 796 | } else { 797 | switch statement.(type) { 798 | case Expression: 799 | loop.Type = CondLoop 800 | loop.Condition = statement.(Expression) 801 | default: 802 | // Error: expected an expression, got {statement} 803 | } 804 | } 805 | 806 | loop.Block = parser.parseBlock() 807 | return loop 808 | } 809 | 810 | func (parser *Parser) parseSwitch() Switch { 811 | line, column := parser.pos() 812 | swtch := Switch{Line: line, Column: column} 813 | 814 | parser.eatLastToken() 815 | if parser.ReadToken().PrimaryType != LeftCurlyBrace { 816 | statement := parser.parseStatementNoSemicolon() 817 | 818 | if parser.ReadToken().PrimaryType == SemiColon { 819 | parser.eatLastToken() 820 | swtch.InitStatement = statement 821 | 822 | if parser.ReadToken().PrimaryType != LeftCurlyBrace { 823 | statement2 := parser.parseStatementNoSemicolon() 824 | 825 | switch statement2.(type) { 826 | case Expression: 827 | swtch.Type = InitCondSwitch 828 | swtch.Expr = statement2.(Expression) 829 | default: 830 | // Error: Expected an expression, got {statement2} 831 | } 832 | } 833 | } else { 834 | switch statement.(type) { 835 | case Expression: 836 | swtch.Type = CondSwitch 837 | swtch.Expr = statement.(Expression) 838 | default: 839 | // Error: expected an expression, got {statement} 840 | } 841 | } 842 | parser.expect(LeftCurlyBrace, SecondaryNullType) 843 | } else { 844 | swtch.Type = NoneSwtch 845 | } 846 | 847 | parser.eatLastToken() 848 | 849 | for parser.ReadToken().PrimaryType == CaseKeyword { 850 | parser.eatLastToken() 851 | 852 | line, column := parser.pos() 853 | Case := CaseStruct{Line: line, Column: column} 854 | Case.Condition = parser.parseExpression() 855 | 856 | parser.expect(PrimaryNullType, Colon) 857 | parser.eatLastToken() 858 | 859 | for token := parser.ReadToken(); token.PrimaryType != CaseKeyword && token.PrimaryType != DefaultKeyword; token = parser.ReadToken() { 860 | switch token.PrimaryType { 861 | case SemiColon: 862 | parser.eatLastToken() 863 | case RightCurlyBrace: 864 | swtch.Cases = append(swtch.Cases, Case) 865 | parser.eatLastToken() 866 | return swtch 867 | default: 868 | Case.Block.Statements = append(Case.Block.Statements, parser.parseStatement()) 869 | } 870 | } 871 | swtch.Cases = append(swtch.Cases, Case) 872 | } 873 | if parser.ReadToken().PrimaryType == DefaultKeyword { 874 | parser.eatLastToken() 875 | parser.expect(PrimaryNullType, Colon) 876 | parser.eatLastToken() 877 | 878 | line, column := parser.pos() 879 | DefaultCase := Block{Line: line, Column: column} 880 | swtch.HasDefaultCase = true 881 | 882 | for token := parser.ReadToken(); token.PrimaryType != CaseKeyword; token = parser.ReadToken() { 883 | switch token.PrimaryType { 884 | case SemiColon: 885 | parser.eatLastToken() 886 | case RightCurlyBrace: 887 | swtch.DefaultCase = DefaultCase 888 | parser.eatLastToken() 889 | return swtch 890 | default: 891 | DefaultCase.Statements = append(DefaultCase.Statements, parser.parseStatement()) 892 | } 893 | } 894 | } 895 | return swtch 896 | } 897 | 898 | func (parser *Parser) parseBlock() Block { 899 | line, column := parser.pos() 900 | block := Block{Line: line, Column: column} 901 | 902 | parser.expect(LeftCurlyBrace, SecondaryNullType) 903 | parser.eatLastToken() 904 | 905 | for token := parser.ReadToken(); token.PrimaryType != RightCurlyBrace; token = parser.ReadToken() { 906 | block.Statements = append(block.Statements, parser.parseStatement()) 907 | } 908 | 909 | parser.eatLastToken() 910 | return block 911 | } 912 | 913 | func (parser *Parser) parseReturn() Return { 914 | line, column := parser.pos() 915 | parser.eatLastToken() 916 | return Return{Values: parser.parseExpressionArray(), Line: line, Column: column} 917 | } 918 | 919 | func (parser *Parser) parseDefer() Defer { 920 | return Defer{Stmt: parser.parseStatement()} 921 | } 922 | 923 | func (parser *Parser) parseAssignment() Assignment { 924 | line, column := parser.pos() 925 | as := Assignment{Line: line, Column: column} 926 | 927 | as.Variables = parser.parseExpressionArray() 928 | 929 | parser.expect(AssignmentOperator, SecondaryNullType) 930 | as.Op = parser.ReadToken() 931 | parser.eatLastToken() 932 | 933 | if as.Op.SecondaryType != AddAdd && as.Op.SecondaryType != SubSub { 934 | as.Values = parser.parseExpressionArray() 935 | } 936 | return as 937 | } 938 | 939 | func (parser *Parser) parseDeclarationOrAssignment() Statement { 940 | parser.fork(1) 941 | parser.parseExpressionArray() 942 | 943 | token := parser.ReadToken() 944 | if token.PrimaryType == AssignmentOperator { 945 | parser.moveToFork(1) 946 | return parser.parseAssignment() 947 | } else if token.SecondaryType == Colon { 948 | parser.moveToFork(1) 949 | return parser.parseDeclaration() 950 | } 951 | 952 | parser.error("Unexpected token {token}, expected assignment orperator or colon, got {token}", token.Line, token.Column) 953 | return Declaration{} 954 | } 955 | 956 | func (parser *Parser) parseCompoundLiteral() CompoundLiteralData { 957 | parser.fork(2) 958 | line, column := parser.pos() 959 | 960 | state := 0 961 | cl := CompoundLiteralData{Line: line, Column: column} 962 | c := true 963 | 964 | for next := parser.ReadToken(); c; next = parser.ReadToken() { 965 | switch state { 966 | case 0: 967 | if next.PrimaryType == Identifier { 968 | parser.eatLastToken() 969 | state = 1 970 | break 971 | } 972 | state = 2 973 | case 1: 974 | if next.SecondaryType == Colon { 975 | parser.moveToFork(2) 976 | state = 3 977 | break 978 | } 979 | parser.moveToFork(2) 980 | state = 2 981 | case 2: 982 | if next.PrimaryType == RightCurlyBrace { 983 | c = false 984 | break 985 | } 986 | cl.Values = append(cl.Values, parser.parseExpr(0)) 987 | 988 | if parser.ReadToken().PrimaryType == RightCurlyBrace { 989 | c = false 990 | break 991 | } 992 | 993 | parser.expect(Comma, SecondaryNullType) 994 | parser.eatLastToken() 995 | case 3: 996 | if next.PrimaryType == RightCurlyBrace { 997 | c = false 998 | break 999 | } 1000 | cl.Fields = append(cl.Fields, parser.expect(Identifier, SecondaryNullType)) 1001 | parser.eatLastToken() 1002 | 1003 | parser.expect(PrimaryNullType, Colon) 1004 | parser.eatLastToken() 1005 | 1006 | cl.Values = append(cl.Values, parser.parseExpr(0)) 1007 | 1008 | if parser.ReadToken().PrimaryType == RightCurlyBrace { 1009 | c = false 1010 | break 1011 | } 1012 | 1013 | parser.expect(Comma, SecondaryNullType) 1014 | parser.eatLastToken() 1015 | } 1016 | } 1017 | 1018 | parser.expect(RightCurlyBrace, SecondaryNullType) 1019 | parser.eatLastToken() 1020 | 1021 | return cl 1022 | } 1023 | 1024 | func (parser *Parser) parseArrayLiteral() ArrayLiteral { 1025 | line, column := parser.pos() 1026 | 1027 | parser.expect(LeftCurlyBrace, SecondaryNullType) 1028 | parser.eatLastToken() 1029 | 1030 | exprs := parser.parseExpressionArray() 1031 | 1032 | parser.expect(RightCurlyBrace, SecondaryNullType) 1033 | parser.eatLastToken() 1034 | 1035 | return ArrayLiteral{Exprs: exprs, Line: line, Column: column} 1036 | } 1037 | 1038 | func (parser *Parser) parseExpression() Expression { 1039 | return parser.parseExpr(0) 1040 | } 1041 | 1042 | func (parser *Parser) parseExpr(state int) Expression { 1043 | line, column := parser.pos() 1044 | switch state { 1045 | case 0: // ternary op 1046 | Cond := parser.parseExpr(1) 1047 | 1048 | if token := parser.ReadToken(); token.SecondaryType == QuesMark { 1049 | parser.eatLastToken() 1050 | Left := parser.parseExpr(0) // 0 is intentional (https://en.cppreference.com/w/c/language/operator_precedence#cite_ref-3) 1051 | 1052 | parser.expect(PrimaryNullType, Colon) 1053 | parser.eatLastToken() 1054 | 1055 | return TernaryExpr{Cond: Cond, Left: Left, Right: parser.parseExpr(1), Line: line, Column: column} 1056 | } 1057 | return Cond 1058 | case 1: // Logical And/Or 1059 | Left := parser.parseExpr(2) 1060 | for { 1061 | if token := parser.ReadToken(); token.PrimaryType == LogicalOperator { 1062 | parser.eatLastToken() 1063 | Left = BinaryExpr{Left: Left, Op: token, Right: parser.parseExpr(2), Line: line, Column: column} 1064 | } else { 1065 | break 1066 | } 1067 | } 1068 | return Left 1069 | case 2: // Bitwise And/Or/Xor 1070 | Left := parser.parseExpr(3) 1071 | for { 1072 | if token := parser.ReadToken(); token.SecondaryType == Or || token.SecondaryType == And || token.SecondaryType == ExclusiveOr { 1073 | parser.eatLastToken() 1074 | Left = BinaryExpr{Left: Left, Op: token, Right: parser.parseExpr(3), Line: line, Column: column} 1075 | } else { 1076 | break 1077 | } 1078 | } 1079 | return Left 1080 | case 3: // Relational Equal/Not equal 1081 | Left := parser.parseExpr(4) 1082 | for { 1083 | if token := parser.ReadToken(); token.SecondaryType == EqualEqual || token.SecondaryType == NotEqual { 1084 | parser.eatLastToken() 1085 | Left = BinaryExpr{Left: Left, Op: token, Right: parser.parseExpr(4), Line: line, Column: column} 1086 | } else { 1087 | break 1088 | } 1089 | } 1090 | return Left 1091 | case 4: // Relational Greater/Less/Greater or equal/Less or equal 1092 | Left := parser.parseExpr(5) 1093 | for { 1094 | if token := parser.ReadToken(); token.SecondaryType == Greater || token.SecondaryType == Less || token.SecondaryType == LessEqual || token.SecondaryType == GreaterEqual { 1095 | parser.eatLastToken() 1096 | Left = BinaryExpr{Left: Left, Op: token, Right: parser.parseExpr(5), Line: line, Column: column} 1097 | } else { 1098 | break 1099 | } 1100 | } 1101 | return Left 1102 | case 5: // Bitwise left shift/ right shift 1103 | Left := parser.parseExpr(6) 1104 | for { 1105 | if token := parser.ReadToken(); token.SecondaryType == LeftShift || token.SecondaryType == RightShift { 1106 | parser.eatLastToken() 1107 | Left = BinaryExpr{Left: Left, Op: token, Right: parser.parseExpr(6), Line: line, Column: column} 1108 | } else { 1109 | break 1110 | } 1111 | } 1112 | return Left 1113 | case 6: // Add/Sub 1114 | Left := parser.parseExpr(7) 1115 | for { 1116 | if token := parser.ReadToken(); token.SecondaryType == Add || token.SecondaryType == Sub { 1117 | parser.eatLastToken() 1118 | Left = BinaryExpr{Left: Left, Op: token, Right: parser.parseExpr(7), Line: line, Column: column} 1119 | } else { 1120 | break 1121 | } 1122 | } 1123 | return Left 1124 | case 7: // Div/Miv/Mod 1125 | Left := parser.parseExpr(8) 1126 | for { 1127 | if token := parser.ReadToken(); token.SecondaryType == Mul || token.SecondaryType == Div || token.SecondaryType == Modulus { 1128 | parser.eatLastToken() 1129 | Left = BinaryExpr{Left: Left, Op: token, Right: parser.parseExpr(8), Line: line, Column: column} 1130 | } else { 1131 | break 1132 | } 1133 | } 1134 | return Left 1135 | case 8: // unary */&/+/-/++/--/!/~, type casting 1136 | if token := parser.ReadToken(); token.SecondaryType == Mul || token.SecondaryType == And || token.SecondaryType == Not || token.SecondaryType == BitwiseNot || token.SecondaryType == Add || token.SecondaryType == Sub || token.SecondaryType == AddAdd || token.SecondaryType == SubSub { 1137 | parser.eatLastToken() 1138 | return UnaryExpr{Expr: parser.parseExpr(8), Op: token, Line: line, Column: column} 1139 | } else if token.PrimaryType == NewKeyword { 1140 | parser.eatLastToken() 1141 | 1142 | Typ := parser.parseType() 1143 | var Expr Expression 1144 | 1145 | if next := parser.ReadToken(); next.PrimaryType == LeftCurlyBrace { 1146 | parser.eatLastToken() 1147 | Expr = CompoundLiteral{Name: Typ, Data: parser.parseCompoundLiteral(), Line: line, Column: column} 1148 | } else if next.PrimaryType == LeftParen { 1149 | Expr = parser.parseExpr(0) 1150 | } 1151 | 1152 | return HeapAlloc{Type: Typ, Val: Expr, Line: line, Column: column} 1153 | } else if token.PrimaryType == AwaitKeyword { 1154 | parser.eatLastToken() 1155 | return AwaitExpr{Expr: parser.parseExpr(0), Line: line, Column: column} 1156 | } else if token.PrimaryType == CastKeyword { 1157 | parser.eatLastToken() 1158 | 1159 | parser.expect(LeftParen, SecondaryNullType) 1160 | parser.eatLastToken() 1161 | 1162 | Typ := parser.parseType() 1163 | 1164 | parser.expect(RightParen, SecondaryNullType) 1165 | parser.eatLastToken() 1166 | 1167 | return TypeCast{Type: Typ, Expr: parser.parseExpr(8), Line: line, Column: column} 1168 | } else if token.PrimaryType == LenKeyword { 1169 | parser.eatLastToken() 1170 | 1171 | parser.expect(LeftParen, SecondaryNullType) 1172 | parser.eatLastToken() 1173 | 1174 | Typ := parser.parseType() 1175 | 1176 | parser.expect(RightParen, SecondaryNullType) 1177 | parser.eatLastToken() 1178 | 1179 | return LenExpr{Type: Typ, Line: line, Column: column} 1180 | } else if token.PrimaryType == SizeKeyword { 1181 | parser.eatLastToken() 1182 | 1183 | parser.expect(LeftParen, SecondaryNullType) 1184 | parser.eatLastToken() 1185 | 1186 | e := parser.parseExprOrType() 1187 | 1188 | parser.expect(RightParen, SecondaryNullType) 1189 | parser.eatLastToken() 1190 | 1191 | return SizeExpr{Expr: e, Line: line, Column: column} 1192 | } 1193 | return parser.parseExpr(9) 1194 | case 9: // function call, postfix ++/--, struct/array members 1195 | expr := parser.parseExpr(10) 1196 | 1197 | for { 1198 | line, column := parser.pos() 1199 | 1200 | if token := parser.ReadToken(); token.PrimaryType == LeftParen { 1201 | parser.eatLastToken() 1202 | 1203 | if parser.ReadToken().PrimaryType == RightParen { 1204 | parser.eatLastToken() 1205 | expr = CallExpr{Function: expr, Args: []Expression{}, Line: line, Column: column} 1206 | continue 1207 | } 1208 | expr = CallExpr{Function: expr, Args: parser.parseExpressionArray(), Line: line, Column: column} 1209 | 1210 | parser.expect(RightParen, SecondaryNullType) 1211 | parser.eatLastToken() 1212 | 1213 | } else if token.SecondaryType == AddAdd || token.SecondaryType == SubSub { 1214 | parser.eatLastToken() 1215 | return PostfixUnaryExpr{Op: token, Expr: expr, Line: line, Column: column} 1216 | } else if token.PrimaryType == LeftBrace { 1217 | parser.eatLastToken() 1218 | expr2 := parser.parseExpr(0) 1219 | 1220 | parser.expect(RightBrace, SecondaryNullType) 1221 | parser.eatLastToken() 1222 | 1223 | expr = ArrayMemberExpr{Parent: expr, Index: expr2, Line: line, Column: column} 1224 | } else if token.SecondaryType == Dot { 1225 | parser.eatLastToken() 1226 | 1227 | tok := parser.expect(Identifier, SecondaryNullType) 1228 | parser.eatLastToken() 1229 | expr = MemberExpr{Base: expr, Prop: tok, Line: line, Column: column} 1230 | } else { 1231 | break 1232 | } 1233 | } 1234 | 1235 | return expr 1236 | case 10: // parentheses, compound literals 1237 | token := parser.ReadToken() 1238 | var expr Expression 1239 | 1240 | switch token.PrimaryType { 1241 | case LeftParen: 1242 | parser.eatLastToken() 1243 | expr = parser.parseExprOrType() 1244 | 1245 | parser.expect(RightParen, SecondaryNullType) 1246 | parser.eatLastToken() 1247 | case LeftCurlyBrace: 1248 | return parser.parseArrayLiteral() 1249 | default: 1250 | return parser.parseExpr(11) 1251 | } 1252 | 1253 | if parser.ReadToken().PrimaryType == LeftCurlyBrace { 1254 | parser.eatLastToken() 1255 | switch expr.(type) { 1256 | case Type: 1257 | return CompoundLiteral{Name: expr.(Type), Data: parser.parseCompoundLiteral(), Line: line, Column: column} 1258 | default: 1259 | return CompoundLiteral{Name: BasicType{Expr: expr, Line: expr.LineM(), Column: expr.ColumnM()}, Data: parser.parseCompoundLiteral(), Line: line, Column: column} 1260 | } 1261 | } 1262 | 1263 | return expr 1264 | case 11: // literals 1265 | token := parser.ReadToken() 1266 | 1267 | switch token.PrimaryType { 1268 | case FunctionKeyword: 1269 | parser.eatLastToken() 1270 | return parser.parseFunctionExpr() 1271 | case Identifier: 1272 | parser.eatLastToken() 1273 | return IdentExpr{Value: token, Line: line, Column: column} 1274 | case StringLiteral: 1275 | parser.eatLastToken() 1276 | return BasicLit{Value: token, Line: line, Column: column} 1277 | case CharLiteral: 1278 | parser.eatLastToken() 1279 | return BasicLit{Value: token, Line: line, Column: column} 1280 | case NumberLiteral: 1281 | parser.eatLastToken() 1282 | return BasicLit{Value: token, Line: line, Column: column} 1283 | case LeftParen: 1284 | parser.eatLastToken() 1285 | expr := parser.parseExpr(0) 1286 | 1287 | parser.expect(RightParen, SecondaryNullType) 1288 | parser.eatLastToken() 1289 | return expr 1290 | } 1291 | 1292 | return nil 1293 | } 1294 | 1295 | return nil 1296 | } 1297 | 1298 | func (parser *Parser) parseFunctionExpr() FuncExpr { 1299 | line, column := parser.pos() 1300 | function := FuncExpr{Line: line, Column: column, Type: FuncType{Line: line, Column: column}} 1301 | 1302 | function.Type.Type = OrdFunction 1303 | function.Type.Mut = true 1304 | 1305 | if token := parser.ReadToken(); token.PrimaryType == AsyncKeyword { 1306 | function.Type.Type = AsyncFunction 1307 | parser.eatLastToken() 1308 | } else if token.PrimaryType == WorkKeyword { 1309 | function.Type.Type = WorkFunction 1310 | parser.eatLastToken() 1311 | } 1312 | 1313 | // parse arguments 1314 | parser.expect(LeftParen, SecondaryNullType) 1315 | parser.eatLastToken() 1316 | 1317 | if token := parser.ReadToken(); token.PrimaryType != RightParen { 1318 | function.Type.ArgNames = append(function.Type.ArgNames, parser.expect(Identifier, SecondaryNullType)) 1319 | parser.eatLastToken() 1320 | 1321 | parser.expect(PrimaryNullType, Colon) 1322 | parser.eatLastToken() 1323 | 1324 | function.Type.ArgTypes = append(function.Type.ArgTypes, parser.parseType()) 1325 | 1326 | for token := parser.ReadToken(); token.PrimaryType == Comma; token = parser.ReadToken() { 1327 | parser.eatLastToken() 1328 | function.Type.ArgNames = append(function.Type.ArgNames, parser.expect(Identifier, SecondaryNullType)) 1329 | parser.eatLastToken() 1330 | 1331 | parser.expect(PrimaryNullType, Colon) 1332 | parser.eatLastToken() 1333 | 1334 | function.Type.ArgTypes = append(function.Type.ArgTypes, parser.parseType()) 1335 | } 1336 | } else { 1337 | function.Type.ArgTypes = []Type{VoidType.Type} 1338 | } 1339 | 1340 | parser.expect(RightParen, SecondaryNullType) 1341 | parser.eatLastToken() 1342 | 1343 | // parse return types 1344 | if token := parser.ReadToken(); token.PrimaryType != LeftCurlyBrace { 1345 | function.Type.ReturnTypes = []Type{parser.parseType()} 1346 | } else { 1347 | function.Type.ReturnTypes = []Type{VoidType.Type} 1348 | } 1349 | 1350 | // parse code block 1351 | function.Block = parser.parseBlock() 1352 | return function 1353 | } 1354 | 1355 | func (parser *Parser) parseFunctionExprOrType() Expression { 1356 | parser.fork(10) 1357 | 1358 | for token := parser.ReadToken(); token.PrimaryType != LeftParen; token = parser.ReadToken() { 1359 | parser.eatLastToken() 1360 | } 1361 | parser.eatLastToken() 1362 | parser.eatLastToken() 1363 | 1364 | if parser.ReadToken().SecondaryType == Colon { 1365 | parser.moveToFork(10) 1366 | return parser.parseFunctionExpr() 1367 | } 1368 | parser.moveToFork(10) 1369 | return parser.parseFunctionType() 1370 | } 1371 | 1372 | func (parser *Parser) parseTypeAHH(state int) Type { 1373 | line, column := parser.pos() 1374 | 1375 | switch state { 1376 | case 0: // arrays 1377 | if parser.ReadToken().PrimaryType != LeftBrace { 1378 | return parser.parseTypeAHH(1) 1379 | } 1380 | parser.eatLastToken() 1381 | 1382 | if parser.ReadToken().PrimaryType == RightBrace { 1383 | parser.eatLastToken() 1384 | return ImplictArrayType{BaseType: parser.parseTypeAHH(0), Line: line, Column: column} 1385 | } 1386 | 1387 | size := parser.expect(NumberLiteral, SecondaryNullType) 1388 | parser.eatLastToken() 1389 | 1390 | parser.expect(RightBrace, SecondaryNullType) 1391 | parser.eatLastToken() 1392 | 1393 | return ArrayType{Size: size, BaseType: parser.parseTypeAHH(0), Line: line, Column: column} 1394 | case 1: // '*' 1395 | if parser.ReadToken().SecondaryType != Mul { 1396 | return parser.parseTypeAHH(2) 1397 | } 1398 | parser.eatLastToken() 1399 | return PointerType{BaseType: parser.parseTypeAHH(0), Line: line, Column: column} 1400 | case 2: // const/dynamic/capture/static/promise keyword 1401 | if token := parser.ReadToken(); token.PrimaryType == VecKeyword { 1402 | parser.eatLastToken() 1403 | return VecType{BaseType: parser.parseTypeAHH(0), Line: line, Column: column} 1404 | } else if token.PrimaryType == ConstKeyword { 1405 | parser.eatLastToken() 1406 | return ConstType{BaseType: parser.parseTypeAHH(0), Line: line, Column: column} 1407 | } else if token.PrimaryType == CaptureKeyword { 1408 | parser.eatLastToken() 1409 | return CaptureType{BaseType: parser.parseTypeAHH(0), Line: line, Column: column} 1410 | } else if token.PrimaryType == StaticKeyword { 1411 | parser.eatLastToken() 1412 | return StaticType{BaseType: parser.parseTypeAHH(0), Line: line, Column: column} 1413 | } else if token.PrimaryType == PromiseKeyword { 1414 | parser.eatLastToken() 1415 | return PromiseType{BaseType: parser.parseTypeAHH(0), Line: line, Column: column} 1416 | } 1417 | return parser.parseTypeAHH(3) 1418 | case 3: 1419 | token := parser.ReadToken() 1420 | 1421 | switch token.PrimaryType { 1422 | case FunctionKeyword: 1423 | parser.eatLastToken() 1424 | return parser.parseFunctionType() 1425 | case TupleKeyword: 1426 | parser.eatLastToken() 1427 | return parser.parseTupleType() 1428 | case StructKeyword: 1429 | parser.eatLastToken() 1430 | return parser.parseStructType() 1431 | case EnumKeyword: 1432 | parser.eatLastToken() 1433 | return parser.parseEnumType() 1434 | case LeftParen: 1435 | parser.eatLastToken() 1436 | Typ := parser.parseTypeAHH(0) 1437 | 1438 | parser.expect(RightParen, SecondaryNullType) 1439 | parser.eatLastToken() 1440 | return Typ 1441 | } 1442 | 1443 | var expr Expression 1444 | 1445 | expr = IdentExpr{Value: parser.expect(Identifier, SecondaryNullType), Line: line, Column: column} 1446 | parser.eatLastToken() 1447 | 1448 | for parser.ReadToken().SecondaryType == Dot { 1449 | parser.eatLastToken() 1450 | expr = MemberExpr{Base: expr, Prop: parser.expect(Identifier, SecondaryNullType), Line: line, Column: column} 1451 | parser.eatLastToken() 1452 | } 1453 | 1454 | return BasicType{Expr: expr, Line: line, Column: column} 1455 | } 1456 | 1457 | return nil 1458 | } 1459 | 1460 | func (parser *Parser) parseExprOrType() Expression { 1461 | switch parser.ReadToken().PrimaryType { 1462 | case PromiseKeyword: 1463 | case ConstKeyword: 1464 | case VecKeyword: 1465 | case LeftBrace: 1466 | break 1467 | default: 1468 | return parser.parseExpr(0) 1469 | } 1470 | return parser.parseType() 1471 | } 1472 | -------------------------------------------------------------------------------- /src/parser/tokens.go: -------------------------------------------------------------------------------- 1 | package parser 2 | 3 | // PrimaryTokenType enum 4 | type PrimaryTokenType byte 5 | 6 | //SecondaryTokenType enum 7 | type SecondaryTokenType byte 8 | 9 | // The numbers here are just to keep values different, they dont mean anything specific 10 | // Primary token type 11 | 12 | const ( 13 | PrimaryNullType PrimaryTokenType = 0 14 | 15 | Identifier PrimaryTokenType = 1 16 | 17 | NumberLiteral PrimaryTokenType = 2 18 | StringLiteral PrimaryTokenType = 3 19 | CharLiteral PrimaryTokenType = 4 20 | 21 | StringDelimiter PrimaryTokenType = 6 22 | CharDelimiter PrimaryTokenType = 7 23 | 24 | LeftParen PrimaryTokenType = 8 25 | RightParen PrimaryTokenType = 9 26 | LeftBrace PrimaryTokenType = 10 27 | RightBrace PrimaryTokenType = 11 28 | LeftCurlyBrace PrimaryTokenType = 12 29 | RightCurlyBrace PrimaryTokenType = 13 30 | SemiColon PrimaryTokenType = 14 31 | Comma PrimaryTokenType = 15 32 | 33 | // Operators 34 | AirthmaticOperator PrimaryTokenType = 51 35 | AssignmentOperator PrimaryTokenType = 52 36 | RelationalOperator PrimaryTokenType = 53 37 | LogicalOperator PrimaryTokenType = 54 38 | BitwiseOperator PrimaryTokenType = 55 39 | SpecialOperator PrimaryTokenType = 56 40 | 41 | // Keywords 42 | ForKeyword PrimaryTokenType = 101 43 | SwitchKeyword PrimaryTokenType = 102 44 | IfKeyword PrimaryTokenType = 103 45 | ElseKeyword PrimaryTokenType = 104 46 | FunctionKeyword PrimaryTokenType = 105 47 | StructKeyword PrimaryTokenType = 106 48 | TupleKeyword PrimaryTokenType = 107 49 | EnumKeyword PrimaryTokenType = 108 50 | CaseKeyword PrimaryTokenType = 109 51 | AsyncKeyword PrimaryTokenType = 110 52 | WorkKeyword PrimaryTokenType = 111 53 | ImportKeyword PrimaryTokenType = 113 54 | DeferKeyword PrimaryTokenType = 114 55 | ReturnKeyword PrimaryTokenType = 115 56 | DefaultKeyword PrimaryTokenType = 116 57 | BreakKeyword PrimaryTokenType = 117 58 | ContinueKeyword PrimaryTokenType = 118 59 | NewKeyword PrimaryTokenType = 119 60 | ConstKeyword PrimaryTokenType = 120 61 | VecKeyword PrimaryTokenType = 121 62 | DeleteKeyword PrimaryTokenType = 122 63 | TypedefKeyword PrimaryTokenType = 123 64 | CastKeyword PrimaryTokenType = 124 65 | LenKeyword PrimaryTokenType = 125 66 | SizeKeyword PrimaryTokenType = 126 67 | ExportKeyword PrimaryTokenType = 127 68 | UnionKeyword PrimaryTokenType = 128 69 | StaticKeyword PrimaryTokenType = 129 70 | CaptureKeyword PrimaryTokenType = 130 71 | PromiseKeyword PrimaryTokenType = 131 72 | LabelKeyword PrimaryTokenType = 132 73 | GotoKeyword PrimaryTokenType = 133 74 | AwaitKeyword PrimaryTokenType = 134 75 | // the parser stops parsing when it receives either of these types and shows the correct error message 76 | EOF PrimaryTokenType = 254 77 | ErrorToken PrimaryTokenType = 255 78 | ) 79 | 80 | // Secondary token type 81 | const ( 82 | SecondaryNullType SecondaryTokenType = 0 83 | 84 | // Radix for number literals 85 | DecimalRadix SecondaryTokenType = 1 86 | BinaryRadix SecondaryTokenType = 2 87 | OctalRadix SecondaryTokenType = 3 88 | HexadecimalRadix SecondaryTokenType = 4 89 | 90 | // Airthmatic Operators 91 | Add SecondaryTokenType = 11 92 | Sub SecondaryTokenType = 12 93 | Mul SecondaryTokenType = 13 94 | Div SecondaryTokenType = 14 95 | Modulus SecondaryTokenType = 15 96 | 97 | // Assignment Operators 98 | AddEqual SecondaryTokenType = 21 99 | SubEqual SecondaryTokenType = 22 100 | MulEqual SecondaryTokenType = 23 101 | DivEqual SecondaryTokenType = 24 102 | ModulusEqual SecondaryTokenType = 25 103 | Equal SecondaryTokenType = 26 104 | AddAdd SecondaryTokenType = 27 105 | SubSub SecondaryTokenType = 28 106 | 107 | // Realtional Operators 108 | EqualEqual SecondaryTokenType = 31 109 | NotEqual SecondaryTokenType = 32 110 | Greater SecondaryTokenType = 33 111 | Less SecondaryTokenType = 34 112 | LessEqual SecondaryTokenType = 35 113 | GreaterEqual SecondaryTokenType = 36 114 | 115 | // Logical Operators 116 | AndAnd SecondaryTokenType = 41 117 | OrOr SecondaryTokenType = 42 118 | Not SecondaryTokenType = 43 119 | 120 | // Bitwise Opeartors 121 | LeftShift SecondaryTokenType = 51 122 | RightShift SecondaryTokenType = 52 123 | Or SecondaryTokenType = 53 124 | And SecondaryTokenType = 54 125 | ExclusiveOr SecondaryTokenType = 55 126 | BitwiseNot SecondaryTokenType = 56 127 | 128 | // Special Operators 129 | Colon SecondaryTokenType = 61 130 | QuesMark SecondaryTokenType = 62 131 | Dot SecondaryTokenType = 63 132 | DotDot SecondaryTokenType = 65 133 | 134 | // Encoding for char literals 135 | Byte1Char SecondaryTokenType = 71 136 | Byte2Char SecondaryTokenType = 72 137 | Byte3Char SecondaryTokenType = 73 138 | Byte4Char SecondaryTokenType = 74 139 | 140 | // For use with ErrorToken 141 | UnexpectedEOF SecondaryTokenType = 101 142 | NotFound SecondaryTokenType = 102 143 | UnknownChar SecondaryTokenType = 103 144 | ) 145 | 146 | // Keywords urgh idk what to write 147 | var Keywords = map[string]PrimaryTokenType{ 148 | "if": IfKeyword, 149 | "else": ElseKeyword, 150 | "for": ForKeyword, 151 | "switch": SwitchKeyword, 152 | "case": CaseKeyword, 153 | "enum": EnumKeyword, 154 | "struct": StructKeyword, 155 | "async": AsyncKeyword, 156 | "work": WorkKeyword, 157 | "import": ImportKeyword, 158 | // "defer": DeferKeyword, 159 | "func": FunctionKeyword, 160 | "return": ReturnKeyword, 161 | "default": DefaultKeyword, 162 | "break": BreakKeyword, 163 | "continue": ContinueKeyword, 164 | "tuple": TupleKeyword, 165 | "new": NewKeyword, 166 | "const": ConstKeyword, 167 | "vec": VecKeyword, 168 | "delete": DeleteKeyword, 169 | "typedef": TypedefKeyword, 170 | "cast": CastKeyword, 171 | // "len": LenKeyword, 172 | "sizeof": SizeKeyword, 173 | "export": ExportKeyword, 174 | "union": UnionKeyword, 175 | "static": StaticKeyword, 176 | "capture": CaptureKeyword, 177 | "promise": PromiseKeyword, 178 | "label": LabelKeyword, 179 | "goto": GotoKeyword, 180 | "await": AwaitKeyword, 181 | // more stuff 182 | } 183 | 184 | // Token ... 185 | type Token struct { 186 | PrimaryType PrimaryTokenType 187 | SecondaryType SecondaryTokenType 188 | Buff []byte 189 | Line int 190 | Column int 191 | Flags int 192 | } 193 | 194 | var PrimaryTypes map[PrimaryTokenType]string = map[PrimaryTokenType]string{ 195 | PrimaryNullType: "Null", 196 | 197 | Identifier: "identifier", 198 | 199 | NumberLiteral: "number literal", 200 | StringLiteral: "string literal", 201 | CharLiteral: "char literal", 202 | 203 | StringDelimiter: "\"", 204 | CharDelimiter: "'", 205 | 206 | LeftParen: "(", 207 | RightParen: ")", 208 | LeftBrace: "[", 209 | RightBrace: "]", 210 | LeftCurlyBrace: "{", 211 | RightCurlyBrace: "}", 212 | SemiColon: ";", 213 | Comma: ",", 214 | 215 | AirthmaticOperator: "airthmatic operator", 216 | AssignmentOperator: "assignment operator", 217 | RelationalOperator: "relational operator", 218 | LogicalOperator: "logical operator", 219 | BitwiseOperator: "bitwise operator", 220 | SpecialOperator: "special operator", 221 | 222 | ForKeyword: "for", 223 | SwitchKeyword: "switch", 224 | IfKeyword: "if", 225 | ElseKeyword: "else", 226 | FunctionKeyword: "func", 227 | StructKeyword: "struct", 228 | TupleKeyword: "tuple", 229 | EnumKeyword: "enum", 230 | CaseKeyword: "case", 231 | AsyncKeyword: "async", 232 | WorkKeyword: "work", 233 | ImportKeyword: "import", 234 | ReturnKeyword: "return", 235 | DefaultKeyword: "default", 236 | BreakKeyword: "break", 237 | ContinueKeyword: "constinue", 238 | NewKeyword: "new", 239 | ConstKeyword: "const", 240 | VecKeyword: "vec", 241 | DeleteKeyword: "delete", 242 | TypedefKeyword: "typedef", 243 | CastKeyword: "cast", 244 | SizeKeyword: "sizeof", 245 | ExportKeyword: "export", 246 | UnionKeyword: "union", 247 | StaticKeyword: "static", 248 | CaptureKeyword: "capture", 249 | PromiseKeyword: "promise", 250 | 251 | EOF: "EOF", 252 | ErrorToken: "ErrorToken", 253 | } 254 | 255 | var SecondaryTypes map[SecondaryTokenType]string = map[SecondaryTokenType]string{ 256 | SecondaryNullType: "Null", 257 | 258 | DecimalRadix: "DecimalRadix", 259 | BinaryRadix: "BinaryRadix", 260 | OctalRadix: "OctalRadix", 261 | HexadecimalRadix: "HexadecimalRadix", 262 | 263 | Add: "+", 264 | Sub: "-", 265 | Mul: "*", 266 | Div: "/", 267 | Modulus: "%", 268 | 269 | AddEqual: "+=", 270 | SubEqual: "-=", 271 | MulEqual: "*=", 272 | DivEqual: "/=", 273 | ModulusEqual: "%=", 274 | Equal: "=", 275 | 276 | AddAdd: "++", 277 | SubSub: "--", 278 | 279 | EqualEqual: "==", 280 | NotEqual: "!=", 281 | Greater: ">", 282 | Less: "<", 283 | LessEqual: "<=", 284 | GreaterEqual: ">=", 285 | 286 | AndAnd: "&&", 287 | OrOr: "||", 288 | Not: "!", 289 | 290 | LeftShift: "<<", 291 | RightShift: ">>", 292 | Or: "|", 293 | And: "&", 294 | ExclusiveOr: "^", 295 | 296 | Colon: ":", 297 | QuesMark: "?", 298 | Dot: ".", 299 | DotDot: "..", 300 | 301 | Byte1Char: "Byte1Char", 302 | Byte2Char: "Byte2Char", 303 | Byte3Char: "Byte3Char", 304 | Byte4Char: "Byte4Char", 305 | 306 | UnexpectedEOF: "UnexpectedEOF", 307 | NotFound: "NotFound", 308 | UnknownChar: "UnknownChar", 309 | } 310 | 311 | // Serialize serializes a token 312 | func (token Token) Serialize() string { 313 | return string(token.Buff) 314 | // return "{\n\tPrimaryType:\t" + PrimaryTypes[token.PrimaryType] + ",\n\tSecondaryType:\t" + SecondaryTypes[token.SecondaryType] + ",\n\tValue:\t" + string(token.Buff) + "\n\tLine:\t" + strconv.Itoa(token.Line) + "\n\tColumn:\t" + strconv.Itoa(token.Column) + "\n}," 315 | } 316 | -------------------------------------------------------------------------------- /src/parser/util.go: -------------------------------------------------------------------------------- 1 | package parser 2 | 3 | //IsChar checks if `b` is an english alphabet `(a-z|A-Z)` 4 | func IsChar(b byte) bool { 5 | return (b >= 'A' && b <= 'Z') || (b >= 'a' && b <= 'z') 6 | } 7 | 8 | //IsNumBi checks if `b` is a binary digit `(0|1)` 9 | func IsNumBi(b byte) bool { 10 | return b == '0' || b == '1' 11 | } 12 | 13 | //IsNumOct checks if `b` is an octal digit `(0-7)` 14 | func IsNumOct(b byte) bool { 15 | return (b >= '0' && b <= '7') 16 | } 17 | 18 | //IsNumDec checks if `b` is a decimal digit `(0-9)` 19 | func IsNumDec(b byte) bool { 20 | return (b >= '0' && b <= '9') 21 | } 22 | 23 | //IsNumHex checks if `b` is a hexadecimal digit `(0-9|a-f|A-F)` 24 | func IsNumHex(b byte) bool { 25 | return (b >= '0' && b <= '9') || (b >= 'A' && b <= 'F') || (b >= 'a' && b <= 'f') 26 | } 27 | 28 | //IsIdentifierPart checks if `b` is a valid character for being a part of identifier `(a-z|A-Z|0-9|_)` 29 | func IsIdentifierPart(b byte) bool { 30 | return IsChar(b) || IsNumDec(b) || b == '_' || b == '$' 31 | } 32 | 33 | //IsIdentifierBegining checks if `b` is valid for being the first character of an identifier `(a-z|A-Z|_)` 34 | func IsIdentifierBegining(b byte) bool { 35 | return IsChar(b) || b == '_' || b == '$' 36 | } 37 | 38 | //IsStringDelimiter checks if `b` is a string delimiter `"` 39 | func IsStringDelimiter(b byte) bool { 40 | return b == '"' 41 | } 42 | 43 | //IsCharDelimiter checks if `b` is a char delimiter `'` 44 | func IsCharDelimiter(b byte) bool { 45 | return b == '\'' 46 | } 47 | 48 | //IsSpace checks if `b` is a blank space (' '|'\n'|'\t|'\r') 49 | func IsSpace(b byte) bool { 50 | return b == ' ' || b == '\n' || b == '\r' || b == '\t' 51 | } 52 | 53 | //GetWordType retuns the right PrimaryTokenType for identifiers or keywords 54 | func GetWordType(str string) PrimaryTokenType { 55 | if keywordType, ok := Keywords[str]; ok { 56 | return keywordType 57 | } 58 | return Identifier 59 | } 60 | 61 | func Pow(a, b int) int { 62 | r := 1 63 | for i := 0; i < b; i++ { 64 | r = r * a 65 | } 66 | return r 67 | } 68 | 69 | func HexToInt(b byte) int { 70 | if IsNumDec(b) { 71 | return int(b - '0') 72 | } else if b < 'a' { 73 | return int(b - 'A' + 10) 74 | } else { 75 | return int(b - 'a' + 10) 76 | } 77 | } 78 | --------------------------------------------------------------------------------