The interpreter works! More builtins to be implemented.
This commit is contained in:
parent
ffc73e773c
commit
b935325eb4
|
|
@ -0,0 +1,14 @@
|
||||||
|
// Kyler Olsen
|
||||||
|
// YREA SLS
|
||||||
|
// Builtin Functions Header
|
||||||
|
// November 2025
|
||||||
|
|
||||||
|
#ifndef SLS_BUILTIN_FUNCTIONS_H
|
||||||
|
#define SLS_BUILTIN_FUNCTIONS_H
|
||||||
|
|
||||||
|
#include "sls/bool.h"
|
||||||
|
#include "sls/interpreter.h"
|
||||||
|
|
||||||
|
Boolean load_builtins(InterpreterState *interpreter_state);
|
||||||
|
|
||||||
|
#endif // SLS_BUILTIN_FUNCTIONS_H
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#include "sls/bool.h"
|
||||||
#include "sls/lexer.h"
|
#include "sls/lexer.h"
|
||||||
#include "sls/hash_table.h"
|
#include "sls/hash_table.h"
|
||||||
|
|
||||||
|
|
@ -34,20 +35,20 @@ extern const size_t STACK_TYPE_COUNT;
|
||||||
typedef struct StackItem {
|
typedef struct StackItem {
|
||||||
StackType type;
|
StackType type;
|
||||||
union {
|
union {
|
||||||
Identifier identifier;
|
Identifier identifier; // type == STACK_IDENTIFIER
|
||||||
int64_t i64;
|
int64_t i64; // type == STACK_I64
|
||||||
int32_t i32;
|
int32_t i32; // type == STACK_I32
|
||||||
int16_t i16;
|
int16_t i16; // type == STACK_I16
|
||||||
int8_t i8;
|
int8_t i8; // type == STACK_I8
|
||||||
uint64_t u64;
|
uint64_t u64; // type == STACK_U64
|
||||||
uint32_t u32;
|
uint32_t u32; // type == STACK_U32
|
||||||
uint16_t u16;
|
uint16_t u16; // type == STACK_U16
|
||||||
uint8_t u8;
|
uint8_t u8; // type == STACK_U8
|
||||||
float f32;
|
float f32; // type == STACK_FLOAT
|
||||||
double f64;
|
double f64; // type == STACK_DOUBLE
|
||||||
uint8_t character;
|
uint8_t character; // type == STACK_CHARACTER
|
||||||
Boolean boolean;
|
Boolean boolean; // type == STACK_BOOLEAN
|
||||||
TokenString token_string;
|
TokenString token_string; // type == STACK_TOKEN_STRING
|
||||||
};
|
};
|
||||||
struct StackItem *next;
|
struct StackItem *next;
|
||||||
} StackItem;
|
} StackItem;
|
||||||
|
|
@ -57,6 +58,21 @@ typedef struct {
|
||||||
HashTable *functions;
|
HashTable *functions;
|
||||||
} InterpreterState;
|
} InterpreterState;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
FUNCTION_TOKEN_STRING,
|
||||||
|
FUNCTION_BUILTIN,
|
||||||
|
} FunctionType;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
FunctionType type;
|
||||||
|
union {
|
||||||
|
TokenString token_string; // type == FUNCTION_TOKEN_STRING
|
||||||
|
Boolean (*builtin)(InterpreterState *); // type == FUNCTION_BUILTIN
|
||||||
|
};
|
||||||
|
} FunctionItem;
|
||||||
|
|
||||||
|
Boolean push_token(InterpreterState *interpreter_state, Token token);
|
||||||
|
|
||||||
Boolean execute(InterpreterState *interpreter_state, LexerTokenResult *token);
|
Boolean execute(InterpreterState *interpreter_state, LexerTokenResult *token);
|
||||||
InterpreterState *interpreter_create();
|
InterpreterState *interpreter_create();
|
||||||
void interpreter_delete(InterpreterState *interpreter_state);
|
void interpreter_delete(InterpreterState *interpreter_state);
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -9,6 +9,7 @@
|
||||||
#include "sls/interpreter.h"
|
#include "sls/interpreter.h"
|
||||||
#include "sls/lexer.h"
|
#include "sls/lexer.h"
|
||||||
#include "sls/hash_table.h"
|
#include "sls/hash_table.h"
|
||||||
|
#include "sls/builtin.h"
|
||||||
|
|
||||||
static const size_t HASH_TABLE_BUCKET_COUNT = 256;
|
static const size_t HASH_TABLE_BUCKET_COUNT = 256;
|
||||||
|
|
||||||
|
|
@ -31,15 +32,15 @@ const char *STACK_TYPES_NAMES[] = {
|
||||||
|
|
||||||
const size_t STACK_TYPE_COUNT = sizeof(STACK_TYPES_NAMES) / sizeof(*STACK_TYPES_NAMES);
|
const size_t STACK_TYPE_COUNT = sizeof(STACK_TYPES_NAMES) / sizeof(*STACK_TYPES_NAMES);
|
||||||
|
|
||||||
static Boolean hash_table_put_funcs(HashTable *ht, SlsStr key, TokenString *item) {
|
static inline Boolean hash_table_put_funcs(HashTable *ht, SlsStr key, FunctionItem *item) {
|
||||||
return hash_table_put(ht, key, (void *)item);
|
return hash_table_put(ht, key, (void *)item);
|
||||||
}
|
}
|
||||||
|
|
||||||
static TokenString *hash_table_get_funcs(const HashTable *ht, SlsStr key, TokenString *default_item) {
|
static inline FunctionItem *hash_table_get_funcs(const HashTable *ht, SlsStr key, FunctionItem *default_item) {
|
||||||
return (TokenString*)hash_table_get(ht, key, (void *)default_item);
|
return (FunctionItem*)hash_table_get(ht, key, (void *)default_item);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Boolean push_token(InterpreterState *interpreter_state, Token token) {
|
Boolean push_token(InterpreterState *interpreter_state, Token token) {
|
||||||
StackType type;
|
StackType type;
|
||||||
switch (token.type) {
|
switch (token.type) {
|
||||||
case TOKEN_EOF:
|
case TOKEN_EOF:
|
||||||
|
|
@ -99,6 +100,7 @@ static Boolean push_token(InterpreterState *interpreter_state, Token token) {
|
||||||
}
|
}
|
||||||
|
|
||||||
StackItem *item = (StackItem *)malloc(sizeof(StackItem));
|
StackItem *item = (StackItem *)malloc(sizeof(StackItem));
|
||||||
|
if (item == NULL) return FALSE;
|
||||||
item->type = type;
|
item->type = type;
|
||||||
item->next = interpreter_state->stack;
|
item->next = interpreter_state->stack;
|
||||||
interpreter_state->stack = item;
|
interpreter_state->stack = item;
|
||||||
|
|
@ -147,10 +149,20 @@ static Boolean push_token(InterpreterState *interpreter_state, Token token) {
|
||||||
item->token_string = copy_token_string(token.token_string);
|
item->token_string = copy_token_string(token.token_string);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Boolean execute_func(InterpreterState *interpreter_state, SlsStr key) {
|
static Boolean execute_func(InterpreterState *interpreter_state, SlsStr key) {
|
||||||
|
FunctionItem *func = hash_table_get_funcs(interpreter_state->functions, key, NULL);
|
||||||
|
if (func == NULL) return FALSE;
|
||||||
|
switch (func->type) {
|
||||||
|
case FUNCTION_BUILTIN:
|
||||||
|
return func->builtin(interpreter_state);
|
||||||
|
case FUNCTION_TOKEN_STRING:
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
Boolean execute(InterpreterState *interpreter_state, LexerTokenResult *token) {
|
Boolean execute(InterpreterState *interpreter_state, LexerTokenResult *token) {
|
||||||
|
|
@ -162,9 +174,14 @@ Boolean execute(InterpreterState *interpreter_state, LexerTokenResult *token) {
|
||||||
|
|
||||||
InterpreterState *interpreter_create() {
|
InterpreterState *interpreter_create() {
|
||||||
InterpreterState *interpreter_state = (InterpreterState *)malloc(sizeof(InterpreterState));
|
InterpreterState *interpreter_state = (InterpreterState *)malloc(sizeof(InterpreterState));
|
||||||
|
if (interpreter_state == NULL)
|
||||||
|
return NULL;
|
||||||
interpreter_state->stack = NULL;
|
interpreter_state->stack = NULL;
|
||||||
interpreter_state->functions = init_hash_table(HASH_TABLE_BUCKET_COUNT);
|
interpreter_state->functions = init_hash_table(HASH_TABLE_BUCKET_COUNT);
|
||||||
|
if (!load_builtins(interpreter_state)) {
|
||||||
|
interpreter_delete(interpreter_state);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
return interpreter_state;
|
return interpreter_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,56 @@
|
||||||
|
|
||||||
static const SlsStr REPL_FILE_NAME = SLS_STR_CONST("<STDIN>");
|
static const SlsStr REPL_FILE_NAME = SLS_STR_CONST("<STDIN>");
|
||||||
|
|
||||||
|
void print_top_of_stack(InterpreterState *interpreter_state) {
|
||||||
|
if (interpreter_state->stack == NULL)
|
||||||
|
return;
|
||||||
|
switch (interpreter_state->stack->type) {
|
||||||
|
case STACK_IDENTIFIER:
|
||||||
|
printf("#0: ::%s\n", interpreter_state->stack->identifier.name.str);
|
||||||
|
break;
|
||||||
|
case STACK_I64:
|
||||||
|
printf("#0: %ld\n", interpreter_state->stack->i64);
|
||||||
|
break;
|
||||||
|
case STACK_I32:
|
||||||
|
printf("#0: %d:i32\n", interpreter_state->stack->i32);
|
||||||
|
break;
|
||||||
|
case STACK_I16:
|
||||||
|
printf("#0: %d:i16\n", interpreter_state->stack->i16);
|
||||||
|
break;
|
||||||
|
case STACK_I8:
|
||||||
|
printf("#0: %d:8\n", interpreter_state->stack->i8);
|
||||||
|
break;
|
||||||
|
case STACK_U64:
|
||||||
|
printf("#0: %lu:u64\n", interpreter_state->stack->u64);
|
||||||
|
break;
|
||||||
|
case STACK_U32:
|
||||||
|
printf("#0: %u:32\n", interpreter_state->stack->u32);
|
||||||
|
break;
|
||||||
|
case STACK_U16:
|
||||||
|
printf("#0: %u:16\n", interpreter_state->stack->u16);
|
||||||
|
break;
|
||||||
|
case STACK_U8:
|
||||||
|
printf("#0: %u:8\n", interpreter_state->stack->u8);
|
||||||
|
break;
|
||||||
|
case STACK_FLOAT:
|
||||||
|
printf("#0: %f:f32\n", interpreter_state->stack->f32);
|
||||||
|
break;
|
||||||
|
case STACK_DOUBLE:
|
||||||
|
printf("#0: %f\n", interpreter_state->stack->f64);
|
||||||
|
break;
|
||||||
|
case STACK_CHARACTER:
|
||||||
|
printf("#0: %c\n", interpreter_state->stack->character);
|
||||||
|
break;
|
||||||
|
case STACK_BOOLEAN:
|
||||||
|
if (interpreter_state->stack->boolean) printf("#0: TRUE\n");
|
||||||
|
else printf("#0: FALSE\n");
|
||||||
|
break;
|
||||||
|
case STACK_TOKEN_STRING:
|
||||||
|
printf("#0: <TOKEN STRING>\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int repl(int argc, char *argv[]) {
|
int repl(int argc, char *argv[]) {
|
||||||
(void)argc;
|
(void)argc;
|
||||||
(void)argv;
|
(void)argv;
|
||||||
|
|
@ -50,12 +100,13 @@ int repl(int argc, char *argv[]) {
|
||||||
break;
|
break;
|
||||||
} else
|
} else
|
||||||
if (!execute(interpreter_state, head)) {
|
if (!execute(interpreter_state, head)) {
|
||||||
printf("A runtime error occurred!");
|
printf("A runtime error occurred!\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
head = head->next;
|
head = head->next;
|
||||||
}
|
}
|
||||||
clean_token_result(result.result);
|
clean_token_result(result.result);
|
||||||
|
print_top_of_stack(interpreter_state);
|
||||||
}
|
}
|
||||||
sls_str_free(&code);
|
sls_str_free(&code);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue