add & float, init tok map

This commit is contained in:
zongor 2023-03-04 13:20:59 -05:00
parent 02d37d3bcc
commit ef263d9cc4
8 changed files with 924 additions and 676 deletions

View File

@ -1 +1 @@
BasedOnStyle: GNU BasedOnStyle: Mozilla

16
.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,16 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "lldb",
"request": "launch",
"name": "Debug",
"program": "${workspaceFolder}/varaq",
"args": ["tests/add.vq", "public/module.wasm"],
"cwd": "${workspaceFolder}"
}
]
}

View File

@ -1,9 +1,7 @@
CC = gcc CC = gcc
CCFLAGS= -g CCFLAGS= -g
all: varaq all:
varaq:
$(CC) $(CCFLAGS) -o varaq main.c compiler.c tokenizer.c $(CC) $(CCFLAGS) -o varaq main.c compiler.c tokenizer.c
clean: clean:

145
compile_test.c Normal file
View File

@ -0,0 +1,145 @@
#include "compiler.h"
#include "common.h"
#include "tokenizer.h"
Code *
demo_function_compile ()
{
Code *add_args_code = (Code *)calloc (1, sizeof (Code));
append_byte (add_args_code, f32);
append_byte (add_args_code, f32);
Code *add_return_code = (Code *)calloc (1, sizeof (Code));
append_byte (add_return_code, f32);
Code *add_function_type = (Code *)calloc (1, sizeof (Code));
append_byte (add_function_type, FUNCTION);
append (add_function_type, encodeVector (add_args_code));
append (add_function_type, encodeVector (add_return_code));
add_function_type->override = true;
add_function_type->override_count = 1;
Code *type_section = createSection (TYPE, encodeVector (add_function_type));
Code *return_type_code = (Code *)calloc (1, sizeof (Code));
append_byte (return_type_code, 0x00);
return_type_code->override = true;
return_type_code->override_count = 1;
Code *func_section = createSection (FUNC, encodeVector (return_type_code));
Code *exp = encodeString ("main");
append_byte (exp, EXPORT_FUNC);
append_byte (exp, 0x00);
exp->override = true;
exp->override_count = 1;
Code *export_section = createSection (EXPORT, encodeVector (exp));
Code *code = (Code *)calloc (1, sizeof (Code));
append_byte (code, LOCAL_GET);
append (code, unsignedLEB128 (0));
append_byte (code, LOCAL_GET);
append (code, unsignedLEB128 (1));
append_byte (code, F32_ADD);
Code *body = (Code *)calloc (1, sizeof (Code));
append_byte (body, EMPTY_ARRAY);
append (body, code);
append_byte (body, END);
Code *function_body = (Code *)calloc (1, sizeof (Code));
append (function_body, encodeVector (body));
function_body->override = true;
function_body->override_count = 1;
Code *code_section = createSection (CODE, encodeVector (function_body));
Code *tape = (Code *)malloc (sizeof (Code));
tape->cells = calloc (8, sizeof (uint8_t));
tape->cells[0] = 0;
tape->cells[1] = 'a';
tape->cells[2] = 's';
tape->cells[3] = 'm';
tape->cells[4] = 1;
tape->cells[5] = 0;
tape->cells[6] = 0;
tape->cells[7] = 0;
tape->count = 8;
append (tape, type_section);
append (tape, func_section);
append (tape, export_section);
append (tape, code_section);
return tape;
}
Code *
demo_add_compile ()
{
Code *add_args_code = (Code *)calloc (1, sizeof (Code));
Code *add_return_code = (Code *)calloc (1, sizeof (Code));
append_byte (add_return_code, f64);
Code *add_function_type = (Code *)calloc (1, sizeof (Code));
append_byte (add_function_type, FUNCTION);
append (add_function_type, encodeVector (add_args_code));
append (add_function_type, encodeVector (add_return_code));
add_function_type->override = true;
add_function_type->override_count = 1;
Code *type_section = createSection (TYPE, encodeVector (add_function_type));
Code *return_type_code = (Code *)calloc (1, sizeof (Code));
append_byte (return_type_code, 0x00);
return_type_code->override = true;
return_type_code->override_count = 1;
Code *func_section = createSection (FUNC, encodeVector (return_type_code));
Code *exp = encodeString ("main");
append_byte (exp, EXPORT_FUNC);
append_byte (exp, 0x00);
exp->override = true;
exp->override_count = 1;
Code *export_section = createSection (EXPORT, encodeVector (exp));
Code *code = (Code *)calloc (1, sizeof (Code));
append_byte (code, F64_CONST);
append_f64 (code, 6.7);
append_byte (code, F64_CONST);
append_f64 (code, 8.5);
append_byte (code, F64_ADD);
Code *body = (Code *)calloc (1, sizeof (Code));
append_byte (body, EMPTY_ARRAY);
append (body, code);
append_byte (body, END);
Code *function_body = (Code *)calloc (1, sizeof (Code));
append (function_body, encodeVector (body));
function_body->override = true;
function_body->override_count = 1;
Code *code_section = createSection (CODE, encodeVector (function_body));
Code *tape = (Code *)malloc (sizeof (Code));
tape->cells = calloc (8, sizeof (uint8_t));
tape->cells[0] = 0;
tape->cells[1] = 'a';
tape->cells[2] = 's';
tape->cells[3] = 'm';
tape->cells[4] = 1;
tape->cells[5] = 0;
tape->cells[6] = 0;
tape->cells[7] = 0;
tape->count = 8;
append (tape, type_section);
append (tape, func_section);
append (tape, export_section);
append (tape, code_section);
return tape;
}

View File

@ -11,27 +11,22 @@ signedLEB128 (size_t num)
buffer->count = 0; buffer->count = 0;
int n = (int)num; int n = (int)num;
while (more) while (more) {
{
uint8_t byte = n & 0x7f; uint8_t byte = n & 0x7f;
n >>= 7; n >>= 7;
if ((n == 0 && (byte & 0x40) == 0) || (n == -1 && (byte & 0x40) != 0)) if ((n == 0 && (byte & 0x40) == 0) || (n == -1 && (byte & 0x40) != 0)) {
{
more = false; more = false;
} } else {
else
{
byte |= 0x80; byte |= 0x80;
} }
size_t old_count = buffer->count; size_t old_count = buffer->count;
uint8_t *tmp = (uint8_t *)calloc ( uint8_t* tmp =
(old_count + 1), (uint8_t*)calloc((old_count + 1),
sizeof(uint8_t)); // really slow and bad refactor later sizeof(uint8_t)); // really slow and bad refactor later
memcpy(tmp, buffer->cells, buffer->count * sizeof(uint8_t)); memcpy(tmp, buffer->cells, buffer->count * sizeof(uint8_t));
if (tmp) if (tmp) {
{
buffer->cells = tmp; buffer->cells = tmp;
} }
buffer->cells[old_count] = byte; buffer->cells[old_count] = byte;
@ -48,70 +43,57 @@ unsignedLEB128 (size_t num)
buffer->count = 0; buffer->count = 0;
int n = (int)num; int n = (int)num;
do do {
{
uint8_t byte = n & 0x7f; uint8_t byte = n & 0x7f;
n >>= 7; n >>= 7;
if (n != 0) if (n != 0) {
{
byte |= 0x80; byte |= 0x80;
} }
size_t old_count = buffer->count; size_t old_count = buffer->count;
uint8_t *tmp = (uint8_t *)calloc ( uint8_t* tmp =
(old_count + 1), (uint8_t*)calloc((old_count + 1),
sizeof(uint8_t)); // really slow and bad refactor later sizeof(uint8_t)); // really slow and bad refactor later
memcpy(tmp, buffer->cells, buffer->count * sizeof(uint8_t)); memcpy(tmp, buffer->cells, buffer->count * sizeof(uint8_t));
if (tmp) if (tmp) {
{
buffer->cells = tmp; buffer->cells = tmp;
} }
buffer->cells[old_count] = byte; buffer->cells[old_count] = byte;
buffer->count += 1; buffer->count += 1;
} } while (n != 0);
while (n != 0);
return buffer; return buffer;
} }
Code* Code*
append_byte (Code *tape, uint8_t data) generic_append(Code* tape, void* data, size_t data_size)
{ {
size_t old_count = tape->count; size_t old_count = tape->count;
uint8_t *tmp = (uint8_t *)calloc ((old_count + 1), sizeof (uint8_t)); uint8_t* tmp = (uint8_t*)calloc((old_count + data_size), sizeof(uint8_t));
if (old_count > 0) if (old_count > 0) {
{
memcpy(tmp, tape->cells, tape->count * sizeof(uint8_t)); memcpy(tmp, tape->cells, tape->count * sizeof(uint8_t));
} }
if (tmp) if (tmp) {
{
tape->cells = tmp; tape->cells = tmp;
} }
tape->cells[old_count] = data;
tape->count += 1; memcpy((tape->cells + old_count), (unsigned char*)data, data_size);
tape->count += data_size;
return tape; return tape;
} }
Code*
append_byte(Code* tape, uint8_t data)
{
return generic_append(tape, &data, sizeof(uint8_t));
}
Code* Code*
append_f64(Code* tape, double data) append_f64(Code* tape, double data)
{ {
size_t old_count = tape->count; return generic_append(tape, &data, sizeof(double));
uint8_t *tmp
= (uint8_t *)calloc ((old_count + sizeof (data)), sizeof (uint8_t));
if (old_count > 0)
{
memcpy (tmp, tape->cells, tape->count * sizeof (uint8_t));
}
if (tmp)
{
tape->cells = tmp;
}
memcpy ((tape->cells + old_count), (unsigned char *)&data, sizeof (data));
tape->count += sizeof (data);
return tape;
} }
Code* Code*
@ -119,16 +101,13 @@ append (Code *tape, Code *data)
{ {
size_t old_count = tape->count; size_t old_count = tape->count;
uint8_t *tmp uint8_t* tmp = (uint8_t*)calloc((old_count + data->count), sizeof(uint8_t));
= (uint8_t *)calloc ((old_count + data->count), sizeof (uint8_t));
memcpy(tmp, tape->cells, tape->count * sizeof(uint8_t)); memcpy(tmp, tape->cells, tape->count * sizeof(uint8_t));
if (tmp) if (tmp) {
{
tape->cells = tmp; tape->cells = tmp;
} }
memcpy ((tape->cells + old_count), data->cells, memcpy((tape->cells + old_count), data->cells, data->count * sizeof(uint8_t));
data->count * sizeof (uint8_t));
tape->count += data->count; tape->count += data->count;
return tape; return tape;
} }
@ -143,8 +122,7 @@ encodeString (char *string)
uint8_t* tmp = (uint8_t*)malloc((1 + strlen(string)) * sizeof(char)); uint8_t* tmp = (uint8_t*)malloc((1 + strlen(string)) * sizeof(char));
memcpy(tmp, buffer->cells, buffer->count * sizeof(uint8_t)); memcpy(tmp, buffer->cells, buffer->count * sizeof(uint8_t));
if (tmp) if (tmp) {
{
buffer->cells = tmp; buffer->cells = tmp;
} }
@ -173,80 +151,10 @@ createSection (uint8_t section, Code *data)
} }
Code* Code*
demo_function_compile () compile(char* buffer)
{ {
Code *add_args_code = (Code *)calloc (1, sizeof (Code)); char number[100];
append_byte (add_args_code, f32);
append_byte (add_args_code, f32);
Code *add_return_code = (Code *)calloc (1, sizeof (Code));
append_byte (add_return_code, f32);
Code *add_function_type = (Code *)calloc (1, sizeof (Code));
append_byte (add_function_type, FUNCTION);
append (add_function_type, encodeVector (add_args_code));
append (add_function_type, encodeVector (add_return_code));
add_function_type->override = true;
add_function_type->override_count = 1;
Code *type_section = createSection (TYPE, encodeVector (add_function_type));
Code *return_type_code = (Code *)calloc (1, sizeof (Code));
append_byte (return_type_code, 0x00);
return_type_code->override = true;
return_type_code->override_count = 1;
Code *func_section = createSection (FUNC, encodeVector (return_type_code));
Code *exp = encodeString ("main");
append_byte (exp, EXPORT_FUNC);
append_byte (exp, 0x00);
exp->override = true;
exp->override_count = 1;
Code *export_section = createSection (EXPORT, encodeVector (exp));
Code *code = (Code *)calloc (1, sizeof (Code));
append_byte (code, LOCAL_GET);
append (code, unsignedLEB128 (0));
append_byte (code, LOCAL_GET);
append (code, unsignedLEB128 (1));
append_byte (code, F32_ADD);
Code *body = (Code *)calloc (1, sizeof (Code));
append_byte (body, EMPTY_ARRAY);
append (body, code);
append_byte (body, END);
Code *function_body = (Code *)calloc (1, sizeof (Code));
append (function_body, encodeVector (body));
function_body->override = true;
function_body->override_count = 1;
Code *code_section = createSection (CODE, encodeVector (function_body));
Code *tape = (Code *)malloc (sizeof (Code));
tape->cells = calloc (8, sizeof (uint8_t));
tape->cells[0] = 0;
tape->cells[1] = 'a';
tape->cells[2] = 's';
tape->cells[3] = 'm';
tape->cells[4] = 1;
tape->cells[5] = 0;
tape->cells[6] = 0;
tape->cells[7] = 0;
tape->count = 8;
append (tape, type_section);
append (tape, func_section);
append (tape, export_section);
append (tape, code_section);
return tape;
}
Code *
demo_add_compile ()
{
Code* add_args_code = (Code*)calloc(1, sizeof(Code)); Code* add_args_code = (Code*)calloc(1, sizeof(Code));
Code* add_return_code = (Code*)calloc(1, sizeof(Code)); Code* add_return_code = (Code*)calloc(1, sizeof(Code));
append_byte(add_return_code, f64); append_byte(add_return_code, f64);
@ -275,12 +183,209 @@ demo_add_compile ()
exp->override_count = 1; exp->override_count = 1;
Code* export_section = createSection(EXPORT, encodeVector(exp)); Code* export_section = createSection(EXPORT, encodeVector(exp));
// Code* code = (Code*)calloc(1, sizeof(Code));
// append_byte(code, F64_CONST);
// append_f64(code, 1.0);
// append_byte(code, F64_CONST);
// append_f64(code, 2.0);
// append_byte(code, F64_ADD);
Code* code = (Code*)calloc(1, sizeof(Code)); Code* code = (Code*)calloc(1, sizeof(Code));
initTokenizer(buffer);
Token t = nextToken();
do {
// debug_printToken(t);
switch (t.type) {
case TOKEN_LEFT_PAREN:
break;
case TOKEN_RIGHT_PAREN:
break;
case TOKEN_LEFT_BRACE:
break;
case TOKEN_RIGHT_BRACE:
break;
case TOKEN_TILDE:
break;
case TOKEN_SLASH:
break;
case TOKEN_MINUS:
break;
case TOKEN_IDENTIFIER:
break;
case TOKEN_STRING:
break;
case TOKEN_FLOAT:
strncpy(number, t.start, t.length);
number[t.length + 1] = '\0';
append_byte(code, F64_CONST); append_byte(code, F64_CONST);
append_f64 (code, 6.7); append_f64(code, strtod(number, NULL));
append_byte (code, F64_CONST); break;
append_f64 (code, 8.5); case TOKEN_LIST:
break;
case TOKEN_ERROR:
break;
case TOKEN_FALSE:
break;
case TOKEN_TRUE:
break;
case TOKEN_PI:
break;
case TOKEN_E:
break;
case TOKEN_EOF:
break;
case TOKEN_POP:
break;
case TOKEN_DUP:
break;
case TOKEN_EXCH:
break;
case TOKEN_CLEAR:
break;
case TOKEN_REMEMBER:
break;
case TOKEN_FORGET:
break;
case TOKEN_DUMP:
break;
case TOKEN_NAME:
break;
case TOKEN_SET:
break;
case TOKEN_IFYES:
break;
case TOKEN_IFNO:
break;
case TOKEN_CHOOSE:
break;
case TOKEN_EVAL:
break;
case TOKEN_ESCAPE:
break;
case TOKEN_REPEAT:
break;
case TOKEN_SPLIT:
break;
case TOKEN_CONS:
break;
case TOKEN_SHATTER:
break;
case TOKEN_EMPTY:
break;
case TOKEN_COMPOSE:
break;
case TOKEN_STREQ:
break;
case TOKEN_STRCUT:
break;
case TOKEN_STRMEASURE:
break;
case TOKEN_STRTIE:
break;
case TOKEN_EXPLODE:
break;
case TOKEN_ADD:
append_byte(code, F64_ADD); append_byte(code, F64_ADD);
break;
case TOKEN_SUB:
break;
case TOKEN_MUL:
break;
case TOKEN_DIV:
break;
case TOKEN_IDIV:
break;
case TOKEN_MOD:
break;
case TOKEN_POW:
break;
case TOKEN_SQRT:
break;
case TOKEN_ADD1:
break;
case TOKEN_SUB1:
break;
case TOKEN_SIN:
break;
case TOKEN_COS:
break;
case TOKEN_TAN:
break;
case TOKEN_ATAN:
break;
case TOKEN_LN:
break;
case TOKEN_LOG:
break;
case TOKEN_LOG3:
break;
case TOKEN_CLIP:
break;
case TOKEN_SMOOTH:
break;
case TOKEN_HOWMUCH:
break;
case TOKEN_SETRAND:
break;
case TOKEN_RAND:
break;
case TOKEN_INT:
break;
case TOKEN_NUMBERIZE:
break;
case TOKEN_ISOLATE:
break;
case TOKEN_MIX:
break;
case TOKEN_CONTRADICT:
break;
case TOKEN_COMPL:
break;
case TOKEN_SHIFTRIGHT:
break;
case TOKEN_SHIFTLEFT:
break;
case TOKEN_GT:
break;
case TOKEN_LT:
break;
case TOKEN_EQ:
break;
case TOKEN_GE:
break;
case TOKEN_LE:
break;
case TOKEN_NE:
break;
case TOKEN_NULL:
break;
case TOKEN_NEGATIVE:
break;
case TOKEN_ISNULL:
break;
case TOKEN_ISINT:
break;
case TOKEN_ISNUMBER:
break;
case TOKEN_AND:
break;
case TOKEN_OR:
break;
case TOKEN_XOR:
break;
case TOKEN_DISP:
break;
case TOKEN_LISTEN:
break;
case TOKEN_COMPLAIN:
break;
case TOKEN_TIME:
break;
case TOKEN_GARBAGE_COLLECT:
break;
}
t = nextToken();
} while (t.type != TOKEN_EOF);
Code* body = (Code*)calloc(1, sizeof(Code)); Code* body = (Code*)calloc(1, sizeof(Code));
append_byte(body, EMPTY_ARRAY); append_byte(body, EMPTY_ARRAY);
@ -309,32 +414,5 @@ demo_add_compile ()
append(tape, func_section); append(tape, func_section);
append(tape, export_section); append(tape, export_section);
append(tape, code_section); append(tape, code_section);
return tape;
}
Code *
compile (char *buffer)
{
Code *tape = (Code *)malloc (sizeof (Code));
tape->cells = calloc (8, sizeof (uint8_t));
tape->cells[0] = 0;
tape->cells[1] = 'a';
tape->cells[2] = 's';
tape->cells[3] = 'm';
tape->cells[4] = 1;
tape->cells[5] = 0;
tape->cells[6] = 0;
tape->cells[7] = 0;
tape->count = 8;
initTokenizer (buffer);
Token t = nextToken ();
while (t.type != TOKEN_EOF)
{
debug_printToken (t);
t = nextToken ();
}
return tape; return tape;
} }

10
main.c
View File

@ -5,8 +5,7 @@
int int
main(int argc, char** argv) main(int argc, char** argv)
{ {
if (argc != 3) if (argc != 3) {
{
printf("usage: varaq input.vq output.wasm"); printf("usage: varaq input.vq output.wasm");
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@ -15,18 +14,17 @@ main (int argc, char **argv)
int length = 0; int length = 0;
int sp = open(argv[1], O_RDONLY); int sp = open(argv[1], O_RDONLY);
if (sp) if (sp) {
{
length = lseek(sp, (size_t)0, SEEK_END); length = lseek(sp, (size_t)0, SEEK_END);
lseek(sp, (size_t)0, SEEK_SET); lseek(sp, (size_t)0, SEEK_SET);
buffer = malloc(length); buffer = malloc(length);
if (buffer) if (buffer) {
{
read(sp, buffer, length * sizeof(char)); read(sp, buffer, length * sizeof(char));
} }
close(sp); close(sp);
} }
initMap();
Code* prog = compile(buffer); Code* prog = compile(buffer);
int tp = open(argv[2], O_CREAT | O_WRONLY, S_IRWXU | S_IRGRP | S_IROTH); int tp = open(argv[2], O_CREAT | O_WRONLY, S_IRWXU | S_IRGRP | S_IROTH);

19
mkfile Normal file
View File

@ -0,0 +1,19 @@
</$objtype/mkfile
prog: main.$O compiler.$O tokenizer.$O
$LD $LDFLAGS -o $target $prereq
%.$O: %.c
$CC $CFLAGS $stem.c
install: $O.out
cp $O.out /$objtype/bin/varaq
installall:
for(objtype in $CPUS) mk install
clean:V:
rm -f [$OS].out *.[$OS] y.tab.?

View File

@ -50,8 +50,7 @@ put (char *keyword, TokenType token)
{ {
Map* np; Map* np;
unsigned int hashval; unsigned int hashval;
if ((np = lookup (keyword)) == NULL) if ((np = lookup(keyword)) == NULL) {
{
np = (Map*)malloc(sizeof(*np)); np = (Map*)malloc(sizeof(*np));
if (np == NULL || (np->keyword = strdup(keyword)) == NULL) if (np == NULL || (np->keyword = strdup(keyword)) == NULL)
return NULL; return NULL;
@ -240,8 +239,8 @@ initTokenizer (char *src)
static bool static bool
isAlpha(char c) isAlpha(char c)
{ {
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' ||
|| c == '\'' || c == '?'; c == '\'' || c == '?';
} }
static bool static bool
@ -313,11 +312,9 @@ match (char expected)
static void static void
skipWhitespace() skipWhitespace()
{ {
for (;;) for (;;) {
{
char c = peek(); char c = peek();
switch (c) switch (c) {
{
case ' ': case ' ':
case '\r': case '\r':
case '\t': case '\t':
@ -328,20 +325,16 @@ skipWhitespace ()
advance(); advance();
break; break;
case '/': case '/':
if (peekNext () == '/') if (peekNext() == '/') {
{
// Ignore the preprocessor import until end of the line. // Ignore the preprocessor import until end of the line.
while (peek() != '\n' && !isAtEnd()) while (peek() != '\n' && !isAtEnd())
advance(); advance();
} } else {
else
{
return; return;
} }
break; break;
case '(': case '(':
if (peekNext () == '*') if (peekNext() == '*') {
{
advance(); // consume ( advance(); // consume (
advance(); // consume * advance(); // consume *
while (!isAtEnd() && peek() != '*' && peekNext() != ')') while (!isAtEnd() && peek() != '*' && peekNext() != ')')
@ -359,9 +352,8 @@ skipWhitespace ()
static TokenType static TokenType
checkKeyword(int start, int length, char* rest, TokenType type) checkKeyword(int start, int length, char* rest, TokenType type)
{ {
if (tokenizer.current - tokenizer.start == start + length if (tokenizer.current - tokenizer.start == start + length &&
&& memcmp (tokenizer.start + start, rest, length) == 0) memcmp(tokenizer.start + start, rest, length) == 0) {
{
return type; return type;
} }
@ -397,8 +389,7 @@ number ()
advance(); advance();
// Look for a fractional part. // Look for a fractional part.
if (peek () == '.' && isDigit (peekNext ())) if (peek() == '.' && isDigit(peekNext())) {
{
is_float = true; is_float = true;
// Consume the ".". // Consume the ".".
advance(); advance();
@ -407,15 +398,13 @@ number ()
advance(); advance();
} }
return makeToken (is_float ? TOKEN_FLOAT return makeToken(TOKEN_FLOAT); // or measure if ends in postscript
: TOKEN_INT); // or measure if ends in postscript
} }
static Token static Token
string() string()
{ {
while (peek () != '"' && !isAtEnd ()) while (peek() != '"' && !isAtEnd()) {
{
if (peek() == '\n') if (peek() == '\n')
tokenizer.line++; tokenizer.line++;
advance(); advance();
@ -442,8 +431,7 @@ nextToken ()
return identifier(); return identifier();
if (isDigit(c)) if (isDigit(c))
return number(); return number();
switch (c) switch (c) {
{
case '(': case '(':
return makeToken(TOKEN_LEFT_PAREN); return makeToken(TOKEN_LEFT_PAREN);
case ')': case ')':
@ -468,280 +456,286 @@ nextToken ()
void void
debug_printToken(Token t) debug_printToken(Token t)
{ {
switch (t.type) char* str;
{ int32_t size = tokenizer.current - tokenizer.start;
str = (char*)malloc(sizeof(size));
strncpy(str, tokenizer.start, size);
str[size] = '\0';
switch (t.type) {
case TOKEN_LEFT_PAREN: case TOKEN_LEFT_PAREN:
printf ("TOKEN_LEFT_PAREN line_no=%d\n", t.line); printf("TOKEN_LEFT_PAREN %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_RIGHT_PAREN: case TOKEN_RIGHT_PAREN:
printf ("TOKEN_RIGHT_PAREN line_no=%d\n", t.line); printf("TOKEN_RIGHT_PAREN %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_LEFT_BRACE: case TOKEN_LEFT_BRACE:
printf ("TOKEN_LEFT_BRACE line_no=%d\n", t.line); printf("TOKEN_LEFT_BRACE %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_RIGHT_BRACE: case TOKEN_RIGHT_BRACE:
printf ("TOKEN_RIGHT_BRACE line_no=%d\n", t.line); printf("TOKEN_RIGHT_BRACE %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_TILDE: case TOKEN_TILDE:
printf ("TOKEN_TILDE line_no=%d\n", t.line); printf("TOKEN_TILDE %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_SLASH: case TOKEN_SLASH:
printf ("TOKEN_SLASH line_no=%d\n", t.line); printf("TOKEN_SLASH %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_MINUS: case TOKEN_MINUS:
printf ("TOKEN_MINUS line_no=%d\n", t.line); printf("TOKEN_MINUS %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_IDENTIFIER: case TOKEN_IDENTIFIER:
printf ("TOKEN_IDENTIFIER line_no=%d\n", t.line); printf("TOKEN_IDENTIFIER %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_STRING: case TOKEN_STRING:
printf ("TOKEN_STRING line_no=%d\n", t.line); printf("TOKEN_STRING %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_FLOAT: case TOKEN_FLOAT:
printf ("TOKEN_FLOAT line_no=%d\n", t.line); printf("TOKEN_FLOAT %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_LIST: case TOKEN_LIST:
printf ("TOKEN_LIST line_no=%d\n", t.line); printf("TOKEN_LIST %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_ERROR: case TOKEN_ERROR:
printf ("TOKEN_ERROR line_no=%d\n", t.line); printf("TOKEN_ERROR %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_FALSE: case TOKEN_FALSE:
printf ("TOKEN_FALSE line_no=%d\n", t.line); printf("TOKEN_FALSE %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_TRUE: case TOKEN_TRUE:
printf ("TOKEN_TRUE line_no=%d\n", t.line); printf("TOKEN_TRUE %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_PI: case TOKEN_PI:
printf ("TOKEN_PI line_no=%d\n", t.line); printf("TOKEN_PI %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_E: case TOKEN_E:
printf ("TOKEN_E line_no=%d\n", t.line); printf("TOKEN_E %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_EOF: case TOKEN_EOF:
printf ("TOKEN_EOF line_no=%d\n", t.line); printf("TOKEN_EOF %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_POP: case TOKEN_POP:
printf ("TOKEN_POP line_no=%d\n", t.line); printf("TOKEN_POP %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_DUP: case TOKEN_DUP:
printf ("TOKEN_DUP line_no=%d\n", t.line); printf("TOKEN_DUP %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_EXCH: case TOKEN_EXCH:
printf ("TOKEN_EXCH line_no=%d\n", t.line); printf("TOKEN_EXCH %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_CLEAR: case TOKEN_CLEAR:
printf ("TOKEN_CLEAR line_no=%d\n", t.line); printf("TOKEN_CLEAR %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_REMEMBER: case TOKEN_REMEMBER:
printf ("TOKEN_REMEMBER line_no=%d\n", t.line); printf("TOKEN_REMEMBER %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_FORGET: case TOKEN_FORGET:
printf ("TOKEN_FORGET line_no=%d\n", t.line); printf("TOKEN_FORGET %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_DUMP: case TOKEN_DUMP:
printf ("TOKEN_DUMP line_no=%d\n", t.line); printf("TOKEN_DUMP %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_NAME: case TOKEN_NAME:
printf ("TOKEN_NAME line_no=%d\n", t.line); printf("TOKEN_NAME %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_SET: case TOKEN_SET:
printf ("TOKEN_SET line_no=%d\n", t.line); printf("TOKEN_SET %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_IFYES: case TOKEN_IFYES:
printf ("TOKEN_IFYES line_no=%d\n", t.line); printf("TOKEN_IFYES %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_IFNO: case TOKEN_IFNO:
printf ("TOKEN_IFNO line_no=%d\n", t.line); printf("TOKEN_IFNO %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_CHOOSE: case TOKEN_CHOOSE:
printf ("TOKEN_CHOOSE line_no=%d\n", t.line); printf("TOKEN_CHOOSE %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_EVAL: case TOKEN_EVAL:
printf ("TOKEN_EVAL line_no=%d\n", t.line); printf("TOKEN_EVAL %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_ESCAPE: case TOKEN_ESCAPE:
printf ("TOKEN_ESCAPE line_no=%d\n", t.line); printf("TOKEN_ESCAPE %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_REPEAT: case TOKEN_REPEAT:
printf ("TOKEN_REPEAT line_no=%d\n", t.line); printf("TOKEN_REPEAT %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_SPLIT: case TOKEN_SPLIT:
printf ("TOKEN_SPLIT line_no=%d\n", t.line); printf("TOKEN_SPLIT %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_CONS: case TOKEN_CONS:
printf ("TOKEN_CONS line_no=%d\n", t.line); printf("TOKEN_CONS %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_SHATTER: case TOKEN_SHATTER:
printf ("TOKEN_SHATTER line_no=%d\n", t.line); printf("TOKEN_SHATTER %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_EMPTY: case TOKEN_EMPTY:
printf ("TOKEN_EMPTY line_no=%d\n", t.line); printf("TOKEN_EMPTY %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_COMPOSE: case TOKEN_COMPOSE:
printf ("TOKEN_COMPOSE line_no=%d\n", t.line); printf("TOKEN_COMPOSE %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_STREQ: case TOKEN_STREQ:
printf ("TOKEN_STREQ line_no=%d\n", t.line); printf("TOKEN_STREQ %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_STRCUT: case TOKEN_STRCUT:
printf ("TOKEN_STRCUT line_no=%d\n", t.line); printf("TOKEN_STRCUT %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_STRMEASURE: case TOKEN_STRMEASURE:
printf ("TOKEN_STRMEASURE line_no=%d\n", t.line); printf("TOKEN_STRMEASURE %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_STRTIE: case TOKEN_STRTIE:
printf ("TOKEN_STRTIE line_no=%d\n", t.line); printf("TOKEN_STRTIE %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_EXPLODE: case TOKEN_EXPLODE:
printf ("TOKEN_EXPLODE line_no=%d\n", t.line); printf("TOKEN_EXPLODE %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_ADD: case TOKEN_ADD:
printf ("TOKEN_ADD line_no=%d\n", t.line); printf("TOKEN_ADD %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_SUB: case TOKEN_SUB:
printf ("TOKEN_SUB line_no=%d\n", t.line); printf("TOKEN_SUB %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_MUL: case TOKEN_MUL:
printf ("TOKEN_MUL line_no=%d\n", t.line); printf("TOKEN_MUL %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_DIV: case TOKEN_DIV:
printf ("TOKEN_DIV line_no=%d\n", t.line); printf("TOKEN_DIV %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_IDIV: case TOKEN_IDIV:
printf ("TOKEN_IDIV line_no=%d\n", t.line); printf("TOKEN_IDIV %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_MOD: case TOKEN_MOD:
printf ("TOKEN_MOD line_no=%d\n", t.line); printf("TOKEN_MOD %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_POW: case TOKEN_POW:
printf ("TOKEN_POW line_no=%d\n", t.line); printf("TOKEN_POW %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_SQRT: case TOKEN_SQRT:
printf ("TOKEN_SQRT line_no=%d\n", t.line); printf("TOKEN_SQRT %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_ADD1: case TOKEN_ADD1:
printf ("TOKEN_ADD1 line_no=%d\n", t.line); printf("TOKEN_ADD1 %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_SUB1: case TOKEN_SUB1:
printf ("TOKEN_SUB1 line_no=%d\n", t.line); printf("TOKEN_SUB1 %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_SIN: case TOKEN_SIN:
printf ("TOKEN_SIN line_no=%d\n", t.line); printf("TOKEN_SIN %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_COS: case TOKEN_COS:
printf ("TOKEN_COS line_no=%d\n", t.line); printf("TOKEN_COS %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_TAN: case TOKEN_TAN:
printf ("TOKEN_TAN line_no=%d\n", t.line); printf("TOKEN_TAN %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_ATAN: case TOKEN_ATAN:
printf ("TOKEN_ATAN line_no=%d\n", t.line); printf("TOKEN_ATAN %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_LN: case TOKEN_LN:
printf ("TOKEN_LN line_no=%d\n", t.line); printf("TOKEN_LN %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_LOG: case TOKEN_LOG:
printf ("TOKEN_LOG line_no=%d\n", t.line); printf("TOKEN_LOG %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_LOG3: case TOKEN_LOG3:
printf ("TOKEN_LOG3 line_no=%d\n", t.line); printf("TOKEN_LOG3 %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_CLIP: case TOKEN_CLIP:
printf ("TOKEN_CLIP line_no=%d\n", t.line); printf("TOKEN_CLIP %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_SMOOTH: case TOKEN_SMOOTH:
printf ("TOKEN_SMOOTH line_no=%d\n", t.line); printf("TOKEN_SMOOTH %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_HOWMUCH: case TOKEN_HOWMUCH:
printf ("TOKEN_HOWMUCH line_no=%d\n", t.line); printf("TOKEN_HOWMUCH %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_SETRAND: case TOKEN_SETRAND:
printf ("TOKEN_SETRAND line_no=%d\n", t.line); printf("TOKEN_SETRAND %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_RAND: case TOKEN_RAND:
printf ("TOKEN_RAND line_no=%d\n", t.line); printf("TOKEN_RAND %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_INT: case TOKEN_INT:
printf ("TOKEN_INT line_no=%d\n", t.line); printf("TOKEN_INT %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_NUMBERIZE: case TOKEN_NUMBERIZE:
printf ("TOKEN_NUMBERIZE line_no=%d\n", t.line); printf("TOKEN_NUMBERIZE %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_ISOLATE: case TOKEN_ISOLATE:
printf ("TOKEN_ISOLATE line_no=%d\n", t.line); printf("TOKEN_ISOLATE %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_MIX: case TOKEN_MIX:
printf ("TOKEN_MIX line_no=%d\n", t.line); printf("TOKEN_MIX %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_CONTRADICT: case TOKEN_CONTRADICT:
printf ("TOKEN_CONTRADICT line_no=%d\n", t.line); printf("TOKEN_CONTRADICT %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_COMPL: case TOKEN_COMPL:
printf ("TOKEN_COMPL line_no=%d\n", t.line); printf("TOKEN_COMPL %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_SHIFTRIGHT: case TOKEN_SHIFTRIGHT:
printf ("TOKEN_SHIFTRIGHT line_no=%d\n", t.line); printf("TOKEN_SHIFTRIGHT %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_SHIFTLEFT: case TOKEN_SHIFTLEFT:
printf ("TOKEN_SHIFTLEFT line_no=%d\n", t.line); printf("TOKEN_SHIFTLEFT %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_GT: case TOKEN_GT:
printf ("TOKEN_GT line_no=%d\n", t.line); printf("TOKEN_GT %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_LT: case TOKEN_LT:
printf ("TOKEN_LT line_no=%d\n", t.line); printf("TOKEN_LT %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_EQ: case TOKEN_EQ:
printf ("TOKEN_EQ line_no=%d\n", t.line); printf("TOKEN_EQ %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_GE: case TOKEN_GE:
printf ("TOKEN_GE line_no=%d\n", t.line); printf("TOKEN_GE %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_LE: case TOKEN_LE:
printf ("TOKEN_LE line_no=%d\n", t.line); printf("TOKEN_LE %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_NE: case TOKEN_NE:
printf ("TOKEN_NE line_no=%d\n", t.line); printf("TOKEN_NE %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_NULL: case TOKEN_NULL:
printf ("TOKEN_NULL line_no=%d\n", t.line); printf("TOKEN_NULL %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_NEGATIVE: case TOKEN_NEGATIVE:
printf ("TOKEN_NEGATIVE line_no=%d\n", t.line); printf("TOKEN_NEGATIVE %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_ISNULL: case TOKEN_ISNULL:
printf ("TOKEN_ISNULL line_no=%d\n", t.line); printf("TOKEN_ISNULL %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_ISINT: case TOKEN_ISINT:
printf ("TOKEN_ISINT line_no=%d\n", t.line); printf("TOKEN_ISINT %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_ISNUMBER: case TOKEN_ISNUMBER:
printf ("TOKEN_ISNUMBER line_no=%d\n", t.line); printf("TOKEN_ISNUMBER %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_AND: case TOKEN_AND:
printf ("TOKEN_AND line_no=%d\n", t.line); printf("TOKEN_AND %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_OR: case TOKEN_OR:
printf ("TOKEN_OR line_no=%d\n", t.line); printf("TOKEN_OR %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_XOR: case TOKEN_XOR:
printf ("TOKEN_XOR line_no=%d\n", t.line); printf("TOKEN_XOR %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_DISP: case TOKEN_DISP:
printf ("TOKEN_DISP line_no=%d\n", t.line); printf("TOKEN_DISP %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_LISTEN: case TOKEN_LISTEN:
printf ("TOKEN_LISTEN line_no=%d\n", t.line); printf("TOKEN_LISTEN %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_COMPLAIN: case TOKEN_COMPLAIN:
printf ("TOKEN_COMPLAIN line_no=%d\n", t.line); printf("TOKEN_COMPLAIN %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_TIME: case TOKEN_TIME:
printf ("TOKEN_TIME line_no=%d\n", t.line); printf("TOKEN_TIME %s line_no=%d\n", str, t.line);
break; break;
case TOKEN_GARBAGE_COLLECT: case TOKEN_GARBAGE_COLLECT:
printf ("TOKEN_GARBAGE_COLLECT line_no=%d\n", t.line); printf("TOKEN_GARBAGE_COLLECT %s line_no=%d\n", str, t.line);
break; break;
} }
free(str);
} }