Commit Graph

116 Commits

Author SHA1 Message Date
Aryadev Chavali
6ae0bbedc5 Plug preprocesser into main 2024-07-07 19:06:56 +01:00
Aryadev Chavali
a422c7d1dc A reworked preprocesser with focus on stopping recursive errors
Preprocesser requires one function to use: preprocess.  Takes Tokens
and gives back Units.

A unit is a tree of tokens, where each unit is a node in that tree.  A
unit has a "root" token (value of node) and an "expansion" (children
of node) where the root is some preprocesser token (such as a
reference or USE call) and the expansion is the tokens it yields.  In
the case of a USE call this is the tokens of the file it includes, in
the case of a reference it's the tokens of the constant it refers to.
This means that the leaves of the tree of units are the completely
preprocessed/expanded form of the source code.

The function has many working components, which may need to be
extracted.  In particular, the function ensures we don't include a
source twice through a hash map and that constants are not redefined
in inner include scopes if they're already defined in outer
scopes (i.e. if compiling a.asm which defines constant N, then include
b.asm which defines constant N, then N uses the definition of a.asm
rather than b.asm).

I need to make a spec for this.
2024-07-06 17:38:02 +01:00
Aryadev Chavali
1145b97c4c Token to_string now include source name and is printed error style
So instead of the previous weird format, we have the format
<source_name>:<line>:<column>: <TYPE> which also allows me to quickly
go to that token via Emacs' (compile).
2024-07-06 17:36:58 +01:00
Aryadev Chavali
f9acb23671 Lexer errors contain the source name and tokenise_symbol refactor 2024-07-05 22:47:25 +01:00
Aryadev Chavali
036ac03176 Lexer tokens now include source name as part of the token 2024-07-05 18:18:11 +01:00
Aryadev Chavali
65ce50f620 Fix copyright notices and includes 2024-07-03 16:55:19 +01:00
Aryadev Chavali
15d39dcfe7 Reworked lexer to deal with invalid type suffixes
Now ~push.magic~ will result in an error about it being an invalid
type suffix.
2024-07-03 16:55:19 +01:00
Aryadev Chavali
42dbf515f0 Deleted preprocesser
Will be reworking it later
2024-07-03 16:55:19 +01:00
Aryadev Chavali
76bb5ec7d9 (Lexer)+to_string functions for Err, Err::Type 2024-06-01 13:53:54 +01:00
Aryadev Chavali
4625b3b7a5 (Lexer)+to_string functions for Token, Token::Type 2024-06-01 13:51:10 +01:00
Aryadev Chavali
a4689f9dd0 Lexer call pattern is now Err return with reference to token 2024-06-01 13:40:17 +01:00
Aryadev Chavali
7e9af309e3 lerr_t and lerr_type_t -> Lexer::Err and Lexer::Err::Type 2024-06-01 13:40:17 +01:00
Aryadev Chavali
4b85f90a52 Namespace the lexer module
Future proofing any name collisions.
2024-06-01 01:52:17 +01:00
Aryadev Chavali
83ad8b832b token_type_t -> Token::Type
Implicit namespacing using the struct
2024-06-01 01:49:24 +01:00
Aryadev Chavali
f5d8777b7a token_t -> Token
Use C++'s implicit typedef
2024-06-01 01:48:11 +01:00
Aryadev Chavali
f3f7578811 Update lexer trivially
HALT is now an opcode, which we deal with already.
2024-06-01 01:47:16 +01:00
Aryadev Chavali
f060a856d3 Fixed Makefile so it tracks dependencies better
It now tracks main.cpp's dependencies and rebuilds them as needed.
2024-04-16 20:42:51 +06:30
Aryadev Chavali
b44a61be41 src->vm, Makefile is now a bit more abstracted and pretty colours
Changed folder names for sake of clarity (will be introducing a new
build target soon), and Makefile can now easily support more targets.
2023-10-23 03:58:34 +01:00
Aryadev Chavali
587f31a63b Remove unnecessary log message 2023-10-23 03:11:05 +01:00
Aryadev Chavali
9496da9d93 Added and implemented OP_JUMP_IF_*
Performs a jump when the (BYTE|HWORD|WORD) at the top of the stack is
non zero.
2023-10-23 01:45:54 +01:00
Aryadev Chavali
b93a4af495 Extracted code that performs a jump into its own routine
Checks if the operand given is a well defined program address, then
performs the jump.
2023-10-23 01:45:18 +01:00
Aryadev Chavali
2ef104f235 Fixed bug in vm_mov(byte|hword) where registers aren't set properly
This is because we just OR the bits into the specific byte of the
word.  This means the previous state may leave artefacts as the OR
doesn't clear the bits away.

To do so, we apply a bit mask to clear the specified byte(s) of the
word, then perform the OR.
2023-10-23 01:43:24 +01:00
Aryadev Chavali
20030e364c Moved macros to extract nth (byte|hword) from a word to base.h 2023-10-23 00:53:44 +01:00
Aryadev Chavali
00f3b3bf21 Rearrange what is printed in vm_print_all
First the program, then the registers then the stack.
2023-10-23 00:49:59 +01:00
Aryadev Chavali
d0ee1f3b1f Check for and handle errors when interpreting bytecode
Prints an error message, returns a non zero code based on error
code (255 - err).

In main, I propagate this exit code.
2023-10-23 00:48:18 +01:00
Aryadev Chavali
919fae2df8 Added an example program fib.c
This is simply a program with an embedded set of instructions which
indefinitely computes and prints fibonacci numbers, computing them in
pairs.

Does it completely through the virtual machine rather than just hard C
instructions.

Also amended the Makefile to compile it.  Required moving the main.c
object file into the dependencies of $(DIST)/$(OUT).

I should track the dependencies for fib.c and main.c as well.
2023-10-23 00:45:23 +01:00
Aryadev Chavali
19eb401498 Fixed bugs with ordering of bytes in some operations
Also fixed an overflow error in vm_dup_word, where I underflow the
index of vm->stack.data which causes a buffer overflow.
2023-10-23 00:28:39 +01:00
Aryadev Chavali
ae9bc91713 Added and implemented OP_PRINT*
Here is where we may have differing interpretations of what the bits
in the data pile may actually mean.  This in particular refers to
printing the signed or unsigned versions of the bits given.  Also,
interpreting some byte as a character or just a raw number.
2023-10-23 00:09:12 +01:00
Aryadev Chavali
45ad8f7296 Fixed bug where vm_print_program listing for program was incorrect
Only happens when vm_print_program(STDERR), as STDERR occurs before
STDOUT on Emacs.  So while the lines would print, no instructions
would follow.  This fixes that by using fp.
2023-10-23 00:08:53 +01:00
Aryadev Chavali
b44eaefabb Remove get_opcode_data_type
Was only used for OP_PUSH data types anyway, so is essentially
useless.  Only OP_PUSH has operands after it that directly relate to
it: the rest either have a fixed type (a byte for registers, for
example) or NIL (because they have no operand).
2023-10-22 22:04:13 +01:00
Aryadev Chavali
7243ac2533 Coupled some routines together, implemented OP_PLUS_*, -vm_peek
Routines that use the stack for their operands i.e. aren't supplied
operands directly all have the same signature.  We may as well stick
them all together in one array and one conditional, just reduces the
number of branches.  Also looks nicer.

Implemented OP_PLUS_*.  Pretty simple to implement.

Deleted vm_peek as it was only necessary to update the `ret` register.
2023-10-22 22:02:53 +01:00
Aryadev Chavali
1962aabdf5 Added OP_PLUS_*
Takes two operands from the stack then pushes their sum.
2023-10-22 22:00:44 +01:00
Aryadev Chavali
789016a343 Fix bug where negative opcodes lead to invalid bytecode parsing 2023-10-22 21:47:32 +01:00
Aryadev Chavali
cc84703725 Added runtime errors to virtual machine
Every vm routine now returns an err_t, which is an enumeration of
possible error states.  ERR_OK represents the good state and is 0 so
error checking seems very natural in terms of language `if (err) ...`.
Errors bubble up the runtime, with any callers forced to check if an
error occurred.

This does mean that routines that call other routines cannot provide
an accurate trace of the subcaller (based on the fact that an error is
generated for the current instruction), but this should be a non issue
as no instruction should be complex enough to need proper traces.
2023-10-22 21:45:38 +01:00
Aryadev Chavali
7f1994c7aa Added and implemented OP_JUMP_(STACK|REGISTER)
Uses the stack and register, respectively, to jump to an absolute
address.  The stack based jump pops a word off the stack to perform a
jump, while the register based one uses the operand to figure out
which register to use.
2023-10-22 20:57:29 +01:00
Aryadev Chavali
d8e45fce04 Removed ret register
Wasn't useful or necessary.
2023-10-22 20:54:29 +01:00
Aryadev Chavali
fffad9aea3 Added and implemented OP_JUMP_ABS
Jumps to the operand given, interpreted as a word, an absolute
address.
2023-10-22 20:54:04 +01:00
Aryadev Chavali
bc0e0fce25 Fixed bug in vm_execute_all, if no OP_HALT then program kept going
This adds a bound on vm_execute_all to stop program->ptr from going
past program->max.
2023-10-22 20:30:17 +01:00
Aryadev Chavali
9da31398ba Implemented vm_* routines for OP_DUP and vm_execute code 2023-10-22 20:30:05 +01:00
Aryadev Chavali
073a23152e Use conversion functions for (h)word to and from bytes instead of bit shifting
Wasn't very secure for endianness, and using these helpers abstracts
the details away a bit in case I want to enforce a certain system.
2023-10-22 20:29:02 +01:00
Aryadev Chavali
aa3d1cb85f Added NUMBER_OF_OPCODES which aids in compilation errors
If I add a new operand I want the build system to be more helpful in
finding the places I need to change to make it work.
2023-10-22 20:28:10 +01:00
Aryadev Chavali
b20ad511a0 Added opcode OP_DUP_*
Duplicates the nth datum off the stack, pushing it to the top.  Useful
for operations such as MOV which eat the stack.
2023-10-22 20:26:17 +01:00
Aryadev Chavali
137a6d3b75 Cleaned up inst.c
Use (H)WORD_SIZE more, added some notes, etc
2023-10-22 20:25:17 +01:00
Aryadev Chavali
d5d37f1264 Functions which convert (h)words to and from bytes
Uses memcpy internally, so we don't need to care about endianness.
2023-10-22 20:23:23 +01:00
Aryadev Chavali
d5d10480fa Simple program which assembles instructions then executes them 2023-10-22 19:33:44 +01:00
Aryadev Chavali
33364fddab Fix bug where accessing byte/hword registers > 8 wouldn't work
This is because we were checking them as if they were word registers.
2023-10-22 19:28:45 +01:00
Aryadev Chavali
36bcd90c81 When VEROBSE flag is set greater than 0, print traces in vm_execute_all
For each cycle, print the cycle and any changes.  We track changes on
the stack by remembering the previous stack pointer.  For registers, I
remember the previous array of registers and do a byte level compare
of the current registers and the remembered ones.

Produces pretty log messages and an easy way to track execution.
2023-10-22 18:07:41 +01:00
Aryadev Chavali
936971c1a3 Changed formats for vm_print_(stack|program)
Easier to read now
2023-10-22 18:07:41 +01:00
Aryadev Chavali
5eb7b6f431 Fix bug where FILE is closed when passing to darr_(write|read) 2023-10-22 18:07:41 +01:00
Aryadev Chavali
5ee9bfaca8 Added flag in base.h, VERBOSE
Will be used to provide traces during program execution or assembly.
2023-10-22 18:07:41 +01:00