Skip to content

Commit 0c2a2e3

Browse files
tidyups, PUSH,POP statements
1 parent d9a0636 commit 0c2a2e3

13 files changed

+583
-437
lines changed

include/tokenizer.h

+2
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@
118118
T(UNTIL) \
119119
T(DIM) \
120120
T(REDIM) \
121+
T(PUSH) \
122+
T(POP) \
121123
T(MOUNT)
122124

123125
/*

include/ubasic.h

+194-37
Original file line numberDiff line numberDiff line change
@@ -125,42 +125,48 @@ typedef struct ub_proc_fn_def {
125125
* @brief An array of integers
126126
*/
127127
typedef struct ub_var_int_array {
128+
uint64_t itemcount;
128129
const char* varname;
129130
int64_t* values;
130-
uint64_t itemcount;
131131
struct ub_var_int_array* next;
132132
} ub_var_int_array;
133133

134134
/**
135135
* @brief An array of strings
136136
*/
137137
typedef struct ub_var_string_array {
138+
uint64_t itemcount;
138139
const char* varname;
139140
const char** values;
140-
uint64_t itemcount;
141141
struct ub_var_string_array* next;
142142
} ub_var_string_array;
143143

144144
/**
145145
* @brief An array of real (double)
146146
*/
147147
typedef struct ub_var_double_array {
148+
uint64_t itemcount;
148149
const char* varname;
149150
double* values;
150-
uint64_t itemcount;
151151
struct ub_var_double_array* next;
152152
} ub_var_double_array;
153153

154+
/**
155+
* @brief A generic array, we can use
156+
* this to represent any array regardless
157+
* of its contained type.
158+
*/
159+
typedef struct ub_var_generic_array {
160+
uint64_t itemcount;
161+
const char* varname;
162+
void* values_inaccesible;
163+
struct ub_var_generic_array* next;
164+
} ub_var_generic_array;
165+
154166
/**
155167
* @brief Line reference in program.
156-
* Each program has a doubly linked list of these,
157-
* stored in ascending order. Once we iterate the
158-
* list past the search number we know we don't have
159-
* to search any further.
160-
*
161-
* TODO: If search number is < current line number,
162-
* search backwards instead and stop when previous
163-
* number is before search.
168+
* Each program has a hashmap of these so it can find a line number
169+
* in O(1) time.
164170
*/
165171
typedef struct ub_line_ref {
166172
uint32_t line_number;
@@ -181,61 +187,183 @@ typedef struct ub_line_ref {
181187
#define STRINGIFY(x) AUX(x)
182188

183189
/**
184-
* @brief BASIC program context
185-
* Every instance of a BASIC program has one of these,
186-
* also certain structures such as procedures will clone
187-
* the context and run on the clone until the procedure
188-
* completes. Cloned contexts share variables and you
189-
* should never call ubasic_destroy() on them!
190+
* @brief BASIC program context.
191+
* Every instance of a BASIC program has one of these,* also certain structures
192+
* such as functions will clone the context and run on the clone until the function
193+
* completes. Cloned contexts share variables and you should never call
194+
* ubasic_destroy() on them!
190195
*/
191196
typedef struct ubasic_ctx {
197+
/**
198+
* @brief Pointer to the start of the next token
199+
* Always between program_ptr and program_ptr + strlen(program_ptr)
200+
*/
192201
char const* ptr;
202+
/**
203+
* @brief Pointer to the character after the next token.
204+
* Always between program_ptr and program_ptr + strlen(program_ptr)
205+
*/
193206
char const* nextptr;
207+
/**
208+
* @brief Numeric form of the token between ptr and nextptr.
209+
* Should always be a value within the enum token_t
210+
*/
194211
int current_token;
212+
/**
213+
* @brief Current line number
214+
*/
195215
int64_t current_linenum;
216+
/**
217+
* @brief True if the program has thrown an error and should end.
218+
* This may not actually cause termination of the program if we are
219+
* inside an EVAL at the time.
220+
*/
196221
bool errored;
222+
/**
223+
* @brief True if the program has ended, e.g. it reached an explicit
224+
* END statement, or fell off the end of the program to the terminating
225+
* null char.
226+
*/
197227
bool ended;
228+
/**
229+
* @brief The whole program text, untokenized.
230+
* May have been "cleaned" by an initial preprocessing phase which removes
231+
* unneccesary spacing etc.
232+
*/
198233
char* program_ptr;
199-
234+
/**
235+
* @brief A context-local string buffer used for parsing function/procedure
236+
* parameter lists.
237+
*/
200238
char string[MAX_STRINGLEN];
201-
239+
/**
240+
* @brief Local integer variable stack for variables declared within a
241+
* function or procedure scope.
242+
*/
202243
struct ub_var_int* local_int_variables[MAX_CALL_STACK_DEPTH];
244+
/**
245+
* @brief Local string variable stack for variables declared within a
246+
* function or procedure scope.
247+
*/
203248
struct ub_var_string* local_string_variables[MAX_CALL_STACK_DEPTH];
249+
/**
250+
* @brief Local real (double) variable stack for variables declared
251+
* within a function or procedure scope.
252+
*/
204253
struct ub_var_double* local_double_variables[MAX_CALL_STACK_DEPTH];
205-
206-
uint64_t gosub_stack[MAX_CALL_STACK_DEPTH];
207-
uint64_t gosub_stack_ptr;
208-
254+
/**
255+
* @brief Call stack, holds the return line numbers for each
256+
* level of calls to a procedure, function or GOSUB
257+
*/
258+
uint64_t call_stack[MAX_CALL_STACK_DEPTH];
259+
/**
260+
* @brief How far up the call stack we are. The call stack pointer
261+
* starts at 0, and can go as high as MAX_CALL_STACK_DEPTH - 1
262+
*/
263+
uint64_t call_stack_ptr;
264+
/**
265+
* @brief Repeat stack, holds the return line numbers for each
266+
* level of REPEAT...UNTIL loop.
267+
*/
209268
uint64_t repeat_stack[MAX_LOOP_STACK_DEPTH];
269+
/**
270+
* @brief How far up the REPEAT...UNTIL stack we are. The repeat
271+
* stack pointer starts at 0, and can go as high as
272+
* MAX_LOOP_STACK_DEPTH - 1
273+
*/
210274
uint64_t repeat_stack_ptr;
211-
212-
int oldlen;
275+
/**
276+
* @brief Previous program length, before an EVAL statement.
277+
* An EVAL statement appends additional lines to the program
278+
* beyond its original end, storing the previous size in this
279+
* value. If this value is non-zero an EVAL is in progress,
280+
* otherwise no EVAL is executing.
281+
*/
282+
size_t oldlen;
283+
/**
284+
* @brief The return line number for an EVAL statement
285+
*/
213286
int64_t eval_linenum;
214-
287+
/**
288+
* @brief FOR stack, holds the return line numbers for each
289+
* level of FOR...NEXT loop.
290+
*/
215291
struct for_state for_stack[MAX_LOOP_STACK_DEPTH];
292+
/**
293+
* @brief How far up the FOR...NEXT stack we are. The FOR
294+
* stack pointer starts at 0, and can go as high as
295+
* MAX_LOOP_STACK_DEPTH - 1
296+
*/
216297
uint64_t for_stack_ptr;
217-
298+
/**
299+
* @brief Definitions for procedures and functions in the program
300+
*/
218301
struct ub_proc_fn_def* defs;
219-
302+
/**
303+
* @brief Global integer variable list
304+
*/
220305
struct ub_var_int* int_variables;
306+
/**
307+
* @brief Global string variable list
308+
*/
221309
struct ub_var_string* str_variables;
310+
/**
311+
* @brief Global double variable list
312+
*/
222313
struct ub_var_double* double_variables;
223-
314+
/**
315+
* @brief Global integer array variable list
316+
*/
224317
struct ub_var_int_array* int_array_variables;
318+
/**
319+
* @brief Global string array variable list
320+
*/
225321
struct ub_var_string_array* string_array_variables;
322+
/**
323+
* @brief Global double array variable list
324+
*/
226325
struct ub_var_double_array* double_array_variables;
227-
326+
/**
327+
* @brief I/O Console
328+
*/
228329
struct console* cons;
229-
330+
/**
331+
* @brief Function return type expected.
332+
* This is only relavent when executing a function atomically.
333+
*/
230334
ub_return_type fn_type;
335+
/**
336+
* @brief Function return value pointer.
337+
* This is only relavent when executing a function atomically.
338+
*/
231339
void* fn_return;
340+
/**
341+
* @brief Bracket depth when parsing function or procedure
342+
* parameter lists.
343+
*/
232344
int bracket_depth;
345+
/**
346+
* @brief Item start pointer when parsing function or procedure
347+
* parameter lists.
348+
*/
233349
char const* item_begin;
350+
/**
351+
* @brief Linked list of function parameters when parsing function
352+
* or procedure parameter lists.
353+
*/
234354
struct ub_param* param;
235-
236-
int32_t graphics_colour; // Current GCOL
237-
238-
struct hashmap* lines; // Hash map of line number to char pointers
355+
/**
356+
* @brief Current graphics colour (GCOL) for graphics drawing commands
357+
*/
358+
int32_t graphics_colour;
359+
/**
360+
* @brief Hashmap of lines for O(1) lookup of line numbers
361+
*/
362+
struct hashmap* lines;
363+
/**
364+
* @brief Block IF...THEN...ELSE depth
365+
*/
366+
uint64_t if_nest_level;
239367
} ubasic_ctx;
240368

241369
/**
@@ -301,7 +429,7 @@ typedef struct ubasic_str_fn
301429
[[maybe_unused]] char const* item_begin = ctx->ptr;
302430

303431
/**
304-
* @brief Get a function parameter of type
432+
* @brief Get a function parameter of type.
305433
* @param type Type of function parameter to get, fills one of the variables
306434
* strval, doubleval or intval.
307435
*/
@@ -358,7 +486,6 @@ typedef struct ubasic_str_fn
358486
} \
359487
}
360488

361-
362489
/*
363490
* Validation functions
364491
*/
@@ -415,6 +542,22 @@ char* ubasic_inkey(struct ubasic_ctx* ctx);
415542
char* ubasic_insocket(struct ubasic_ctx* ctx);
416543
char* ubasic_upper(struct ubasic_ctx* ctx);
417544
char* ubasic_lower(struct ubasic_ctx* ctx);
545+
546+
/*
547+
* File I/O functions
548+
*/
549+
void openin_statement(struct ubasic_ctx* ctx);
550+
void openup_statement(struct ubasic_ctx* ctx);
551+
void openout_statement(struct ubasic_ctx* ctx);
552+
void read_statement(struct ubasic_ctx* ctx);
553+
void close_statement(struct ubasic_ctx* ctx);
554+
void eof_statement(struct ubasic_ctx* ctx);
555+
void delete_statement(struct ubasic_ctx* ctx);
556+
void mkdir_statement(struct ubasic_ctx* ctx);
557+
void mount_statement(struct ubasic_ctx* ctx);
558+
void rmdir_statement(struct ubasic_ctx* ctx);
559+
void write_statement(struct ubasic_ctx* ctx);
560+
418561
/*
419562
* Builtin real (double) functions
420563
*/
@@ -472,6 +615,15 @@ void ubasic_set_string_array(const char* var, const char* value, struct ubasic_c
472615
void ubasic_set_double_array(const char* var, double value, struct ubasic_ctx* ctx);
473616
void dim_statement(struct ubasic_ctx* ctx);
474617
void redim_statement(struct ubasic_ctx* ctx);
618+
void pop_statement(struct ubasic_ctx* ctx);
619+
void push_statement(struct ubasic_ctx* ctx);
620+
int64_t arr_expr_set_index(struct ubasic_ctx* ctx, const char* varname);
621+
bool ubasic_pop_string_array(const char* var, int64_t pop_pos, struct ubasic_ctx* ctx);
622+
bool ubasic_pop_int_array(const char* var, int64_t pop_pos, struct ubasic_ctx* ctx);
623+
bool ubasic_pop_double_array(const char* var, int64_t pop_pos, struct ubasic_ctx* ctx);
624+
bool ubasic_push_string_array(const char* var, int64_t push_pos, struct ubasic_ctx* ctx);
625+
bool ubasic_push_int_array(const char* var, int64_t push_pos, struct ubasic_ctx* ctx);
626+
bool ubasic_push_double_array(const char* var, int64_t push_pos, struct ubasic_ctx* ctx);
475627

476628
/*
477629
* Integer expression evaluation
@@ -490,3 +642,8 @@ void double_relation(struct ubasic_ctx* ctx, double* res);
490642
*/
491643
const char* str_expr(struct ubasic_ctx* ctx);
492644
int64_t str_relation(struct ubasic_ctx* ctx);
645+
646+
/*
647+
* Misc functions
648+
*/
649+
char* printable_syntax(struct ubasic_ctx* ctx);

src/debugger.c

+4-4
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ void init_debug()
5555
symbol_fail();
5656
return;
5757
} else {
58-
unsigned char* filecontent = (unsigned char*)kmalloc(filesize);
58+
unsigned char* filecontent = kmalloc(filesize);
5959
if (!fs_read_file(symfile, 0, filesize, filecontent)) {
6060
symbol_fail();
6161
kfree(filecontent);
@@ -72,7 +72,7 @@ void init_debug()
7272
uint32_t offset = 0;
7373
uint32_t symcount = 0;
7474
uint32_t sizebytes = 0;
75-
symbol_table = (symbol_t*)kmalloc(sizeof(symbol_t));
75+
symbol_table = kmalloc(sizeof(symbol_t));
7676
symbol_t* thisentry = symbol_table;
7777

7878
while (offset < filesize) {
@@ -106,11 +106,11 @@ void init_debug()
106106
uint32_t length = strlen(symbol) + 1;
107107

108108
if (*type == 'T') {
109-
thisentry->name = (char*)kmalloc(length);
109+
thisentry->name = kmalloc(length);
110110
memcpy(thisentry->name, symbol, length);
111111
thisentry->address = hextoint(symbol_address);
112112
thisentry->type = *type;
113-
symbol_t* next = (symbol_t*)kmalloc(sizeof(symbol_t));
113+
symbol_t* next = kmalloc(sizeof(symbol_t));
114114
next->next = NULL;
115115
thisentry->next = next;
116116
thisentry = thisentry->next;

src/devfs.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ void init_devfs()
3434
devfs->rmdir = NULL;
3535
devfs->rm = NULL;
3636
register_filesystem(devfs);
37-
devfs_entries = (fs_directory_entry_t*)kmalloc(sizeof(fs_directory_entry_t));
37+
devfs_entries = kmalloc(sizeof(fs_directory_entry_t));
3838
devfs_entries->next = NULL;
3939
devfs_entries->size = 0;
4040
devfs_entries->flags = 0;

0 commit comments

Comments
 (0)