Reorganize, add tools for parser
This commit is contained in:
parent
922959191d
commit
df9d19207c
58
Makefile
58
Makefile
|
@ -21,7 +21,7 @@ BASE_CFLAGS := -I$(SRC_DIR) -Wall -Wextra -Werror -pedantic
|
||||||
CORE_CFLAGS := $(BASE_CFLAGS) -std=c89 -ffreestanding -nostdlib -fno-builtin
|
CORE_CFLAGS := $(BASE_CFLAGS) -std=c89 -ffreestanding -nostdlib -fno-builtin
|
||||||
|
|
||||||
# --- PLATFORM-SPECIFIC FLAGS ---
|
# --- PLATFORM-SPECIFIC FLAGS ---
|
||||||
PLATFORM_CFLAGS := $(BASE_CFLAGS)
|
PLATFORM_CFLAGS := $(BASE_CFLAGS) -std=c99
|
||||||
|
|
||||||
# --- MODE & PLATFORM SPECIFIC FLAGS ---
|
# --- MODE & PLATFORM SPECIFIC FLAGS ---
|
||||||
ifeq ($(BUILD_MODE), deploy)
|
ifeq ($(BUILD_MODE), deploy)
|
||||||
|
@ -51,8 +51,8 @@ ifeq ($(PLATFORM), emscripten)
|
||||||
|
|
||||||
# For deploy: optimize, strip debug, minimize size
|
# For deploy: optimize, strip debug, minimize size
|
||||||
ifeq ($(BUILD_MODE), deploy)
|
ifeq ($(BUILD_MODE), deploy)
|
||||||
PLATFORM_CFLAGS += -O3
|
PLATFORM_CFLAGS += -O2
|
||||||
LDFLAGS += -O3 --closure 1
|
LDFLAGS += -O2 --closure 1
|
||||||
else
|
else
|
||||||
# For debug: preserve names, generate source maps
|
# For debug: preserve names, generate source maps
|
||||||
PLATFORM_CFLAGS += -gsource-map
|
PLATFORM_CFLAGS += -gsource-map
|
||||||
|
@ -68,23 +68,28 @@ ifndef TARGET
|
||||||
TARGET = $(BUILD_DIR)/zre-$(PLATFORM)$(TARGET_SUFFIX)
|
TARGET = $(BUILD_DIR)/zre-$(PLATFORM)$(TARGET_SUFFIX)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# --- CORE SOURCES (flat in src/) ---
|
# --- VM CORE SOURCES ---
|
||||||
CORE_SOURCES := \
|
VM_SOURCES := \
|
||||||
$(SRC_DIR)/str.c \
|
$(SRC_DIR)/vm/vm.c \
|
||||||
$(SRC_DIR)/vm.c \
|
$(SRC_DIR)/vm/device.c \
|
||||||
$(SRC_DIR)/device.c \
|
$(SRC_DIR)/vm/str.c
|
||||||
$(SRC_DIR)/test.c
|
|
||||||
|
|
||||||
# --- PLATFORM SOURCE ---
|
ifeq ($(BUILD_MODE), deploy)
|
||||||
PLATFORM_SOURCE := $(ARCH_DIR)/main.c \
|
PLATFORM_SOURCE := $(ARCH_DIR)/main.c \
|
||||||
$(ARCH_DIR)/devices.c
|
$(ARCH_DIR)/devices.c
|
||||||
|
else
|
||||||
|
PLATFORM_SOURCE := $(ARCH_DIR)/main.c \
|
||||||
|
$(ARCH_DIR)/devices.c \
|
||||||
|
$(SRC_DIR)/tools/test.c \
|
||||||
|
$(SRC_DIR)/tools/parser.c
|
||||||
|
endif
|
||||||
|
|
||||||
# --- OBJECT FILES ---
|
# --- OBJECT FILES ---
|
||||||
CORE_OBJS := $(CORE_SOURCES:$(SRC_DIR)/%.c=$(BUILD_DIR)/%.o)
|
VM_OBJS := $(VM_SOURCES:$(SRC_DIR)/%.c=$(BUILD_DIR)/%.o)
|
||||||
PLATFORM_OBJ := $(PLATFORM_SOURCE:$(SRC_DIR)/%.c=$(BUILD_DIR)/%.o)
|
PLATFORM_OBJ := $(PLATFORM_SOURCE:$(SRC_DIR)/%.c=$(BUILD_DIR)/%.o)
|
||||||
|
|
||||||
# --- DEPENDENCIES ---
|
# --- DEPENDENCIES ---
|
||||||
DEPS := $(CORE_OBJS:.o=.d) $(PLATFORM_OBJ:.o=.d)
|
DEPS := $(VM_OBJS:.o=.d) $(PLATFORM_OBJ:.o=.d)
|
||||||
|
|
||||||
.PHONY: all debug deploy clean clean-all help
|
.PHONY: all debug deploy clean clean-all help
|
||||||
|
|
||||||
|
@ -99,8 +104,23 @@ debug: $(TARGET)
|
||||||
deploy: BUILD_MODE = deploy
|
deploy: BUILD_MODE = deploy
|
||||||
deploy: $(TARGET)
|
deploy: $(TARGET)
|
||||||
|
|
||||||
|
# --- COMPILE VM CORE (freestanding) ---
|
||||||
|
$(BUILD_DIR)/vm/%.o: $(SRC_DIR)/vm/%.c
|
||||||
|
@mkdir -p $(dir $@)
|
||||||
|
$(CC) $(CORE_CFLAGS) -MMD -MP -c $< -o $@
|
||||||
|
|
||||||
|
# --- COMPILE TOOLS (debug only, uses PLATFORM_CFLAGS) ---
|
||||||
|
$(BUILD_DIR)/tools/%.o: $(SRC_DIR)/tools/%.c
|
||||||
|
@mkdir -p $(dir $@)
|
||||||
|
$(CC) $(PLATFORM_CFLAGS) -MMD -MP -c $< -o $@
|
||||||
|
|
||||||
|
# --- COMPILE PLATFORM ---
|
||||||
|
$(BUILD_DIR)/arch/$(PLATFORM)/%.o: $(ARCH_DIR)/%.c
|
||||||
|
@mkdir -p $(dir $@)
|
||||||
|
$(CC) $(PLATFORM_CFLAGS) -MMD -MP -c $< -o $@
|
||||||
|
|
||||||
# Main build rule
|
# Main build rule
|
||||||
$(TARGET): $(CORE_OBJS) $(PLATFORM_OBJ)
|
$(TARGET): $(VM_OBJS) $(PLATFORM_OBJ)
|
||||||
@mkdir -p $(dir $@)
|
@mkdir -p $(dir $@)
|
||||||
$(CC) $(PLATFORM_CFLAGS) $(LDFLAGS) -o $@ $^
|
$(CC) $(PLATFORM_CFLAGS) $(LDFLAGS) -o $@ $^
|
||||||
@echo "Built: $@"
|
@echo "Built: $@"
|
||||||
|
@ -108,16 +128,6 @@ $(TARGET): $(CORE_OBJS) $(PLATFORM_OBJ)
|
||||||
echo "Open in browser: file://$(shell pwd)/$@"; \
|
echo "Open in browser: file://$(shell pwd)/$@"; \
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# --- COMPILE CORE (freestanding) ---
|
|
||||||
$(BUILD_DIR)/%.o: $(SRC_DIR)/%.c
|
|
||||||
@mkdir -p $(dir $@)
|
|
||||||
$(CC) $(CORE_CFLAGS) -MMD -MP -c $< -o $@
|
|
||||||
|
|
||||||
# --- COMPILE PLATFORM ---
|
|
||||||
$(BUILD_DIR)/arch/$(PLATFORM)/%.o: $(ARCH_DIR)/%.c
|
|
||||||
@mkdir -p $(dir $@)
|
|
||||||
$(CC) $(PLATFORM_CFLAGS) -MMD -MP -c $< -o $@
|
|
||||||
|
|
||||||
# --- AUTO-DEPENDENCIES ---
|
# --- AUTO-DEPENDENCIES ---
|
||||||
-include $(DEPS)
|
-include $(DEPS)
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#include "../../device.h"
|
#include "../../vm/device.h"
|
||||||
#include "../../vm.h"
|
#include "../../vm/vm.h"
|
||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
|
|
||||||
/* Screen device data */
|
/* Screen device data */
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "../../test.h"
|
#include "../../tools/test.h"
|
||||||
#include "../../vm.h"
|
#include "../../tools/parser.h"
|
||||||
|
#include "../../vm/vm.h"
|
||||||
#include "devices.h"
|
#include "devices.h"
|
||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
|
|
||||||
|
@ -12,19 +13,19 @@ static DeviceOps screen_ops = {.open = screen_open,
|
||||||
.read = screen_read,
|
.read = screen_read,
|
||||||
.write = screen_write,
|
.write = screen_write,
|
||||||
.close = screen_close,
|
.close = screen_close,
|
||||||
.ioctl = NULL};
|
.ioctl = nil};
|
||||||
|
|
||||||
static DeviceOps mouse_ops = {.open = mouse_open,
|
static DeviceOps mouse_ops = {.open = mouse_open,
|
||||||
.read = mouse_read,
|
.read = mouse_read,
|
||||||
.write = mouse_write,
|
.write = mouse_write,
|
||||||
.close = mouse_close,
|
.close = mouse_close,
|
||||||
.ioctl = NULL};
|
.ioctl = nil};
|
||||||
|
|
||||||
static DeviceOps keyboard_ops = {.open = keyboard_open,
|
static DeviceOps keyboard_ops = {.open = keyboard_open,
|
||||||
.read = keyboard_read,
|
.read = keyboard_read,
|
||||||
.write = keyboard_write,
|
.write = keyboard_write,
|
||||||
.close = keyboard_close,
|
.close = keyboard_close,
|
||||||
.ioctl = NULL};
|
.ioctl = nil};
|
||||||
|
|
||||||
static DeviceOps console_device_ops = {
|
static DeviceOps console_device_ops = {
|
||||||
.open = console_open,
|
.open = console_open,
|
||||||
|
@ -62,6 +63,28 @@ void compileFile(const char *path, VM *vm) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void repl(VM *vm) {
|
void repl(VM *vm) {
|
||||||
|
USED(vm);
|
||||||
|
|
||||||
|
const char *source = "(fn main ()\n"
|
||||||
|
" (print (ftos (addf 1.0 2.0))))\n"
|
||||||
|
"\n"
|
||||||
|
"(device Terminal \"/dev/term/0\"\n"
|
||||||
|
" (write buffer size)\n"
|
||||||
|
" (read buffer size))";
|
||||||
|
|
||||||
|
printf("Parsing:\n%s\n\n", source);
|
||||||
|
|
||||||
|
ExprNode *ast = expr_parse(source, strlen(source));
|
||||||
|
if (!ast) {
|
||||||
|
printf("Parse failed.\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("AST:\n");
|
||||||
|
expr_print(ast, 0);
|
||||||
|
|
||||||
|
expr_free(ast);
|
||||||
|
|
||||||
char line[1024];
|
char line[1024];
|
||||||
for (;;) {
|
for (;;) {
|
||||||
printf("> ");
|
printf("> ");
|
||||||
|
@ -70,25 +93,26 @@ void repl(VM *vm) {
|
||||||
printf("\n");
|
printf("\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* reset the code counter to 0 */
|
|
||||||
vm->cp = 0;
|
|
||||||
vm->sp = 0;
|
|
||||||
vm->pc = 0;
|
|
||||||
vm->mp = 0;
|
|
||||||
|
|
||||||
/* assemble(line, vm); */
|
ExprNode *ast = expr_parse(source, strlen(line));
|
||||||
while (step_vm(vm))
|
if (!ast) {
|
||||||
;
|
printf("Parse failed.\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("AST:\n");
|
||||||
|
expr_print(ast, 0);
|
||||||
|
|
||||||
|
expr_free(ast);
|
||||||
}
|
}
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
enum FlagType {
|
enum FlagType {
|
||||||
FLAG_NONE = 0,
|
FLAG_NONE = 0,
|
||||||
FLAG_DEV_MODE = 1,
|
FLAG_TEST_MODE = 1,
|
||||||
FLAG_TEST_MODE = 2,
|
FLAG_DUMP_ROM = 2,
|
||||||
FLAG_DUMP_ROM = 4,
|
FLAG_GUI_MODE = 4,
|
||||||
FLAG_GUI_MODE = 8,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MAX_INPUT_FILES 16 /* Adjust based on your system's constraints */
|
#define MAX_INPUT_FILES 16 /* Adjust based on your system's constraints */
|
||||||
|
@ -114,9 +138,7 @@ i32 parse_arguments(i32 argc, char *argv[], struct CompilerConfig *config) {
|
||||||
for (i = 1; i < argc; i++) {
|
for (i = 1; i < argc; i++) {
|
||||||
if (argv[i][0] == '-') {
|
if (argv[i][0] == '-') {
|
||||||
/* Long and short flag handling */
|
/* Long and short flag handling */
|
||||||
if (strcmp(argv[i], "-d") == 0 || strcmp(argv[i], "--dev") == 0) {
|
if (strcmp(argv[i], "-g") == 0 || strcmp(argv[i], "--gui") == 0) {
|
||||||
config->flags |= FLAG_DEV_MODE;
|
|
||||||
} else if (strcmp(argv[i], "-g") == 0 || strcmp(argv[i], "--gui") == 0) {
|
|
||||||
config->flags |= FLAG_GUI_MODE;
|
config->flags |= FLAG_GUI_MODE;
|
||||||
} else if (strcmp(argv[i], "-t") == 0 || strcmp(argv[i], "--test") == 0) {
|
} else if (strcmp(argv[i], "-t") == 0 || strcmp(argv[i], "--test") == 0) {
|
||||||
config->flags |= FLAG_TEST_MODE;
|
config->flags |= FLAG_TEST_MODE;
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
gcc math_gen.c -o math_gen -lm
|
gcc math_gen.c -o math_gen -lm
|
||||||
./math_gen > ../math.h
|
./math_gen > ./math.h
|
|
@ -0,0 +1,194 @@
|
||||||
|
#include "parser.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
// Helper function to allocate memory and handle errors
|
||||||
|
static void *safe_malloc(size_t size) {
|
||||||
|
void *ptr = malloc(size);
|
||||||
|
if (!ptr) {
|
||||||
|
fprintf(stderr, "Memory allocation failed\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper function to create a new node
|
||||||
|
static ExprNode *expr_node_create(const char *token, int line) {
|
||||||
|
ExprNode *node = (ExprNode *)safe_malloc(sizeof(ExprNode));
|
||||||
|
node->token = strdup(token ? token : "");
|
||||||
|
node->children = NULL;
|
||||||
|
node->child_count = 0;
|
||||||
|
node->line = line;
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Forward declaration
|
||||||
|
static ExprNode *parse_expression(const char **ptr, int line);
|
||||||
|
|
||||||
|
// Skip whitespace characters
|
||||||
|
static const char *skip_whitespace(const char *ptr) {
|
||||||
|
while (*ptr && isspace(*ptr)) {
|
||||||
|
ptr++;
|
||||||
|
}
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse a token (atom)
|
||||||
|
static char *parse_token(const char **ptr) {
|
||||||
|
const char *start = *ptr;
|
||||||
|
|
||||||
|
// Skip leading whitespace
|
||||||
|
start = skip_whitespace(start);
|
||||||
|
if (!*start) return NULL;
|
||||||
|
|
||||||
|
const char *end = start;
|
||||||
|
|
||||||
|
// Handle parentheses specially
|
||||||
|
if (*end == '(' || *end == ')') {
|
||||||
|
end++;
|
||||||
|
} else {
|
||||||
|
// Read until whitespace or parentheses
|
||||||
|
while (*end && !isspace(*end) && *end != '(' && *end != ')') {
|
||||||
|
end++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (end == start) return NULL;
|
||||||
|
|
||||||
|
size_t len = end - start;
|
||||||
|
char *token = (char *)safe_malloc(len + 1);
|
||||||
|
memcpy(token, start, len);
|
||||||
|
token[len] = '\0';
|
||||||
|
|
||||||
|
*ptr = end;
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse a list (expression starting with '(')
|
||||||
|
static ExprNode *parse_list(const char **ptr, int line) {
|
||||||
|
// Skip the opening parenthesis
|
||||||
|
(*ptr)++;
|
||||||
|
|
||||||
|
// Parse the operator (first token)
|
||||||
|
*ptr = skip_whitespace(*ptr);
|
||||||
|
if (**ptr == ')') {
|
||||||
|
// Empty list
|
||||||
|
(*ptr)++;
|
||||||
|
return expr_node_create("nil", line);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse the operator/first element
|
||||||
|
char *op_token = parse_token(ptr);
|
||||||
|
if (!op_token) {
|
||||||
|
fprintf(stderr, "Error: Expected operator at line %d\n", line);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExprNode *node = expr_node_create(op_token, line);
|
||||||
|
free(op_token);
|
||||||
|
|
||||||
|
// Parse children
|
||||||
|
while (**ptr && **ptr != ')') {
|
||||||
|
*ptr = skip_whitespace(*ptr);
|
||||||
|
if (**ptr == ')') break;
|
||||||
|
|
||||||
|
ExprNode *child = parse_expression(ptr, line);
|
||||||
|
if (child) {
|
||||||
|
// Resize children array properly
|
||||||
|
ExprNode **new_children = (ExprNode **)safe_malloc(sizeof(ExprNode *) * (node->child_count + 1));
|
||||||
|
|
||||||
|
// Copy existing children
|
||||||
|
for (size_t i = 0; i < node->child_count; i++) {
|
||||||
|
new_children[i] = node->children[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add new child
|
||||||
|
new_children[node->child_count] = child;
|
||||||
|
|
||||||
|
// Free old array and update
|
||||||
|
free(node->children);
|
||||||
|
node->children = new_children;
|
||||||
|
node->child_count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
*ptr = skip_whitespace(*ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (**ptr == ')') {
|
||||||
|
(*ptr)++; // Skip closing parenthesis
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "Error: Missing closing parenthesis at line %d\n", line);
|
||||||
|
}
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse an expression (either atom or list)
|
||||||
|
static ExprNode *parse_expression(const char **ptr, int line) {
|
||||||
|
*ptr = skip_whitespace(*ptr);
|
||||||
|
|
||||||
|
if (!**ptr) return NULL;
|
||||||
|
|
||||||
|
if (**ptr == '(') {
|
||||||
|
return parse_list(ptr, line);
|
||||||
|
} else {
|
||||||
|
// Parse atom
|
||||||
|
char *token = parse_token(ptr);
|
||||||
|
if (token) {
|
||||||
|
ExprNode *node = expr_node_create(token, line);
|
||||||
|
free(token);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Main parsing function
|
||||||
|
ExprNode *expr_parse(const char *source, size_t source_len) {
|
||||||
|
if (!source || source_len == 0) return NULL;
|
||||||
|
|
||||||
|
const char *ptr = source;
|
||||||
|
int line = 1;
|
||||||
|
|
||||||
|
ptr = skip_whitespace(ptr);
|
||||||
|
if (!*ptr) return NULL;
|
||||||
|
|
||||||
|
return parse_expression(&ptr, line);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Free an Expr AST (and all children)
|
||||||
|
void expr_free(ExprNode *node) {
|
||||||
|
if (!node) return;
|
||||||
|
|
||||||
|
free(node->token);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < node->child_count; i++) {
|
||||||
|
expr_free(node->children[i]);
|
||||||
|
}
|
||||||
|
free(node->children);
|
||||||
|
free(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Debug: print AST (for dev)
|
||||||
|
void expr_print(ExprNode *node, int indent) {
|
||||||
|
if (!node) return;
|
||||||
|
|
||||||
|
for (int i = 0; i < indent; i++) {
|
||||||
|
printf(" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node->child_count == 0) {
|
||||||
|
// Atom
|
||||||
|
printf("Atom: '%s' (line %d)\n", node->token, node->line);
|
||||||
|
} else {
|
||||||
|
// List
|
||||||
|
printf("List: '%s' (line %d) [%zu children]\n",
|
||||||
|
node->token, node->line, node->child_count);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < node->child_count; i++) {
|
||||||
|
expr_print(node->children[i], indent + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
#ifndef PARSER_H
|
||||||
|
#define PARSER_H
|
||||||
|
|
||||||
|
#include <stddef.h> // for size_t
|
||||||
|
|
||||||
|
// Forward declare
|
||||||
|
typedef struct ExprNode ExprNode;
|
||||||
|
|
||||||
|
// Node type: atom or list
|
||||||
|
struct ExprNode {
|
||||||
|
char *token; // For atoms: the value ("123", "$0", "add")
|
||||||
|
// For lists: the operator (first token)
|
||||||
|
ExprNode **children; // Array of child nodes (NULL if atom)
|
||||||
|
size_t child_count; // 0 if atom
|
||||||
|
int line; // Source line number (for errors)
|
||||||
|
};
|
||||||
|
|
||||||
|
// Parse a string into an Expr AST
|
||||||
|
ExprNode *expr_parse(const char *source, size_t source_len);
|
||||||
|
|
||||||
|
// Free an Expr AST (and all children)
|
||||||
|
void expr_free(ExprNode *node);
|
||||||
|
|
||||||
|
// Debug: print AST (for dev)
|
||||||
|
void expr_print(ExprNode *node, int indent);
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,7 +1,7 @@
|
||||||
#include "test.h"
|
#include "test.h"
|
||||||
#include "opcodes.h"
|
#include "../vm/opcodes.h"
|
||||||
#include "str.h"
|
#include "../vm/vm.h"
|
||||||
#include "vm.h"
|
#include "string.h"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
u32 real_alloc(VM *vm, float v) {
|
u32 real_alloc(VM *vm, float v) {
|
||||||
|
@ -39,7 +39,7 @@ struct TestMapping internal_tests[] = {
|
||||||
bool compile_internal_test(const char *filename, VM *vm) {
|
bool compile_internal_test(const char *filename, VM *vm) {
|
||||||
i32 i;
|
i32 i;
|
||||||
for (i = 0; internal_tests[i].filename != NULL; i++) {
|
for (i = 0; internal_tests[i].filename != NULL; i++) {
|
||||||
if (streq(internal_tests[i].filename, filename)) {
|
if (strcmp(internal_tests[i].filename, filename) == 0) {
|
||||||
return internal_tests[i].test_func(vm);
|
return internal_tests[i].test_func(vm);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef ZRE_TEST_H
|
#ifndef ZRE_TEST_H
|
||||||
#define ZRE_TEST_H
|
#define ZRE_TEST_H
|
||||||
|
|
||||||
#include "opcodes.h"
|
#include "../vm/opcodes.h"
|
||||||
|
|
||||||
#define AS_FIXED(v) ((float)(i32)(v) / 65536.0f)
|
#define AS_FIXED(v) ((float)(i32)(v) / 65536.0f)
|
||||||
#define TO_FIXED(f) ((u32)((i32)( \
|
#define TO_FIXED(f) ((u32)((i32)( \
|
|
@ -25,7 +25,7 @@ bool streq(const char *s1, const char *s2) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
u32 strlen(const char *str) {
|
u32 strlength(const char *str) {
|
||||||
u32 i;
|
u32 i;
|
||||||
if (str == nil) {return 0;}
|
if (str == nil) {return 0;}
|
||||||
for (i = 0; str[i] != '\0'; i++) {
|
for (i = 0; str[i] != '\0'; i++) {
|
||||||
|
@ -34,7 +34,7 @@ u32 strlen(const char *str) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 strnlen(const char *str, u32 max_len) {
|
u32 strnlength(const char *str, u32 max_len) {
|
||||||
u32 i;
|
u32 i;
|
||||||
if (str == nil) {return 0;}
|
if (str == nil) {return 0;}
|
||||||
for (i = 0; i < max_len && str[i] != '\0'; i++) {
|
for (i = 0; i < max_len && str[i] != '\0'; i++) {
|
|
@ -3,10 +3,11 @@
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
i32 strcopy(char* to, const char *from, u32 length);
|
|
||||||
u32 strlen(const char* str);
|
|
||||||
bool streq(const char *s1, const char *s2);
|
bool streq(const char *s1, const char *s2);
|
||||||
char *write_digits_backwards(u32 value, char *buf_end, char *buf_start);
|
i32 strcopy(char* to, const char *from, u32 length);
|
||||||
|
u32 strlength(const char *str);
|
||||||
|
u32 strnlength(const char *str, u32 max_len);
|
||||||
|
void uint_to_string(u32 value, char *buffer);
|
||||||
void int_to_string(i32 value, char *buffer);
|
void int_to_string(i32 value, char *buffer);
|
||||||
void fixed_to_string(i32 value, char *buffer);
|
void fixed_to_string(i32 value, char *buffer);
|
||||||
|
|
|
@ -434,7 +434,7 @@ bool step_vm(VM *vm) {
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
int_to_string(AS_INT(frame.registers[src1]), buffer);
|
int_to_string(AS_INT(frame.registers[src1]), buffer);
|
||||||
ptr = str_alloc(vm, &frame, buffer, strlen(buffer));
|
ptr = str_alloc(vm, &frame, buffer, strlength(buffer));
|
||||||
frame.registers[dest] = ptr;
|
frame.registers[dest] = ptr;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -445,7 +445,7 @@ bool step_vm(VM *vm) {
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
uint_to_string(frame.registers[src1], buffer);
|
uint_to_string(frame.registers[src1], buffer);
|
||||||
ptr = str_alloc(vm, &frame, buffer, strlen(buffer));
|
ptr = str_alloc(vm, &frame, buffer, strlength(buffer));
|
||||||
frame.registers[dest] = ptr;
|
frame.registers[dest] = ptr;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -457,7 +457,7 @@ bool step_vm(VM *vm) {
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
fixed_to_string(AS_INT(frame.registers[src1]), buffer);
|
fixed_to_string(AS_INT(frame.registers[src1]), buffer);
|
||||||
ptr =
|
ptr =
|
||||||
str_alloc(vm, &frame, buffer, strlen(buffer)); /* copy buffer to dest */
|
str_alloc(vm, &frame, buffer, strlength(buffer)); /* copy buffer to dest */
|
||||||
frame.registers[dest] = ptr;
|
frame.registers[dest] = ptr;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
Loading…
Reference in New Issue