Author: mesyeti <mesyeti@mesyeti.uk>
add VM instruction set
activate | 1 basic-std/compile_test.sh | 2 basic-std/examples/hello_world.bas | 14 +++++ basic-std/std/file.bas | 28 +++++++++++ basic-std/std/io.bas | 7 ++ basic-std/std/string.bas | 12 ----- basic-std/test.bas | 4 + basic/source/frontend/c89.c | 8 ++ basic/source/semanticAnalysis.c | 5 + basic/test.bas | 2 build.sh | 5 + | 0 | 0 kernel/source/vm.h | 8 --- lines_of_code.sh | 1 man/vm.md | 76 ++++++++++++++++++++++++++++++++ vm/source/vm.h | 48 ++++++++++++++++++++
diff --git a/activate b/activate index bb7600aca95141d5114975c1fa70e792016f7200..a7802e82599a961eef759699a1e0d48325426249 100644 --- a/activate +++ b/activate @@ -3,3 +3,4 @@ export NITRON="$(realpath out)" export NITRON_BIN="$(realpath out/bin)" export NITRON_LIB="$(realpath out/lib)" export NITRON_SRC="$(realpath out/src)" +export NITRON_MAN="$(realpath out/man)" diff --git a/basic/source/frontend/c89.c b/basic/source/frontend/c89.c index 3fafe168557c18f557f82fa3cffa655951c5d0d9..f07d25118bacb86a265c93539df9771c0343e5d9 100644 --- a/basic/source/frontend/c89.c +++ b/basic/source/frontend/c89.c @@ -1,5 +1,6 @@ #include <stdio.h> #include <assert.h> +#include <string.h> #include "c89.h" #include "../util.h" #include "../state.h" @@ -46,7 +47,12 @@ static void CompileUsedType(UsedType used) { Type* type = State_GetTypeFromUsed(used); - fprintf(out, "nitron_%s", type->name); + if (strcmp(type->name, "unit") == 0) { + fprintf(out, "void"); + } + else { + fprintf(out, "nitron_%s", type->name); + } for (size_t i = 0; i < used.ptr; ++ i) { fprintf(out, "*"); diff --git a/basic/source/semanticAnalysis.c b/basic/source/semanticAnalysis.c index 98268be0227c22f91703d573f47cd89be6f81a75..149285cc63ec92f133572243354fe8751ef5c754 100644 --- a/basic/source/semanticAnalysis.c +++ b/basic/source/semanticAnalysis.c @@ -263,7 +263,10 @@ Type* leftType = State_GetTypeFromUsed(left); Type* rightType = State_GetTypeFromUsed(right); - if ((leftType->type != TYPE_PRIM) || (rightType->type != TYPE_PRIM)) { + if ( + ((left.ptr == 0) && (leftType->type != TYPE_PRIM)) || + ((right.ptr == 0) && (rightType->type != TYPE_PRIM)) + ) { PrintError(node->i.err, "You can only use primitive types in binary expressions"); } diff --git a/basic/test.bas b/basic/test.bas index 97e2e57c6abe01b20032e1dc6f5e3366e8b9c4cc..62cae97c6aa1aae3353f57b20ce0c913d4a6663d 100644 --- a/basic/test.bas +++ b/basic/test.bas @@ -18,3 +18,5 @@ myArray[0] = 4 printf("myArray[0] = %d\n", myArray[0]) printf("127 ^ 4 = %d\n", 127 ^ 4) + +dim foo as ptr(unit) diff --git a/basic-std/compile_test.sh b/basic-std/compile_test.sh index edfe7da131819f21efa83dde1adeaf66063ed4ad..1ee714748d2a199726ca818d521656b8099dad3c 100755 --- a/basic-std/compile_test.sh +++ b/basic-std/compile_test.sh @@ -1,4 +1,4 @@ -nitron-basic test.bas --obj -o test.o +nitron-basic $1 --obj -o test.o if [ $? -ne 0 ]; then exit diff --git a/basic-std/examples/hello_world.bas b/basic-std/examples/hello_world.bas new file mode 100644 index 0000000000000000000000000000000000000000..b4285bfd17e6af9feb9db2b6f8ec6beb3d2090d0 --- /dev/null +++ b/basic-std/examples/hello_world.bas @@ -0,0 +1,14 @@ +'NITRON + +program test + +import std.io + +dim i as int + +while i != 10 do + PrintStr("Hello, world! ") + i = i + 1 +end + +NewLine() diff --git a/basic-std/std/file.bas b/basic-std/std/file.bas new file mode 100644 index 0000000000000000000000000000000000000000..cc31f916f4e4c9f4c10a2ba182ec22cde3cb703d --- /dev/null +++ b/basic-std/std/file.bas @@ -0,0 +1,28 @@ +'NITRON + +extern func fopen(path as ptr(char), mode as ptr(char)) ptr(unit) +extern func fclose(file as ptr(unit)) i32 + +type File + file as ptr(unit) +end + +func File_Open(this as ptr(File), path as ptr(char), write as bool) bool + dim file as ptr(unit) + dim modeStr as ptr(char) + + if write then + modeStr = "wb" + else + modeStr = "rb" + end + + file = fopen(path, modeStr) + + if file != 0 then + return 0 + end + + 'this.file = file + return 1 +end diff --git a/basic-std/std/io.bas b/basic-std/std/io.bas index 8d71472149b19410d55374414f249493717f056f..957c8d97d4e893e5c31555c8646f129f0a0aea79 100644 --- a/basic-std/std/io.bas +++ b/basic-std/std/io.bas @@ -7,7 +7,12 @@ sub PrintChar(ch as char) putchar(ch) end -' TODO: PrintStr +sub PrintStr(str as ptr(char)) + while ^str != 0 do + PrintChar(^str) + str = str + 1 + end +end sub PrintStrLn(str as ptr(char)) puts(str) diff --git a/basic-std/std/string.bas b/basic-std/std/string.bas deleted file mode 100644 index 4e1559e54c2e65a86589a9216d4f5aa32328eb9f..0000000000000000000000000000000000000000 --- a/basic-std/std/string.bas +++ /dev/null @@ -1,12 +0,0 @@ -'NITRON - -func StringLen(str as ptr(char)) int - dim ret as int - - while ^str != 0 do - ret = ret + 1 - str = str + 1 - end - - return ret -end diff --git a/basic-std/test.bas b/basic-std/test.bas index 550eced053f04131f9b32383d8a8ec160d44599b..b4285bfd17e6af9feb9db2b6f8ec6beb3d2090d0 100644 --- a/basic-std/test.bas +++ b/basic-std/test.bas @@ -7,6 +7,8 @@ dim i as int while i != 10 do - PrintStrLn("Hello, world!") + PrintStr("Hello, world! ") i = i + 1 end + +NewLine() diff --git a/build.sh b/build.sh index 3f7a470511e98af545fda00acf9eadeb7400f258..0db8b6bb440c6920a3eb24a874b35aeae3934536 100755 --- a/build.sh +++ b/build.sh @@ -6,6 +6,7 @@ mkdir out mkdir out/bin mkdir out/lib mkdir out/src +cp -r man out/man echo "==================" echo "= BASIC Compiler =" @@ -18,7 +19,7 @@ echo "Compilation failed" exit fi cd .. -mv basic/nitron-basic out/bin/ +cp basic/nitron-basic out/bin/ echo "==================" echo "= BASIC STD =" @@ -34,4 +35,6 @@ cd .. cp basic-std/libstd.a out/lib cp -r basic-std/std out/src +echo "========================" echo "Finished building nitron" +echo "========================" diff --git a/kernel/Makefile b/kernel/Makefile deleted file mode 100644 index 7a6707ef8c225fc324aed07d75c627dc16583acb..0000000000000000000000000000000000000000 --- a/kernel/Makefile +++ /dev/null @@ -1,67 +0,0 @@ -SOURCES := $(wildcard source/*.c) $(wildcard source/**/*.c) -OBJECTS := $(patsubst source/%.c,bin/%.o,$(SOURCES)) -OUT := nitron -LD := $(CC) - -override CFLAGS += -std=c99 -Wall -Wextra -Wuninitialized -Wundef -pedantic -Ilib -m32 -override CFLAGS += -DN_DEVICE_HOST -override LDLIBS += -lm -m32 - -ifeq ($(BUILD),release) - override CFLAGS += -O3 - #override CPPFLAGS += -NDEBUG -else - override CFLAGS += -Og -g - ifeq ($(ASAN), y) - override CFLAGS += -fno-omit-frame-pointer -fsanitize=address - override LDFLAGS += -fsanitize=address - endif - - ifeq ($(SYS_ALLOC), y) - override CFLAGS += -DN_SYS_ALLOC - endif - - ifeq ($(REI_ALLOC), y) - override CFLAGS += -DN_REI_ALLOC - endif -endif - -.SECONDEXPANSION: - -deps.filter := %.c %.h -deps.option := -MM -define deps -$$(filter $$(deps.filter),,$$(shell $(CC) $(CFLAGS) $(CPPFLAGS) -E $(deps.option) $(1))) -endef - -all: $(OUT) - @: - -run: $(OUT) - '$(dir $<)$(notdir $<)' $(RUNFLAGS) - -$(OUT): $(OBJECTS) - $(LD) $(LDFLAGS) $^ $(LDLIBS) -o $@ - -bin/: - mkdir -p bin - -bin/fs: - mkdir -p bin/fs - -bin/disk: - mkdir -p bin/disk - -bin/system: - mkdir -p bin/system - -bin/%.o: source/%.c $(call deps,source/%.c) romfs.h | bin/ bin/fs bin/disk bin/system - $(CC) $(CFLAGS) $(CPPFLAGS) $< -c -o $@ - -clean: - rm -r bin - -distclean: clean - rm $(OUT) - -.PHONY: all run clean distclean diff --git a/kernel/source/common.h b/kernel/source/common.h deleted file mode 100644 index 0f2bbb6733256481d77ba83a8ebb35a04e561748..0000000000000000000000000000000000000000 --- a/kernel/source/common.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef N_COMMON_H -#define N_COMMON_H - -#include <stdint.h> -#include <stdlib.h> - -#endif diff --git a/kernel/source/vm.h b/kernel/source/vm.h deleted file mode 100644 index 299760539cd2593075dc82270addc8b2db860f98..0000000000000000000000000000000000000000 --- a/kernel/source/vm.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef N_VM_H -#define N_VM_H - -typedef struct { - -} VMState; - -#endif diff --git a/lines_of_code.sh b/lines_of_code.sh new file mode 100755 index 0000000000000000000000000000000000000000..52d16fa2f4039ea60b9cb4e4dc2dd02d40feda06 --- /dev/null +++ b/lines_of_code.sh @@ -0,0 +1 @@ +cloc basic/source basic-std/std vm/source diff --git a/man/vm.md b/man/vm.md new file mode 100644 index 0000000000000000000000000000000000000000..11d07f26035fbcb8c3594168948e617fc5ff9d57 --- /dev/null +++ b/man/vm.md @@ -0,0 +1,76 @@ +# Nitron VM +## Instructions +- VM_INST_NOP (`0x00`) + - Does nothing +- VM_INST_ADD (`0x01`) `( a b -- a+b )` + - Adds 2 integers and returns the result +- VM_INST_SUB (`0x02`) `( a b -- a-b )` + - Subtracts 2 integers and returns the result +- VM_INST_MUL (`0x03`) `( a b -- a*b )` + - Multiplies 2 integers and returns the result +- VM_INST_DIV (`0x04`) `( a b -- a/b )` + - Divides 2 integers and returns the result +- VM_INST_MOD (`0x05`) `( a b -- a%b )` + - Divides 2 integers and returns the remainder +- VM_INST_R2D (`0x06`) `r( v -- )` `( -- v)` + - Pops from the return stack and pushes the value to the data stack +- VM_INST_D2R (`0x07`) `r( -- v )` `( v -- )` + - Pops from the data stack and pushes the value to the return stack +- VM_INST_DUP (`0x08`) `( v -- v v )` + - Duplicates the value on the data stack +- VM_INST_OVER (`0x09`) `( a b -- a b a )` + - Duplicates the value below the top element on the data stack +- VM_INST_DROP (`0x0A`) `( v -- )` + - Pops the value at the top of the data stack +- VM_INST_ROT (`0x0B`) `( a b c -- b c a)` + - Rotates the 3 values on top of the data stack +- VM_INST_READ (`0x0C`) `( addr -- v )` + - Reads a 32-bit value from the given address and returns it +- VM_INST_WRITE (`0x0D`) `( v addr -- )` + - Writes the given value to the given address +- VM_INST_JUMP (`0x0E`) `( addr -- )` + - Jumps to the given address +- VM_INST_JNZ (`0x0F`) `( v addr -- )` + - Jumps to the given address if the value below the address is not 0 +- VM_INST_HALT (`0x10`) `( -- )` + - Halts the virtual machine +- VM_INST_SYSCALL (`0x11`) + - Pops the given system call ID and calls it, see system calls section +- VM_INST_REG (`0x12`) `( reg -- v)` + - Returns the value of the given register +- VM_INST_WREG (`0x13`) `( v reg -- )` + - Writes the given value to the given register +- VM_INST_READ8 (`0x14`) `( addr -- v )` + - Reads the 8 bit value from the given address +- VM_INST_WRITE8 (`0x15`) `( v addr -- )` + - Writes the first 8 bits of given value to the given address +- VM_INST_READ16 (`0x16`) `( addr -- v)` + - Reads the 16 bit value from the given address +- VM_INST_WRITE16 (`0x17`) `( v addr --)` + - Writes the first 16 bits of given value to the given address +- VM_INST_JZ (`0x18`) `( v addr -- )` + - Jumps to the given address if the value below that address is not 0 +- VM_INST_EQU (`0x19`) `( a b -- bool )` + - Returns `0xFFFFFFFF` if the given values are equal, 0 if not +- VM_INST_LESS (`0x1A`) `( a b -- bool )` + - Returns `0xFFFFFFFF` if `a` is less than `b`, 0 if not +- VM_INST_GREATER (`0x1B`) `( a b -- bool )` + - Returns `0xFFFFFFFF` if `a` is greater than `b`, 0 if not +- VM_INST_LE (`0x1C`) `( a b -- bool )` + - Returns `0xFFFFFFFF` if `a` is less than or equal to `b`, 0 if not +- VM_INST_GE (`0x1D`) `( a b -- bool )` + - Returns `0xFFFFFFFF` if `a` is greater than or equal to `b`, 0 if not +- VM_INST_AND (`0x1E`) `( a b -- a&b )` + - Performs a bitwise and operation on the given values +- VM_INST_XOR (`0x1F`) `( a b -- a^b )` + - Performs a bitwise exclusive or operation on the given values +- VM_INST_OR (`0x20`) `( a b -- a|b )` + - Performs a bitwise or operation on the given values +- VM_INST_NOT (`0x21`) `( v -- ~v)` + - Performs a bitwise not operation on the given value +- VM_INST_SWAP (`0x22`) `( a b -- b a )` + - Swaps the 2 values on top of the data stack +- VM_INST_CALL (`0x23`) `r( -- caller )` `( addr -- )` + - Pushes the current IP to the return stack, then calls the address on the data stack +- VM_INST_RET (`0x24`) `r( caller -- )` + - Pops the caller address from the return stack, and jumps to it diff --git a/vm/Makefile b/vm/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..7a6707ef8c225fc324aed07d75c627dc16583acb --- /dev/null +++ b/vm/Makefile @@ -0,0 +1,67 @@ +SOURCES := $(wildcard source/*.c) $(wildcard source/**/*.c) +OBJECTS := $(patsubst source/%.c,bin/%.o,$(SOURCES)) +OUT := nitron +LD := $(CC) + +override CFLAGS += -std=c99 -Wall -Wextra -Wuninitialized -Wundef -pedantic -Ilib -m32 +override CFLAGS += -DN_DEVICE_HOST +override LDLIBS += -lm -m32 + +ifeq ($(BUILD),release) + override CFLAGS += -O3 + #override CPPFLAGS += -NDEBUG +else + override CFLAGS += -Og -g + ifeq ($(ASAN), y) + override CFLAGS += -fno-omit-frame-pointer -fsanitize=address + override LDFLAGS += -fsanitize=address + endif + + ifeq ($(SYS_ALLOC), y) + override CFLAGS += -DN_SYS_ALLOC + endif + + ifeq ($(REI_ALLOC), y) + override CFLAGS += -DN_REI_ALLOC + endif +endif + +.SECONDEXPANSION: + +deps.filter := %.c %.h +deps.option := -MM +define deps +$$(filter $$(deps.filter),,$$(shell $(CC) $(CFLAGS) $(CPPFLAGS) -E $(deps.option) $(1))) +endef + +all: $(OUT) + @: + +run: $(OUT) + '$(dir $<)$(notdir $<)' $(RUNFLAGS) + +$(OUT): $(OBJECTS) + $(LD) $(LDFLAGS) $^ $(LDLIBS) -o $@ + +bin/: + mkdir -p bin + +bin/fs: + mkdir -p bin/fs + +bin/disk: + mkdir -p bin/disk + +bin/system: + mkdir -p bin/system + +bin/%.o: source/%.c $(call deps,source/%.c) romfs.h | bin/ bin/fs bin/disk bin/system + $(CC) $(CFLAGS) $(CPPFLAGS) $< -c -o $@ + +clean: + rm -r bin + +distclean: clean + rm $(OUT) + +.PHONY: all run clean distclean diff --git a/vm/source/common.h b/vm/source/common.h new file mode 100644 index 0000000000000000000000000000000000000000..0f2bbb6733256481d77ba83a8ebb35a04e561748 --- /dev/null +++ b/vm/source/common.h @@ -0,0 +1,7 @@ +#ifndef N_COMMON_H +#define N_COMMON_H + +#include <stdint.h> +#include <stdlib.h> + +#endif diff --git a/vm/source/vm.h b/vm/source/vm.h new file mode 100644 index 0000000000000000000000000000000000000000..6ec93f406c712d7acfb6e938dbd573a0dcf28af9 --- /dev/null +++ b/vm/source/vm.h @@ -0,0 +1,48 @@ +#ifndef N_VM_H +#define N_VM_H + +enum { + VM_INST_NOP = 0x00, + VM_INST_ADD = 0x01, + VM_INST_SUB = 0x02, + VM_INST_MUL = 0x03, + VM_INST_DIV = 0x04, + VM_INST_MOD = 0x05, + VM_INST_R2D = 0x06, + VM_INST_D2R = 0x07, + VM_INST_DUP = 0x08, + VM_INST_OVER = 0x09, + VM_INST_DROP = 0x0A, + VM_INST_ROT = 0x0B, + VM_INST_READ = 0x0C, + VM_INST_WRITE = 0x0D, + VM_INST_JUMP = 0x0E, + VM_INST_JNZ = 0x0F, + VM_INST_HALT = 0x10, + VM_INST_SYSCALL = 0x11, + VM_INST_REG = 0x12, + VM_INST_WREG = 0x13, + VM_INST_READ8 = 0x14, + VM_INST_WRITE8 = 0x15, + VM_INST_READ16 = 0x16, + VM_INST_WRITE16 = 0x17, + VM_INST_JZ = 0x18, + VM_INST_EQU = 0x19, + VM_INST_LESS = 0x1A, + VM_INST_GREATER = 0x1B, + VM_INST_LE = 0x1C, + VM_INST_GE = 0x1D, + VM_INST_AND = 0x1E, + VM_INST_XOR = 0x1F, + VM_INST_OR = 0x20, + VM_INST_NOT = 0x21, + VM_INST_SWAP = 0x22, + VM_INST_CALL = 0x23, + VM_INST_RET = 0x24 +}; + +typedef struct { + +} VMState; + +#endif