add BASIC interpreter

Signed-off-by: Avinal Kumar <avinal.xlvii@gmail.com>
This commit is contained in:
2021-08-03 22:27:49 +05:30
parent 886ed106e7
commit 5a5a37e3f8
23 changed files with 3770 additions and 0 deletions

View File

@@ -0,0 +1,28 @@
/**
* SPDX-License-Identifier: MIT
* SPDX-FileCopyrightText: 2015-2016 Johan Van den Brande
*
* @file arch.h
*/
#ifndef BASIC_ARCH_H_
#define BASIC_ARCH_H_
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
int arch_init(void);
typedef void (*arch_load_out_cb)(char* line, void* context);
int arch_load(char* filename, arch_load_out_cb cb, void* context);
typedef uint16_t (*arch_save_cb)(char** line, void* context);
int arch_save(char* filename, arch_save_cb cb, void* context);
typedef void (*arch_dir_out_cb)(char* name, size_t size, bool label, void* context);
int arch_dir(arch_dir_out_cb cb, void* context);
int arch_delete(char* filename);
#endif // BASIC_ARCH_H_

View File

@@ -0,0 +1,28 @@
/**
* SPDX-License-Identifier: MIT
* SPDX-FileCopyrightText: 2015-2016 Johan Van den Brande
*
* @file array.h
*/
#ifndef BASIC_ARRAY_H_
#define BASIC_ARRAY_H_
#include <stddef.h>
typedef struct array array;
array* array_new(size_t element_size);
array* array_alloc(array* array, size_t size);
void array_destroy(array* array);
void* array_push(array* array, void* value);
void* array_get(array* array, size_t index);
void* array_set(array* array, size_t index, void* value);
size_t array_size(array* array);
#endif // BASIC_ARRAY_H_

View File

@@ -0,0 +1,19 @@
/**
* SPDX-License-Identifier: MIT
* SPDX-FileCopyrightText: 2015-2016 Johan Van den Brande
*
* @file callback.h
*/
#ifndef BASIC_CALLBACK_H_
#define BASIC_CALLBACK_H_
#include <stdbool.h>
typedef struct error {
int error;
};
typedef bool (*callback)(error err, void* data);
#endif // BASIC_CALLBACK_H_

View File

@@ -0,0 +1,25 @@
/**
* SPDX-License-Identifier: MIT
* SPDX-FileCopyrightText: 2015-2016 Johan Van den Brande
*
* @file dictionary.h
*/
#ifndef BASIC_DICTIONARY_H_
#define BASIC_DICTIONARY_H_
#include <stdbool.h>
typedef struct dictionary dictionary;
typedef void (*dictionary_each_cb)(char* name, void* value, void* context);
dictionary* dictionary_new(void);
void dictionary_destroy(dictionary* d, dictionary_each_cb cb);
void dictionary_put(dictionary* d, char* name, void* value);
bool dictionary_has(dictionary* d, char* name);
void* dictionary_get(dictionary* d, char* name);
void dictionary_each(dictionary* d, dictionary_each_cb cb, void* context);
void* dictionary_del(dictionary* d, char* name);
#endif // BASIC_DICTIONARY_H_

View File

@@ -0,0 +1,14 @@
/**
* SPDX-License-Identifier: MIT
* SPDX-FileCopyrightText: 2015-2016 Johan Van den Brande
*
* @file error.h
*/
#ifndef BASIC_ERROR_H_
#define BASIC_ERROR_H_
extern char *last_error;
void error(const char *error_msg);
#endif // BASIC_ERROR_H_

View File

@@ -0,0 +1,13 @@
/**
* SPDX-License-Identifier: MIT
* SPDX-FileCopyrightText: 2015-2016 Johan Van den Brande
*
* @file hexdump.h
*/
#ifndef BASIC_HEXDUMP_H_
#define BASIC_HEXDUMP_H_
void hexdump(char *desc, void *addr, int len);
#endif // BASIC_HEXDUMP_H_

View File

@@ -0,0 +1,18 @@
/**
* SPDX-License-Identifier: MIT
* SPDX-FileCopyrightText: 2015-2016 Johan Van den Brande
*
* @file io.h
*/
#ifndef BASIC_IO_H_
#define BASIC_IO_H_
#include <stdlib.h>
typedef int (*basic_putchar)(int ch);
typedef int (*basic_getchar)(void);
void basic_io_print(char* buffer);
char* basic_io_readline(char* prompt, char* buffer, size_t buffer_size);
#endif // BASIC_IO_H_

View File

@@ -0,0 +1,13 @@
/**
* SPDX-License-Identifier: MIT
* SPDX-FileCopyrightText: 2015-2016 Johan Van den Brande
*
* @file kbhit.h
*/
#ifndef BASIC_KBHIT_H_
#define BASIC_KBHIT_H_
int kbhit(void);
#endif // BASIC_KBHIT_H_

View File

@@ -0,0 +1,42 @@
/**
* SPDX-License-Identifier: MIT
* SPDX-FileCopyrightText: 2015-2016 Johan Van den Brande
*
* @file lines.h
*/
#ifndef BASIC_LINES_H_
#define BASIC_LINES_H_
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
typedef struct line line;
struct line {
uint16_t number;
uint8_t length;
char contents;
};
void lines_init(char* memory, size_t memory_size);
size_t lines_memory_used(void);
size_t lines_memory_available(void);
bool lines_delete(uint16_t number);
bool lines_store(uint16_t number, char* contents);
typedef void (*lines_list_cb)(uint16_t number, char* contents);
void lines_list(uint16_t start, uint16_t end, lines_list_cb out);
void lines_clear(void);
char* lines_get_contents(uint16_t number);
uint16_t lines_first(void);
uint16_t lines_next(uint16_t number);
#endif // BASIC_LINES_H_

View File

@@ -0,0 +1,87 @@
/**
* SPDX-License-Identifier: MIT
* SPDX-FileCopyrightText: 2015-2016 Johan Van den Brande
*
* @file parser.h
*/
#ifndef BASIC_PARSER_H_
#define BASIC_PARSER_H_
#include <io.h>
#include <stdbool.h>
#include <tokenizer.h>
float evaluate(char* expression_string);
void evaluate_print(char* line);
void evaluate_print_func_param(char* func, float param);
const char* evaluate_last_error(void);
void clear_last_error(void);
void basic_init(size_t memory_size, size_t stack_size);
void basic_destroy(void);
void basic_register_io(basic_putchar putch, basic_getchar getch);
char* basic_readline(char* prompt, char* buffer, size_t buffer_size);
void basic_eval(char* line);
void basic_run(void);
// For extensions
typedef float (*function)(float number);
typedef struct {
token _token;
function _function;
} token_to_function;
typedef enum {
basic_function_type_keyword,
basic_function_type_op,
basic_function_type_numeric,
basic_function_type_string,
basic_function_type_print
} basic_function_type;
typedef enum { kind_numeric, kind_string } kind;
typedef union {
float number;
char* string;
} value;
typedef struct {
kind kind;
bool empty;
bool mallocd;
value value;
} basic_type;
typedef int (*function_0)(basic_type* rv);
typedef int (*function_1)(basic_type* v1, basic_type* rv);
typedef int (*function_2)(basic_type* v1, basic_type* v2, basic_type* rv);
typedef int (*function_3)(basic_type* v1, basic_type* v2, basic_type* v3, basic_type* rv);
typedef int (*function_4)(basic_type* v1, basic_type* v2, basic_type* v3, basic_type* v4,
basic_type* rv);
typedef int (*function_5)(basic_type* v1, basic_type* v2, basic_type* v3, basic_type* v4,
basic_type* v5, basic_type* rv);
token register_token(char* token_name);
token register_function_0(basic_function_type type, char* keyword, function_0 function);
token register_function_1(basic_function_type type, char* keyword, function_1 function, kind v1);
token register_function_2(basic_function_type type, char* keyword, function_2 function, kind v1,
kind v2);
token register_function_3(basic_function_type type, char* keyword, function_3 function, kind v1,
kind v2, kind v3);
token register_function_4(basic_function_type type, char* keyword, function_4 function, kind v1,
kind v2, kind v3, kind v4);
token register_function_5(basic_function_type type, char* keyword, function_5 function, kind v1,
kind v2, kind v3, kind v4, kind v5);
#endif // BASIC_PARSER_H_

View File

@@ -0,0 +1,70 @@
/**
* SPDX-License-Identifier: MIT
* SPDX-FileCopyrightText: 2015-2016 Johan Van den Brande
*
* @file tokenizer.h
*/
#ifndef BASIC_TOKENIZER_H_
#define BASIC_TOKENIZER_H_
#include <stdlib.h>
#define tokenizer_string_length 64
#define tokenizer_variable_length 8
typedef unsigned int token;
typedef char* token_name;
typedef char* token_keyword;
typedef struct {
token token;
token_name name;
} token_entry;
#define add_token(t, k) static token_entry _##t = {t, k};
typedef enum {
// Standard token types needed by the tokenizer
T_THE_END,
T_ERROR,
T_EOF,
T_NUMBER,
T_STRING,
T_VARIABLE_STRING,
T_VARIABLE_NUMBER,
// Some tokens that are standard as well
T_PLUS,
T_MINUS,
T_MULTIPLY,
T_DIVIDE,
T_LEFT_BANANA,
T_RIGHT_BANANA,
T_COLON,
T_SEMICOLON,
T_EQUALS,
T_LESS,
T_GREATER,
T_COMMA,
TOKEN_TYPE_END
} token_type;
void tokenizer_setup(void);
void tokenizer_init(char* input);
token tokenizer_get_next_token(void);
float tokenizer_get_number(void);
char* tokenizer_get_string(void);
void tokenizer_get_variable_name(char* name);
char* tokenizer_token_name(token);
char* tokenizer_char_pointer(char* set);
void tokenizer_add_tokens(token_entry* tokens);
void tokenizer_register_token(token_entry* entry);
void tokenizer_free_registered_tokens(void);
#endif // BASIC_TOKENIZER_H_

View File

@@ -0,0 +1,41 @@
/**
* SPDX-License-Identifier: MIT
* SPDX-FileCopyrightText: 2015-2016 Johan Van den Brande
*
* @file variable.h
*/
#ifndef BASIC_VARIABLES_H_
#define BASIC_VARIABLES_H_
#include <stdbool.h>
typedef enum { variable_type_unknown, variable_type_numeric, variable_type_string } variable_type;
typedef struct variable variable;
bool variables_init(void);
void variables_destroy(void);
variable* variable_get(char* name);
char* variable_get_string(char* name);
float variable_get_numeric(char* name);
variable* variable_set_string(char* name, char* value);
variable* variable_set_numeric(char* name, float value);
variable_type variable_get_type(char* name);
variable* variable_array_init(char* name, variable_type type, size_t dimensions, size_t* vector);
variable* variable_array_set_string(char* name, char* value, size_t* vector);
char* variable_array_get_string(char* name, size_t* vector);
variable* variable_array_set_numeric(char* name, float value, size_t* vector);
float variable_array_get_numeric(char* name, size_t* vector);
typedef void (*variables_each_cb)(variable* var, void* context);
void variables_each(variables_each_cb each, void* context);
void variable_dump(variable* var);
#endif // BASIC_VARIABLES_H_