wip more array defs
This commit is contained in:
parent
4e9f3973a4
commit
1ec9f7a2d1
4
common.h
4
common.h
|
|
@ -38,8 +38,8 @@ struct symbol_s {
|
||||||
u32 ref; /* either constant value or pointer to other thing */
|
u32 ref; /* either constant value or pointer to other thing */
|
||||||
u32 size; /* either size of the plex or length of the array/list/etc. */
|
u32 size; /* either size of the plex or length of the array/list/etc. */
|
||||||
u32 scope; /* scope ref */
|
u32 scope; /* scope ref */
|
||||||
List *args; /* function params or plex constructor args */
|
List *args; /* function params or plex constructor args or array dimensions */
|
||||||
List *fields; /* either plex variable fields, or method signatures */
|
List *fields; /* either plex variable fields, or method signatures or array strides */
|
||||||
};
|
};
|
||||||
|
|
||||||
void *node_value(Node *n);
|
void *node_value(Node *n);
|
||||||
|
|
|
||||||
111
compiler.c
111
compiler.c
|
|
@ -2,6 +2,7 @@
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "emit.h"
|
#include "emit.h"
|
||||||
#include "lexer.h"
|
#include "lexer.h"
|
||||||
|
#include "libc.h"
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
|
|
||||||
Emitter emitter = {0};
|
Emitter emitter = {0};
|
||||||
|
|
@ -257,6 +258,67 @@ define_function()
|
||||||
fn->size = size;
|
fn->size = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
calculate_strides(List *dims, List *strides)
|
||||||
|
{
|
||||||
|
u32 *num;
|
||||||
|
u32 i;
|
||||||
|
u32 num_dims = dims->count;
|
||||||
|
u32 current_stride = 1;
|
||||||
|
|
||||||
|
if (num_dims == 1) {
|
||||||
|
List_push(arena, strides, ¤t_stride, sizeof(u32));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i = num_dims - 1; i > 0; i--) {
|
||||||
|
List_push(arena, strides, ¤t_stride, sizeof(u32));
|
||||||
|
|
||||||
|
/* this is very slow but for small numbers of dimensions its fine */
|
||||||
|
num = (u32*)List_get(dims, i);
|
||||||
|
if (num){
|
||||||
|
current_stride *= (*num);
|
||||||
|
} else {
|
||||||
|
emitter.error("Tried to get a dimension that did not exist", 43, parser.previous.line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
define_array()
|
||||||
|
{
|
||||||
|
i32 size = 0, n = 0, flat_array_length = 1;
|
||||||
|
TokenType tt = parser.previous.type;
|
||||||
|
SymbolType st = token_type_to_sym_type(tt);
|
||||||
|
Symbol *array;
|
||||||
|
|
||||||
|
List *dims = List_init(arena);
|
||||||
|
List *strides = List_init(arena);
|
||||||
|
advance();
|
||||||
|
|
||||||
|
while(!match(TOKEN_RBRACKET)) {
|
||||||
|
if(parser.current.type == TOKEN_LITERAL_INT) {
|
||||||
|
n = ston(parser.current.start, parser.current.length);
|
||||||
|
flat_array_length *= n;
|
||||||
|
List_push(arena, dims, &n, sizeof(u32));
|
||||||
|
}
|
||||||
|
advance();
|
||||||
|
if(check(TOKEN_LBRACKET)) break;
|
||||||
|
if(check(TOKEN_COMMA)) {
|
||||||
|
/* it is a multidimensional array */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size = emitter.get_size(st) * flat_array_length;
|
||||||
|
|
||||||
|
array = scope_add_symbol(parser.current.start, parser.current.length,
|
||||||
|
SYMBOL_ARRAY, size);
|
||||||
|
array->secondary_type = st;
|
||||||
|
calculate_strides(dims, strides);
|
||||||
|
array->args = dims;
|
||||||
|
array->fields = strides;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
build_symbol_table(char *source)
|
build_symbol_table(char *source)
|
||||||
{
|
{
|
||||||
|
|
@ -276,6 +338,12 @@ build_symbol_table(char *source)
|
||||||
define_plex();
|
define_plex();
|
||||||
} else if(match(TOKEN_KEYWORD_TRAIT)) {
|
} else if(match(TOKEN_KEYWORD_TRAIT)) {
|
||||||
define_trait();
|
define_trait();
|
||||||
|
} else if (parser.current.type >= TOKEN_TYPE_I8 &&
|
||||||
|
parser.current.type <= TOKEN_TYPE_PTR) {
|
||||||
|
advance();
|
||||||
|
if (check(TOKEN_LBRACKET)) {
|
||||||
|
define_array();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/* in binary bytecode output mode we need to count the bytes here */
|
/* in binary bytecode output mode we need to count the bytes here */
|
||||||
/* otherwise ignore everything */
|
/* otherwise ignore everything */
|
||||||
|
|
@ -291,29 +359,6 @@ ParseRule *get_rule(TokenType type);
|
||||||
void parse_precedence(Precedence precedence);
|
void parse_precedence(Precedence precedence);
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
calculate_strides(i32 *dims, i32 num_dims, i32 *out_strides)
|
|
||||||
{
|
|
||||||
i32 i;
|
|
||||||
i32 current_stride = 1;
|
|
||||||
|
|
||||||
for(i = num_dims - 1; i >= 0; i--) {
|
|
||||||
out_strides[i] = current_stride;
|
|
||||||
current_stride *= dims[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
define_array()
|
|
||||||
{
|
|
||||||
/* example
|
|
||||||
i32 dims[3] = {3, 3, 3};
|
|
||||||
i32 strides[3];
|
|
||||||
|
|
||||||
calculate_strides(dims, 3, strides);
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
u32
|
u32
|
||||||
variable_declaration(Symbol *def)
|
variable_declaration(Symbol *def)
|
||||||
{
|
{
|
||||||
|
|
@ -322,33 +367,17 @@ variable_declaration(Symbol *def)
|
||||||
SymbolType st = token_type_to_sym_type(tt);
|
SymbolType st = token_type_to_sym_type(tt);
|
||||||
Symbol *variable;
|
Symbol *variable;
|
||||||
|
|
||||||
bool is_array = false;
|
|
||||||
i32 current_stride = 1;
|
|
||||||
List *strides;
|
|
||||||
|
|
||||||
if (parser.current.type == TOKEN_LBRACE) {
|
if (parser.current.type == TOKEN_LBRACE) {
|
||||||
is_array = true;
|
|
||||||
strides = List_init(arena);
|
|
||||||
|
|
||||||
while(!check(TOKEN_RBRACKET)) {
|
while(!check(TOKEN_RBRACKET)) {
|
||||||
if(parser.previous.type == TOKEN_LITERAL_NAT) {
|
|
||||||
/* consume dimension if exists */
|
|
||||||
}
|
|
||||||
advance();
|
advance();
|
||||||
if(check(TOKEN_LBRACKET)) break;
|
|
||||||
advance();
|
|
||||||
if(check(TOKEN_COMMA)) {
|
|
||||||
/* it is a multidimensional array */
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
USED(is_array);
|
|
||||||
|
|
||||||
if(st != SYMBOL_UNDEFINED) {
|
if(st != SYMBOL_UNDEFINED) {
|
||||||
size = emitter.get_size(st);
|
size = emitter.get_size(st);
|
||||||
|
|
||||||
variable =
|
variable = scope_add_symbol(parser.current.start, parser.current.length, st, size);
|
||||||
scope_add_symbol(parser.current.start, parser.current.length, st, size);
|
|
||||||
if(!def && (parser.pass == 0)) return size;
|
if(!def && (parser.pass == 0)) return size;
|
||||||
|
|
||||||
if(def) {
|
if(def) {
|
||||||
|
|
|
||||||
|
|
@ -16,34 +16,10 @@ It is short for "Undarsċieppan" The name comes from the Proto-West-Germanic wor
|
||||||
:PROPERTIES:
|
:PROPERTIES:
|
||||||
:CUSTOM_ID: undar-grammar-and-specification
|
:CUSTOM_ID: undar-grammar-and-specification
|
||||||
:END:
|
:END:
|
||||||
** Plexs
|
|
||||||
|
** Primitive Types
|
||||||
:PROPERTIES:
|
:PROPERTIES:
|
||||||
:CUSTOM_ID: plexs
|
:CUSTOM_ID: primitive-types
|
||||||
:END:
|
|
||||||
- A =plex= is a container for primitive types.
|
|
||||||
- Not a class: no inheritance, no vtables
|
|
||||||
- Methods are functions with implicit =this= argument
|
|
||||||
|
|
||||||
#+begin_src ul
|
|
||||||
plex «token» {
|
|
||||||
init() {
|
|
||||||
// values
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// example
|
|
||||||
plex Vec3 {
|
|
||||||
init(real x, real y, real z) {
|
|
||||||
this.x = x;
|
|
||||||
this.y = z;
|
|
||||||
this.y = z;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#+end_src ul
|
|
||||||
|
|
||||||
*** Substantial Plexs
|
|
||||||
:PROPERTIES:
|
|
||||||
:CUSTOM_ID: substantial-plexs
|
|
||||||
:END:
|
:END:
|
||||||
|
|
||||||
| Type | Description |
|
| Type | Description |
|
||||||
|
|
@ -127,7 +103,13 @@ if («token» is real) {
|
||||||
}
|
}
|
||||||
#+end_src ul
|
#+end_src ul
|
||||||
|
|
||||||
also used for letting constants
|
checks if a atom's plex contains the fields inside of a trait
|
||||||
|
|
||||||
|
#+begin_src ul
|
||||||
|
if («token» is [Tunnel, Drawable]) {
|
||||||
|
print("im tunnel-able and draw-able");
|
||||||
|
}
|
||||||
|
#+end_src ul
|
||||||
|
|
||||||
=as=
|
=as=
|
||||||
|
|
||||||
|
|
@ -140,18 +122,10 @@ some_functon(«token» as real); // needs a real
|
||||||
|
|
||||||
=in=
|
=in=
|
||||||
|
|
||||||
checks if a atom's plex contains the fields inside of a trait
|
used inside of the for loops
|
||||||
|
|
||||||
#+begin_src ul
|
#+begin_src ul
|
||||||
if («token» in Tunnel, Drawable) {
|
for («type» «token» in «collection») { «body» }
|
||||||
print("im tunnel-able and draw-able");
|
|
||||||
}
|
|
||||||
#+end_src ul
|
|
||||||
|
|
||||||
also used inside of the for loops
|
|
||||||
|
|
||||||
#+begin_src ul
|
|
||||||
for («token» in «collection») { «body» }
|
|
||||||
#+end_src ul
|
#+end_src ul
|
||||||
|
|
||||||
** Control flow
|
** Control flow
|
||||||
|
|
@ -170,7 +144,7 @@ for («variable» in «collection») { «body» }
|
||||||
iterates through each atom in the collection setting it to variable
|
iterates through each atom in the collection setting it to variable
|
||||||
|
|
||||||
#+begin_src ul
|
#+begin_src ul
|
||||||
for («variable» = initial_value; end_value; increment) { «body» }
|
for («type» «variable» = initial_value; «boolean expression»; «increment») { «body» }
|
||||||
#+end_src ul
|
#+end_src ul
|
||||||
|
|
||||||
loops from initial value to end value by increment value (like a for loop in other languages)
|
loops from initial value to end value by increment value (like a for loop in other languages)
|
||||||
|
|
@ -248,6 +222,35 @@ Array of a specific plex
|
||||||
«plex»[«length»] «variable» = [val1, val2, ...];
|
«plex»[«length»] «variable» = [val1, val2, ...];
|
||||||
#+end_src ul
|
#+end_src ul
|
||||||
|
|
||||||
|
** Plexs
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: plexs
|
||||||
|
:END:
|
||||||
|
- A =plex= is a container for primitive types.
|
||||||
|
- Not a class: no inheritance, no vtables
|
||||||
|
- Methods are functions with implicit =this= argument
|
||||||
|
|
||||||
|
#+begin_src ul
|
||||||
|
plex «token» {
|
||||||
|
init() {
|
||||||
|
// values
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// example
|
||||||
|
plex Vec3 {
|
||||||
|
real x;
|
||||||
|
real y;
|
||||||
|
real z;
|
||||||
|
|
||||||
|
init(real x, real y, real z) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.z = z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#+end_src ul
|
||||||
|
|
||||||
** Tunnel :WIP:
|
** Tunnel :WIP:
|
||||||
:PROPERTIES:
|
:PROPERTIES:
|
||||||
:CUSTOM_ID: tunnel-1
|
:CUSTOM_ID: tunnel-1
|
||||||
|
|
|
||||||
78
libc.c
78
libc.c
|
|
@ -328,3 +328,81 @@ real_to_string(Arena *a, r32 q)
|
||||||
return ascpy(a, buffer + i, MAX_LEN_REAL32 - i);
|
return ascpy(a, buffer + i, MAX_LEN_REAL32 - i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
is_digit(char c)
|
||||||
|
{
|
||||||
|
return c >= '0' && c <= '9';
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
is_space(char c)
|
||||||
|
{
|
||||||
|
switch(c) {
|
||||||
|
case ' ':
|
||||||
|
case '\r':
|
||||||
|
case '\t':
|
||||||
|
case '\v':
|
||||||
|
case '\f':
|
||||||
|
case '\n':
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
i32
|
||||||
|
stoi(const char *str, u32 length)
|
||||||
|
{
|
||||||
|
bool neg = false;
|
||||||
|
i32 n = 0;
|
||||||
|
|
||||||
|
while (is_space(*str)) {
|
||||||
|
if (length-- == 0) return n;
|
||||||
|
str++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*str == '-') {
|
||||||
|
neg = true;
|
||||||
|
if (length-- == 0) return n;
|
||||||
|
str++;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (is_digit(*str) && length-- > 0) {
|
||||||
|
int digit = *str++ - '0';
|
||||||
|
|
||||||
|
if (neg) {
|
||||||
|
if (n < (I32_MIN / 10) || (n == (I32_MIN / 10) && digit > -(I32_MIN % 10))) {
|
||||||
|
return I32_MIN;
|
||||||
|
}
|
||||||
|
n = n * 10 - digit;
|
||||||
|
} else {
|
||||||
|
if (n > (I32_MAX / 10) || (n == (I32_MAX / 10) && digit > (I32_MAX % 10))) {
|
||||||
|
return I32_MAX;
|
||||||
|
}
|
||||||
|
n = n * 10 + digit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return neg ? -n : n;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32
|
||||||
|
ston(const char *str, u32 length)
|
||||||
|
{
|
||||||
|
u32 n = 0;
|
||||||
|
|
||||||
|
while (is_space(*str)) {
|
||||||
|
if (length-- == 0) return n;
|
||||||
|
str++;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (is_digit(*str) && length-- > 0) {
|
||||||
|
int digit = *str++ - '0';
|
||||||
|
|
||||||
|
if (n > (U32_MAX / 10) || (n == (U32_MAX / 10) && digit > (U32_MAX % 10))) {
|
||||||
|
return U32_MAX;
|
||||||
|
}
|
||||||
|
n = n * 10 + digit;
|
||||||
|
}
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
|
||||||
6
libc.h
6
libc.h
|
|
@ -57,7 +57,7 @@ typedef u8 bool;
|
||||||
#define I16_MAX 32767
|
#define I16_MAX 32767
|
||||||
#define U16_MAX 65535
|
#define U16_MAX 65535
|
||||||
|
|
||||||
#define I32_MIN -2147483648
|
#define I32_MIN -2147483647
|
||||||
#define I32_MAX 2147483647
|
#define I32_MAX 2147483647
|
||||||
#define U32_MAX 4294967295
|
#define U32_MAX 4294967295
|
||||||
|
|
||||||
|
|
@ -66,7 +66,7 @@ typedef u8 bool;
|
||||||
#define AS_INT(v) ((i32)(v))
|
#define AS_INT(v) ((i32)(v))
|
||||||
#define AS_NAT(v) ((u32)(v))
|
#define AS_NAT(v) ((u32)(v))
|
||||||
#define AS_REAL(v) ((i32)(v))
|
#define AS_REAL(v) ((i32)(v))
|
||||||
#define FLOAT_TO_REAL(v) (((i32)(v)) * FIXED_CONST)
|
#define FLOAT_TO_REAL(v) ((i32)((v) * FIXED_CONST))
|
||||||
#define REAL_TO_FLOAT(v) (((f32)(v)) / FIXED_CONST)
|
#define REAL_TO_FLOAT(v) (((f32)(v)) / FIXED_CONST)
|
||||||
|
|
||||||
#define USED(x) ((void)(x))
|
#define USED(x) ((void)(x))
|
||||||
|
|
@ -132,5 +132,7 @@ r32 real_abs(r32 f);
|
||||||
char *int_to_string(Arena *a, i32 v);
|
char *int_to_string(Arena *a, i32 v);
|
||||||
char *nat_to_string(Arena *a, u32 v);
|
char *nat_to_string(Arena *a, u32 v);
|
||||||
char *real_to_string(Arena *a, r32 q);
|
char *real_to_string(Arena *a, r32 q);
|
||||||
|
i32 stoi(const char *str, u32 len);
|
||||||
|
u32 ston(const char *str, u32 len);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -2,17 +2,16 @@
|
||||||
nat[6] fixed_size = [1, 2, 3, 4, 5, 6];
|
nat[6] fixed_size = [1, 2, 3, 4, 5, 6];
|
||||||
|
|
||||||
nat i = 0;
|
nat i = 0;
|
||||||
nat len = array.length;
|
while (i < fixed_size.length) {
|
||||||
while (i < len) {
|
print(fixed_size[i] as str);
|
||||||
print(array[i] as str);
|
print(" ");
|
||||||
print("\n");
|
|
||||||
i = i + 1;
|
i = i + 1;
|
||||||
}
|
}
|
||||||
print("\n");
|
print("\n");
|
||||||
|
|
||||||
for (i in array) {
|
// for (i in fixed_size) {
|
||||||
print(i as str);
|
// print(i as str);
|
||||||
print("\n");
|
// print("\n");
|
||||||
}
|
// }
|
||||||
|
|
||||||
halt;
|
halt;
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,8 @@ bool found = false;
|
||||||
for (nat x = 0; x < xSize; x++) {
|
for (nat x = 0; x < xSize; x++) {
|
||||||
for (nat y = 0; y < ySize; y++) {
|
for (nat y = 0; y < ySize; y++) {
|
||||||
for (nat z = 0; z < zSize; z++) {
|
for (nat z = 0; z < zSize; z++) {
|
||||||
if (matrix[x][y][z] == 0) {
|
if (matrix[x, y, z] == 0) {
|
||||||
print("found: [");
|
print("found '0' at [");
|
||||||
print(x as str);
|
print(x as str);
|
||||||
print(", ");
|
print(", ");
|
||||||
print(y as str);
|
print(y as str);
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ System system = devmap(0x00, System);
|
||||||
Screen screen = devmap(0x20, Screen);
|
Screen screen = devmap(0x20, Screen);
|
||||||
screen.vector = ref render_screen;
|
screen.vector = ref render_screen;
|
||||||
Mouse mouse = devmap(0x90, Mouse);
|
Mouse mouse = devmap(0x90, Mouse);
|
||||||
mouse.vector = ref render_screen;
|
mouse.vector = ref on_mouse_down;
|
||||||
halt;
|
halt;
|
||||||
|
|
||||||
function on_mouse_down() {
|
function on_mouse_down() {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue