Compare commits
2 Commits
9c94e4a6ef
...
49f7189470
Author | SHA1 | Date |
---|---|---|
|
49f7189470 | |
|
fefc9e803a |
|
@ -7,7 +7,7 @@
|
|||
! Camera .
|
||||
!!
|
||||
type Camera {
|
||||
init(pos [3]real, look [3]real) {
|
||||
init(real[3] pos, real[3] look) {
|
||||
this.setting = "CAMERA_PERSPECTIVE";
|
||||
this.pov = 45.0;
|
||||
this.up = [0.0, 1.0, 0.0];
|
||||
|
@ -20,7 +20,7 @@ type Camera {
|
|||
! Player .
|
||||
!!
|
||||
type Player {
|
||||
init(username str, pos real[3], color Color) {
|
||||
init(str username, real[3] pos, Color color) {
|
||||
this.server = Client("tcp://localhost:25565");
|
||||
this.username = username;
|
||||
this.pos = pos;
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#define ZRE_DEBUG_H
|
||||
|
||||
#include "vm.h"
|
||||
#include "parser.h"
|
||||
#include "opcodes.h"
|
||||
|
||||
int core_dump(VM *vm);
|
||||
|
|
|
@ -1,89 +0,0 @@
|
|||
#ifndef HASHMAP_H
|
||||
#define HASHMAP_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
char *strdup(const char *s) {
|
||||
size_t len = strlen(s) + 1;
|
||||
char *copy = (char*)malloc(len);
|
||||
if (copy) {
|
||||
memcpy(copy, s, len);
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
|
||||
#define DEFINE_HASHMAP(StructType, HASHSIZE) \
|
||||
unsigned int hash_##StructType(char *s) { \
|
||||
unsigned int hashval; \
|
||||
for (hashval = 0; *s != '\0'; s++) \
|
||||
hashval = *s + 31 * hashval; \
|
||||
return hashval % HASHSIZE; \
|
||||
} \
|
||||
\
|
||||
StructType *get_##StructType(StructType **map, char *s) { \
|
||||
StructType *np; \
|
||||
for (np = map[hash_##StructType(s)]; np != NULL; np = np->next) \
|
||||
if (strcmp(s, np->keyword) == 0) \
|
||||
return np; \
|
||||
return NULL; \
|
||||
} \
|
||||
\
|
||||
StructType *put_##StructType(StructType **map, char *keyword, TokenType token) { \
|
||||
StructType *np; \
|
||||
unsigned int hashval; \
|
||||
if ((np = get_##StructType(map, keyword)) == NULL) { \
|
||||
np = (StructType *)malloc(sizeof(*np)); \
|
||||
if (np == NULL || (np->keyword = strdup(keyword)) == NULL) \
|
||||
return NULL; \
|
||||
hashval = hash_##StructType(keyword); \
|
||||
np->next = map[hashval]; \
|
||||
map[hashval] = np; \
|
||||
} \
|
||||
np->token = token; \
|
||||
return np; \
|
||||
} \
|
||||
\
|
||||
int delete_##StructType(StructType **map, char *keyword) { \
|
||||
unsigned int hashval = hash_##StructType(keyword); \
|
||||
StructType *current = map[hashval]; \
|
||||
StructType *prev = NULL; \
|
||||
while (current) { \
|
||||
if (strcmp(current->keyword, keyword) == 0) { \
|
||||
if (prev) { \
|
||||
prev->next = current->next; \
|
||||
} else { \
|
||||
map[hashval] = current->next; \
|
||||
} \
|
||||
free(current->keyword); \
|
||||
free(current); \
|
||||
return 1; \
|
||||
} \
|
||||
prev = current; \
|
||||
current = current->next; \
|
||||
} \
|
||||
return 0; \
|
||||
} \
|
||||
\
|
||||
StructType **new_##StructType() { \
|
||||
StructType **map = (StructType **)calloc(HASHSIZE, sizeof(StructType *)); \
|
||||
if (!map) return NULL; \
|
||||
return map; \
|
||||
} \
|
||||
\
|
||||
void free_##StructType(StructType **map) { \
|
||||
if (!map) return; \
|
||||
int i; \
|
||||
for (i = 0; i < HASHSIZE; i++) { \
|
||||
StructType *current = map[i]; \
|
||||
while (current) { \
|
||||
StructType *next = current->next; \
|
||||
free(current->keyword); \
|
||||
free(current); \
|
||||
current = next; \
|
||||
} \
|
||||
} \
|
||||
free(map); \
|
||||
}
|
||||
|
||||
#endif
|
27
src/main.c
27
src/main.c
|
@ -1,14 +1,10 @@
|
|||
#include "compiler.h"
|
||||
#include "test.h"
|
||||
#include "debug.h"
|
||||
#include "parser.h"
|
||||
#include "vm.h"
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/uio.h>
|
||||
#include <unistd.h>
|
||||
|
@ -30,27 +26,6 @@ void mainloop() {
|
|||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
if (argc != 2) {
|
||||
printf("usage: zre input.zre");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
char *buffer;
|
||||
int length = 0;
|
||||
int sp = open(argv[1], O_RDONLY);
|
||||
|
||||
if (sp) {
|
||||
length = lseek(sp, (size_t)0, SEEK_END);
|
||||
lseek(sp, (size_t)0, SEEK_SET);
|
||||
buffer = malloc(length);
|
||||
if (buffer) {
|
||||
read(sp, buffer, length * sizeof(char));
|
||||
}
|
||||
close(sp);
|
||||
}
|
||||
|
||||
initTokenMap();
|
||||
compile(vm.memory, buffer);
|
||||
vm.frames_size = FRAMES_SIZE;
|
||||
vm.stack_size = STACK_SIZE;
|
||||
vm.memory_size = MEMORY_SIZE;
|
||||
|
|
|
@ -15,9 +15,9 @@ typedef struct {
|
|||
uint32_t end;
|
||||
} Slice;
|
||||
|
||||
#define MAX_REGS 256
|
||||
#define MAX_REGS 32
|
||||
typedef struct {
|
||||
Value registers[MAX_REGS]; /* R0-R255 */
|
||||
Value registers[MAX_REGS]; /* R0-R31 */
|
||||
uint32_t rp; /* register pointer (last unused) */
|
||||
Slice allocated; /* start and end of global allocated block */
|
||||
} Frame;
|
||||
|
@ -55,9 +55,9 @@ typedef enum {
|
|||
OP_POPF, /* popf : pop float from stack onto the register */
|
||||
OP_POPS, /* pops : pop str ref from stack and move/copy to register */
|
||||
OP_ADD_INT, /* addi : dest = src1 + src2 */
|
||||
OP_SUB_INT, /* subs : dest = src1 - src2 */
|
||||
OP_MUL_INT, /* mulm : dest = src1 * src2 */
|
||||
OP_DIV_INT, /* divd : dest = src1 / src2 */
|
||||
OP_SUB_INT, /* subi : dest = src1 - src2 */
|
||||
OP_MUL_INT, /* muli : dest = src1 * src2 */
|
||||
OP_DIV_INT, /* divi : dest = src1 / src2 */
|
||||
OP_JEQ_INT, /* jeqi : jump to address dest if src1 as int == src2 as int */
|
||||
OP_JGT_INT, /* jgti : jump to address dest if src1 as int > src2 as int*/
|
||||
OP_JLT_INT, /* jlti : jump to address dest if src1 as int < src2 as int */
|
||||
|
@ -92,8 +92,8 @@ typedef enum {
|
|||
OP_INT_TO_STRING, /* itos : dest = src1 as str */
|
||||
OP_UINT_TO_STRING, /* utos : dest = src1 as str */
|
||||
OP_REAL_TO_STRING, /* rtos : dest = src1 as str */
|
||||
OP_READ_STRING, /* read : dest = read as str */
|
||||
OP_PRINT_STRING, /* wrte : write src1 to stdout */
|
||||
OP_READ_STRING, /* gets : dest = gets as str */
|
||||
OP_PRINT_STRING, /* puts : write src1 to stdout */
|
||||
OP_CMP_STRING, /* cmps : dest = (str == src2) as bool */
|
||||
} Opcode;
|
||||
|
||||
|
|
312
src/parser.c
312
src/parser.c
|
@ -1,312 +0,0 @@
|
|||
#include "parser.h"
|
||||
#include "hashmap.h"
|
||||
|
||||
DEFINE_HASHMAP(TokenMap, 150);
|
||||
|
||||
TokenMap **tokenMap;
|
||||
|
||||
void initTokenMap() {
|
||||
tokenMap = new_TokenMap();
|
||||
|
||||
put_TokenMap(tokenMap, "fn", TOKEN_FN);
|
||||
put_TokenMap(tokenMap, "to", TOKEN_TO);
|
||||
put_TokenMap(tokenMap, "in", TOKEN_IN);
|
||||
put_TokenMap(tokenMap, "is", TOKEN_IS);
|
||||
put_TokenMap(tokenMap, "as", TOKEN_AS);
|
||||
put_TokenMap(tokenMap, "use", TOKEN_USE);
|
||||
put_TokenMap(tokenMap, "if", TOKEN_IF);
|
||||
put_TokenMap(tokenMap, "else", TOKEN_ELSE);
|
||||
put_TokenMap(tokenMap, "default", TOKEN_DEFAULT);
|
||||
put_TokenMap(tokenMap, "for", TOKEN_FOR);
|
||||
put_TokenMap(tokenMap, "try", TOKEN_TRY);
|
||||
put_TokenMap(tokenMap, "catch", TOKEN_CATCH);
|
||||
put_TokenMap(tokenMap, "while", TOKEN_WHILE);
|
||||
put_TokenMap(tokenMap, "do", TOKEN_DO);
|
||||
put_TokenMap(tokenMap, "exit", TOKEN_EXIT);
|
||||
put_TokenMap(tokenMap, "switch", TOKEN_SWITCH);
|
||||
put_TokenMap(tokenMap, "return", TOKEN_RETURN);
|
||||
put_TokenMap(tokenMap, "const", TOKEN_CONST);
|
||||
put_TokenMap(tokenMap, "type", TOKEN_TYPE);
|
||||
put_TokenMap(tokenMap, "this", TOKEN_THIS);
|
||||
put_TokenMap(tokenMap, "yield", TOKEN_YIELD);
|
||||
put_TokenMap(tokenMap, "case", TOKEN_CASE);
|
||||
put_TokenMap(tokenMap, "assert", TOKEN_ASSERT);
|
||||
put_TokenMap(tokenMap, "break", TOKEN_BREAK);
|
||||
put_TokenMap(tokenMap, "let", TOKEN_LET);
|
||||
put_TokenMap(tokenMap, "print", TOKEN_PRINT);
|
||||
put_TokenMap(tokenMap, "nil", TOKEN_NULL);
|
||||
put_TokenMap(tokenMap, "and", TOKEN_AND);
|
||||
put_TokenMap(tokenMap, "or", TOKEN_OR);
|
||||
put_TokenMap(tokenMap, "xor", TOKEN_XOR);
|
||||
put_TokenMap(tokenMap, "mod", TOKEN_MOD);
|
||||
put_TokenMap(tokenMap, "eq", TOKEN_EQ);
|
||||
put_TokenMap(tokenMap, "ge", TOKEN_GE);
|
||||
put_TokenMap(tokenMap, "lt", TOKEN_LT);
|
||||
put_TokenMap(tokenMap, "le", TOKEN_LE);
|
||||
put_TokenMap(tokenMap, "ne", TOKEN_NE);
|
||||
put_TokenMap(tokenMap, "gt", TOKEN_GT);
|
||||
put_TokenMap(tokenMap, "ge", TOKEN_GE);
|
||||
put_TokenMap(tokenMap, "srl", TOKEN_SHIFTRIGHT);
|
||||
put_TokenMap(tokenMap, "sll", TOKEN_SHIFTLEFT);
|
||||
put_TokenMap(tokenMap, "toS", TOKEN_TO_S);
|
||||
}
|
||||
|
||||
typedef struct Tokenizer Tokenizer;
|
||||
struct Tokenizer {
|
||||
char *start;
|
||||
char *current;
|
||||
int32_t line;
|
||||
};
|
||||
|
||||
Tokenizer tokenizer;
|
||||
|
||||
void initTokenizer(char *src) {
|
||||
tokenizer.start = src;
|
||||
tokenizer.current = src;
|
||||
tokenizer.line = 1;
|
||||
}
|
||||
|
||||
static bool isAlpha(char c) {
|
||||
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' ||
|
||||
c == '\'' || c == '?';
|
||||
}
|
||||
|
||||
static bool isDigit(char c) { return (c >= '0' && c <= '9') || c == '-'; }
|
||||
|
||||
static bool isAtEnd() { return *tokenizer.current == '\0'; }
|
||||
|
||||
static Token makeToken(TokenType type) {
|
||||
Token token;
|
||||
token.type = type;
|
||||
token.start = tokenizer.start;
|
||||
token.length = (int32_t)(tokenizer.current - tokenizer.start);
|
||||
token.line = tokenizer.line;
|
||||
return token;
|
||||
}
|
||||
|
||||
static Token errorToken(char *msg) {
|
||||
Token token;
|
||||
token.type = TOKEN_ERROR;
|
||||
token.start = msg;
|
||||
token.length = (int32_t)strlen(msg);
|
||||
token.line = tokenizer.line;
|
||||
return token;
|
||||
}
|
||||
|
||||
static char advance() {
|
||||
tokenizer.current++;
|
||||
return tokenizer.current[-1];
|
||||
}
|
||||
|
||||
static char peek() { return *tokenizer.current; }
|
||||
|
||||
static char peekNext() {
|
||||
if (isAtEnd())
|
||||
return '\0';
|
||||
return tokenizer.current[1];
|
||||
}
|
||||
|
||||
static void skipWhitespace() {
|
||||
for (;;) {
|
||||
char c = peek();
|
||||
switch (c) {
|
||||
case ' ':
|
||||
case '\r':
|
||||
case '\t':
|
||||
advance();
|
||||
break;
|
||||
case '\n':
|
||||
tokenizer.line++;
|
||||
advance();
|
||||
break;
|
||||
case '!':
|
||||
while (peek() != '\n' && !isAtEnd())
|
||||
advance();
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static char *currentTokenToS() {
|
||||
int32_t size = tokenizer.current - tokenizer.start;
|
||||
char *str = (char *)malloc(sizeof(size));
|
||||
strncpy(str, tokenizer.start, size);
|
||||
str[size] = '\0';
|
||||
return str;
|
||||
}
|
||||
|
||||
TokenType getToken(char *s) {
|
||||
TokenMap *np;
|
||||
for (np = tokenMap[hash_TokenMap(s)]; np != NULL; np = np->next)
|
||||
if (strcmp(s, np->keyword) == 0)
|
||||
return np->token;
|
||||
return TOKEN_IDENTIFIER;
|
||||
}
|
||||
|
||||
static TokenType identifierType() {
|
||||
char *check = currentTokenToS();
|
||||
TokenType t = getToken(check);
|
||||
free(check);
|
||||
return t;
|
||||
}
|
||||
|
||||
static Token identifier() {
|
||||
while (isAlpha(peek()) || isDigit(peek()))
|
||||
advance();
|
||||
return makeToken(identifierType());
|
||||
}
|
||||
|
||||
static Token number() {
|
||||
bool is_float = false;
|
||||
while (isDigit(peek()))
|
||||
advance();
|
||||
|
||||
/* Look for a fractional part. */
|
||||
if (peek() == '.' && isDigit(peekNext())) {
|
||||
is_float = true;
|
||||
/* Consume the ".". */
|
||||
advance();
|
||||
|
||||
while (isDigit(peek()))
|
||||
advance();
|
||||
}
|
||||
|
||||
return makeToken((is_float)
|
||||
? TOKEN_FLOAT
|
||||
: TOKEN_INT); /* or measure if ends in postscript */
|
||||
}
|
||||
|
||||
static Token string() {
|
||||
while (peek() != '"' && !isAtEnd()) {
|
||||
if (peek() == '\n')
|
||||
tokenizer.line++;
|
||||
advance();
|
||||
}
|
||||
|
||||
if (isAtEnd())
|
||||
return errorToken("Unterminated string.");
|
||||
|
||||
/* The closing quote. */
|
||||
advance();
|
||||
return makeToken(TOKEN_STRING);
|
||||
}
|
||||
|
||||
Token nextToken() {
|
||||
skipWhitespace();
|
||||
tokenizer.start = tokenizer.current;
|
||||
if (isAtEnd())
|
||||
return makeToken(TOKEN_EOF);
|
||||
|
||||
char c = advance();
|
||||
if (isAlpha(c))
|
||||
return identifier();
|
||||
if (isDigit(c))
|
||||
return number();
|
||||
switch (c) {
|
||||
case '(':
|
||||
return makeToken(TOKEN_LEFT_PAREN);
|
||||
case ')':
|
||||
return makeToken(TOKEN_RIGHT_PAREN);
|
||||
case '{':
|
||||
return makeToken(TOKEN_LEFT_BRACE);
|
||||
case '}':
|
||||
return makeToken(TOKEN_RIGHT_BRACE);
|
||||
case '+':
|
||||
return makeToken(TOKEN_ADD);
|
||||
case '/':
|
||||
return makeToken(TOKEN_DIV);
|
||||
case '-':
|
||||
return makeToken(TOKEN_SUB);
|
||||
case '*':
|
||||
return makeToken(TOKEN_MUL);
|
||||
case ';':
|
||||
return makeToken(TOKEN_SEMICOLON);
|
||||
case '=':
|
||||
return makeToken(TOKEN_EQUALS);
|
||||
case '.':
|
||||
return makeToken(TOKEN_DOT);
|
||||
case '"':
|
||||
return string();
|
||||
}
|
||||
|
||||
return errorToken("Unexpected character.");
|
||||
}
|
||||
|
||||
|
||||
void printToken(Token t) {
|
||||
char *str = currentTokenToS();
|
||||
|
||||
switch (t.type) {
|
||||
PRINT_TOKEN_CASE(TOKEN_EQUALS)
|
||||
PRINT_TOKEN_CASE(TOKEN_DOT)
|
||||
PRINT_TOKEN_CASE(TOKEN_LEFT_PAREN)
|
||||
PRINT_TOKEN_CASE(TOKEN_RIGHT_PAREN)
|
||||
PRINT_TOKEN_CASE(TOKEN_LEFT_BRACE)
|
||||
PRINT_TOKEN_CASE(TOKEN_RIGHT_BRACE)
|
||||
PRINT_TOKEN_CASE(TOKEN_SEMICOLON)
|
||||
PRINT_TOKEN_CASE(TOKEN_IDENTIFIER)
|
||||
PRINT_TOKEN_CASE(TOKEN_STRING)
|
||||
PRINT_TOKEN_CASE(TOKEN_FLOAT)
|
||||
PRINT_TOKEN_CASE(TOKEN_U8)
|
||||
PRINT_TOKEN_CASE(TOKEN_I8)
|
||||
PRINT_TOKEN_CASE(TOKEN_U16)
|
||||
PRINT_TOKEN_CASE(TOKEN_I16)
|
||||
PRINT_TOKEN_CASE(TOKEN_U64)
|
||||
PRINT_TOKEN_CASE(TOKEN_I64)
|
||||
PRINT_TOKEN_CASE(TOKEN_INT)
|
||||
PRINT_TOKEN_CASE(TOKEN_UINT)
|
||||
/* PRINT_TOKEN_CASE(TOKEN_ARRAY) */
|
||||
/* PRINT_TOKEN_CASE(TOKEN_MAP) */
|
||||
PRINT_TOKEN_CASE(TOKEN_FALSE)
|
||||
PRINT_TOKEN_CASE(TOKEN_TRUE)
|
||||
PRINT_TOKEN_CASE(TOKEN_NULL)
|
||||
PRINT_TOKEN_CASE(TOKEN_EOF)
|
||||
PRINT_TOKEN_CASE(TOKEN_ERROR)
|
||||
PRINT_TOKEN_CASE(TOKEN_ADD)
|
||||
PRINT_TOKEN_CASE(TOKEN_SUB)
|
||||
PRINT_TOKEN_CASE(TOKEN_MUL)
|
||||
PRINT_TOKEN_CASE(TOKEN_DIV)
|
||||
PRINT_TOKEN_CASE(TOKEN_MOD)
|
||||
PRINT_TOKEN_CASE(TOKEN_GT)
|
||||
PRINT_TOKEN_CASE(TOKEN_LT)
|
||||
PRINT_TOKEN_CASE(TOKEN_EQ)
|
||||
PRINT_TOKEN_CASE(TOKEN_GE)
|
||||
PRINT_TOKEN_CASE(TOKEN_LE)
|
||||
PRINT_TOKEN_CASE(TOKEN_NE)
|
||||
PRINT_TOKEN_CASE(TOKEN_AND)
|
||||
PRINT_TOKEN_CASE(TOKEN_OR)
|
||||
PRINT_TOKEN_CASE(TOKEN_XOR)
|
||||
PRINT_TOKEN_CASE(TOKEN_SHIFTRIGHT)
|
||||
PRINT_TOKEN_CASE(TOKEN_SHIFTLEFT)
|
||||
PRINT_TOKEN_CASE(TOKEN_FN)
|
||||
PRINT_TOKEN_CASE(TOKEN_TO)
|
||||
PRINT_TOKEN_CASE(TOKEN_IN)
|
||||
PRINT_TOKEN_CASE(TOKEN_IS)
|
||||
PRINT_TOKEN_CASE(TOKEN_AS)
|
||||
PRINT_TOKEN_CASE(TOKEN_USE)
|
||||
PRINT_TOKEN_CASE(TOKEN_IF)
|
||||
PRINT_TOKEN_CASE(TOKEN_ELSE)
|
||||
PRINT_TOKEN_CASE(TOKEN_DEFAULT)
|
||||
PRINT_TOKEN_CASE(TOKEN_FOR)
|
||||
PRINT_TOKEN_CASE(TOKEN_TRY)
|
||||
PRINT_TOKEN_CASE(TOKEN_CATCH)
|
||||
PRINT_TOKEN_CASE(TOKEN_WHILE)
|
||||
PRINT_TOKEN_CASE(TOKEN_DO)
|
||||
PRINT_TOKEN_CASE(TOKEN_EXIT)
|
||||
PRINT_TOKEN_CASE(TOKEN_SWITCH)
|
||||
PRINT_TOKEN_CASE(TOKEN_RETURN)
|
||||
PRINT_TOKEN_CASE(TOKEN_CONST)
|
||||
PRINT_TOKEN_CASE(TOKEN_TYPE)
|
||||
PRINT_TOKEN_CASE(TOKEN_THIS)
|
||||
PRINT_TOKEN_CASE(TOKEN_YIELD)
|
||||
PRINT_TOKEN_CASE(TOKEN_CASE)
|
||||
PRINT_TOKEN_CASE(TOKEN_ASSERT)
|
||||
PRINT_TOKEN_CASE(TOKEN_BREAK)
|
||||
PRINT_TOKEN_CASE(TOKEN_LET)
|
||||
PRINT_TOKEN_CASE(TOKEN_PRINT)
|
||||
PRINT_TOKEN_CASE(TOKEN_TO_S)
|
||||
}
|
||||
free(str);
|
||||
}
|
118
src/parser.h
118
src/parser.h
|
@ -1,118 +0,0 @@
|
|||
#ifndef ZRE_PARSER_H
|
||||
#define ZRE_PARSER_H
|
||||
|
||||
#include "common.h"
|
||||
#include <string.h>
|
||||
|
||||
typedef enum TokenType
|
||||
{
|
||||
/* Single char tokens */
|
||||
TOKEN_LEFT_PAREN,
|
||||
TOKEN_RIGHT_PAREN,
|
||||
TOKEN_LEFT_BRACE,
|
||||
TOKEN_RIGHT_BRACE,
|
||||
TOKEN_SEMICOLON,
|
||||
TOKEN_EQUALS,
|
||||
TOKEN_DOT,
|
||||
/* Literals */
|
||||
TOKEN_IDENTIFIER,
|
||||
TOKEN_STRING,
|
||||
TOKEN_FLOAT,
|
||||
TOKEN_U8,
|
||||
TOKEN_I8,
|
||||
TOKEN_U16,
|
||||
TOKEN_I16,
|
||||
TOKEN_U64,
|
||||
TOKEN_I64,
|
||||
TOKEN_INT,
|
||||
TOKEN_UINT,
|
||||
/* TOKEN_ARRAY, */
|
||||
/* TOKEN_MAP, */
|
||||
TOKEN_FALSE,
|
||||
TOKEN_TRUE,
|
||||
TOKEN_NULL,
|
||||
TOKEN_EOF,
|
||||
TOKEN_ERROR,
|
||||
/* Operators */
|
||||
TOKEN_ADD,
|
||||
TOKEN_SUB,
|
||||
TOKEN_MUL,
|
||||
TOKEN_DIV,
|
||||
TOKEN_MOD,
|
||||
TOKEN_GT,
|
||||
TOKEN_LT,
|
||||
TOKEN_EQ,
|
||||
TOKEN_GE,
|
||||
TOKEN_LE,
|
||||
TOKEN_NE,
|
||||
TOKEN_AND,
|
||||
TOKEN_OR,
|
||||
TOKEN_XOR,
|
||||
TOKEN_SHIFTRIGHT,
|
||||
TOKEN_SHIFTLEFT,
|
||||
/* Keywords */
|
||||
TOKEN_FN,
|
||||
TOKEN_TO,
|
||||
TOKEN_IN,
|
||||
TOKEN_IS,
|
||||
TOKEN_AS,
|
||||
TOKEN_USE,
|
||||
TOKEN_IF,
|
||||
TOKEN_ELSE,
|
||||
TOKEN_DEFAULT,
|
||||
TOKEN_FOR,
|
||||
TOKEN_TRY,
|
||||
TOKEN_CATCH,
|
||||
TOKEN_WHILE,
|
||||
TOKEN_DO,
|
||||
TOKEN_EXIT,
|
||||
TOKEN_SWITCH,
|
||||
TOKEN_RETURN,
|
||||
TOKEN_CONST,
|
||||
TOKEN_TYPE,
|
||||
TOKEN_THIS,
|
||||
TOKEN_YIELD,
|
||||
TOKEN_CASE,
|
||||
TOKEN_ASSERT,
|
||||
TOKEN_BREAK,
|
||||
TOKEN_LET,
|
||||
TOKEN_PRINT,
|
||||
TOKEN_TO_S,
|
||||
} TokenType;
|
||||
|
||||
#define PRINT_TOKEN_CASE(token_suffix) \
|
||||
case token_suffix: \
|
||||
printf("" #token_suffix " %s line_no=%d\n", str, t.line); \
|
||||
break;
|
||||
|
||||
typedef struct Token Token;
|
||||
struct Token
|
||||
{
|
||||
TokenType type;
|
||||
char *start;
|
||||
int32_t length;
|
||||
int32_t line;
|
||||
};
|
||||
|
||||
typedef struct SourceCode SourceCode;
|
||||
struct SourceCode
|
||||
{
|
||||
size_t size;
|
||||
char *buf;
|
||||
int count;
|
||||
};
|
||||
|
||||
typedef struct TokenMap TokenMap;
|
||||
struct TokenMap
|
||||
{
|
||||
struct TokenMap* next;
|
||||
char* keyword;
|
||||
TokenType token;
|
||||
};
|
||||
|
||||
void initTokenMap();
|
||||
void initTokenizer (char *src);
|
||||
void printToken (Token t);
|
||||
Token nextToken();
|
||||
|
||||
#endif
|
|
@ -1,5 +1,4 @@
|
|||
#include "compiler.h"
|
||||
#include "parser.h"
|
||||
#include "test.h"
|
||||
|
||||
uint32_t test_add_compile(Value *memory) {
|
||||
uint32_t i = 0;
|
||||
|
@ -76,44 +75,32 @@ uint32_t test_add_function_compile(Value *memory) {
|
|||
}
|
||||
|
||||
uint32_t test_recursive_function_compile(Value *memory) {
|
||||
uint32_t i = 0;
|
||||
uint32_t i = 3;
|
||||
memory[i++].u = OP(OP_POPU, 0, 0, 0); /* return ptr */
|
||||
memory[i++].u = OP(OP_POPI, 1, 0, 0); /* n int */
|
||||
/* if (n < 2) */
|
||||
/* return n; */
|
||||
memory[i++].u = OP(OP_POPI, 2, 0, 0); /* fib(n - 2) */
|
||||
memory[i++].u = OP(OP_POPI, 3, 0, 0); /* fib(n - 1) */
|
||||
memory[i++].u = OP(OP_ADD_INT, 4, 3, 2); /* add */
|
||||
memory[i++].u = OP(OP_PUSHI, 4, 0, 0); /* return */
|
||||
memory[i++].u = OP(OP_RETURN, 0, 0, 0);
|
||||
uint32_t main = i;
|
||||
memory[0].u = OP(OP_LOADF, 0, 0, 0);
|
||||
memory[1].u = main;
|
||||
memory[2].u = OP(OP_JMP, 0, 0, 0); /* jump to 'main' */
|
||||
memory[i++].u = OP(OP_LOADI, 0, 0, 0); /* 35 */
|
||||
memory[i++].i = 35;
|
||||
memory[i++].u = OP(OP_PUSHI, 0, 0, 0);
|
||||
uint32_t add_fn_return = i + 6; /* after the call */
|
||||
memory[i++].u = OP(OP_LOADI, 0, 0, 0); /* return */
|
||||
memory[i++].u = add_fn_return;
|
||||
memory[i++].u = OP(OP_PUSHU, 0, 0, 0);
|
||||
memory[i++].u = OP(OP_LOADU, 0, 0, 0); /* add fn ptr */
|
||||
memory[i++].u = 3;
|
||||
memory[i++].u = OP(OP_CALL, 0, 0, 0); /* ); */
|
||||
memory[i++].u = OP(OP_POPI, 0, 0, 0); /* get return value */
|
||||
memory[i++].u = OP(OP_INT_TO_STRING, 1, 0, 0);
|
||||
memory[i++].u = OP(OP_HALT, 0, 0, 0);
|
||||
return i;
|
||||
}
|
||||
|
||||
static void letDeclaration() {
|
||||
/* uint8_t global = parseVariable("Expect variable name."); */
|
||||
|
||||
/* if (match(TOKEN_EQUAL)) { */
|
||||
/* expression(); */
|
||||
/* } else { */
|
||||
/* emitByte(OP_NIL); */
|
||||
/* } */
|
||||
/* consume(TOKEN_SEMICOLON, */
|
||||
/* "Expect ';' after variable declaration."); */
|
||||
|
||||
/* defineVariable(global); */
|
||||
}
|
||||
|
||||
static void declaration(Token t) {
|
||||
if (t.type == TOKEN_LET) {
|
||||
letDeclaration();
|
||||
} else {
|
||||
/* statement(); */
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile.
|
||||
*/
|
||||
uint32_t compile(Value *memory, char *buffer) {
|
||||
uint32_t i = 0;
|
||||
initTokenizer(buffer);
|
||||
Token t = nextToken();
|
||||
while (t.type != TOKEN_EOF) {
|
||||
printToken(t);
|
||||
declaration(t);
|
||||
t = nextToken();
|
||||
}
|
||||
return i;
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
#ifndef ZRE_COMPILER_H
|
||||
#define ZRE_COMPILER_H
|
||||
#ifndef ZRE_TEST_H
|
||||
#define ZRE_TEST_H
|
||||
|
||||
#include "opcodes.h"
|
||||
|
||||
|
@ -7,6 +7,5 @@ uint32_t test_add_compile (Value *memory);
|
|||
uint32_t test_loop_compile (Value *memory);
|
||||
uint32_t test_add_function_compile(Value *memory);
|
||||
uint32_t test_recursive_function_compile(Value *memory);
|
||||
uint32_t compile (Value* memory, char *buffer);
|
||||
|
||||
#endif
|
3
src/vm.c
3
src/vm.c
|
@ -1,5 +1,6 @@
|
|||
#include "vm.h"
|
||||
#include "debug.h"
|
||||
#include <string.h>
|
||||
|
||||
#define COMPARE_AND_JUMP(type, accessor, op) \
|
||||
do { \
|
||||
|
@ -258,7 +259,7 @@ bool step_vm(VM *vm) {
|
|||
}
|
||||
vm->memory[str_dest].u = length;
|
||||
vm->frames[vm->fp].allocated.end +=
|
||||
length + 1; /* increment to end of allocated */
|
||||
((length / 4) + (length % 4) + 1); /* increment to end of allocated */
|
||||
return true;
|
||||
}
|
||||
case OP_PRINT_STRING: {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
fn add(int a, int b) int {
|
||||
int add(int a, int b) {
|
||||
return a + b;
|
||||
}
|
||||
|
||||
let sum = add(1, 1);
|
||||
int sum = add(1, 1);
|
||||
print(sum.toS());
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
main:
|
||||
loadi $0 1 ;load 1 into r0
|
||||
pushi $0 ;push onto stack
|
||||
loadi $0 1 ;1
|
||||
pushi $0
|
||||
call &add ; call memory location for tag "add"
|
||||
popi $0 ;get value from function call "add"
|
||||
itos $1 $0 ;convert int to string
|
||||
puts $1 ;print string to stdout
|
||||
halt
|
||||
|
||||
add:
|
||||
popu $0 ; pop unsigned int
|
||||
popi $1 ; int a
|
||||
popi $2 ; int b
|
||||
addi $3 $2 $1 ; a + b
|
||||
pushi $3 ; push a + b onto stack for return
|
||||
return $0 ; actually do the return
|
|
@ -1,2 +1,2 @@
|
|||
let sum = 1 + 2;
|
||||
int sum = 1 + 2;
|
||||
print(sum.toS());
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
fn fib(int n) {
|
||||
if (n < 2) return n;
|
||||
int fib(int n) {
|
||||
if (n < 2) {
|
||||
return n;
|
||||
}
|
||||
return fib(n - 2) + fib(n - 1);
|
||||
}
|
||||
|
||||
print fib(35);
|
||||
print(fib(35).toS());
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
let a = 5.0;
|
||||
do (i = 5, 0, -1) {
|
||||
real a = 5.0;
|
||||
do (int i = 5, 0, -1) {
|
||||
a += 5.0;
|
||||
}
|
||||
let b = a as nat;
|
||||
let user_string = gets();
|
||||
nat b = a as nat;
|
||||
str user_string = readln();
|
||||
print(a.toS());
|
||||
print(b.toS());
|
||||
print(user_string);
|
||||
|
|
Loading…
Reference in New Issue