nitron

commit 139090ae90db9916ad5e28ef09fbfa45445c94e3

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