nitron

commit 6a7d06ea3f9f03681291871f2bc4e69ff58e64ee

Author: mesyeti <mesyeti@mesyeti.uk>

reading file

 basic-std/std/heap.bas | 17 +++++++++++++++++
 basic-std/std/stringView.bas | 26 ++++++++++++++++++++------
 basic-std/test.bas | 19 ++++++++++++++++++-
 basic/source/frontend/c89.c | 4 ++++
 basic/source/lexer.c | 30 ++++++++++++++++++++++++++++--
 basic/source/lexer.h | 2 ++
 basic/source/parser.c | 9 +++++++--
 basic/source/semanticAnalysis.c | 17 ++++++++++++-----


diff --git a/basic/source/frontend/c89.c b/basic/source/frontend/c89.c
index b6f8241ece46e2b7b2e5693fa703fd3be7e81623..b6a60463bca17e61aa9322e3d8c23b9e5f3798c9 100644
--- a/basic/source/frontend/c89.c
+++ b/basic/source/frontend/c89.c
@@ -159,6 +159,8 @@
 		if (node->paramsNum > 0) {
 			fprintf(out, ", ");
 		}
+
+		isMethod = false;
 	}
 
 	for (size_t i = 0; i < node->paramsNum; ++ i) {
@@ -270,6 +272,8 @@ 				case TOKEN_MOD:         fprintf(out, "%%"); break;
 				case TOKEN_EQUAL:       fprintf(out, "=="); break;
 				case TOKEN_LESS:        fprintf(out, "<");  break;
 				case TOKEN_GREATER:     fprintf(out, ">");  break;
+				case TOKEN_LESS_EQ:     fprintf(out, "<="); break;
+				case TOKEN_GREATER_EQ:  fprintf(out, ">="); break;
 				case TOKEN_ASSIGN:      fprintf(out, "=");  break;
 				case TOKEN_NOT_EQUAL:   fprintf(out, "!="); break;
 				case TOKEN_ACCESS_XOR:  fprintf(out, "^");  break;




diff --git a/basic/source/lexer.c b/basic/source/lexer.c
index 9dacb830df350ef14cb009a9bf64f5e3169af130..fcd317d3b96cbb7932fb6286fafa9d302c48a193 100644
--- a/basic/source/lexer.c
+++ b/basic/source/lexer.c
@@ -152,8 +152,32 @@ 				fseek(lexer->file, -1, SEEK_CUR);
 			}
 			return LEXER_TOKEN;
 		}
-		case '<':  *token = TOKEN(TOKEN_LESS,        NULL); return LEXER_TOKEN;
-		case '>':  *token = TOKEN(TOKEN_GREATER,     NULL); return LEXER_TOKEN;
+		case '<': {
+			char next;
+			GET_CHAR(next);
+
+			if (next == '=') {
+				*token = TOKEN(TOKEN_LESS_EQ, NULL);
+			}
+			else {
+				*token = TOKEN(TOKEN_LESS, NULL);
+			}
+
+			return LEXER_TOKEN;
+		}
+		case '>': {
+			char next;
+			GET_CHAR(next);
+
+			if (next == '=') {
+				*token = TOKEN(TOKEN_LESS_EQ, NULL);
+			}
+			else {
+				*token = TOKEN(TOKEN_GREATER, NULL);
+			}
+
+			return LEXER_TOKEN;
+		}
 		case '&':  *token = TOKEN(TOKEN_ADDRESS_AND, NULL); return LEXER_TOKEN;
 		case '^':  *token = TOKEN(TOKEN_ACCESS_XOR,  NULL); return LEXER_TOKEN;
 		case '\n': *token = TOKEN(TOKEN_LINE,        NULL); return LEXER_TOKEN;
@@ -278,6 +302,8 @@ 		case TOKEN_MOD:         return "mod";
 		case TOKEN_EQUAL:       return "equal";
 		case TOKEN_LESS:        return "less";
 		case TOKEN_GREATER:     return "greater";
+		case TOKEN_LESS_EQ:     return "less than or equal to";
+		case TOKEN_GREATER_EQ:  return "greater than or equal to";
 		case TOKEN_ASSIGN:      return "assign";
 		case TOKEN_ACCESS_XOR:  return "access/bitwise xor";
 		case TOKEN_ADDRESS_AND: return "address/bitwise and";




diff --git a/basic/source/lexer.h b/basic/source/lexer.h
index ca68a1372327c1732ad60053afc078459e2334f3..7e6488dfbfb0bf21475ad5addb5a5bf9fc1c1eab 100644
--- a/basic/source/lexer.h
+++ b/basic/source/lexer.h
@@ -56,6 +56,8 @@ 	TOKEN_MOD,
 	TOKEN_EQUAL,
 	TOKEN_LESS,
 	TOKEN_GREATER,
+	TOKEN_LESS_EQ,
+	TOKEN_GREATER_EQ,
 	TOKEN_ASSIGN,
 	TOKEN_ACCESS_XOR,
 	TOKEN_ADDRESS_AND,




diff --git a/basic/source/parser.c b/basic/source/parser.c
index ee4549af9e4ec1e7962645e7a354c1ac55ab8f2c..54968bc0ca55a294511b4c0183103ef4d3df004a 100644
--- a/basic/source/parser.c
+++ b/basic/source/parser.c
@@ -284,13 +284,16 @@
 	return left;
 }
 
+static Node ParseType(Parser* p);
+
 static Node ParseCast(Parser* p) {
 	Node left = ParseBitwise(p);
 
 	while (p->tokens[p->i].type == TOKEN_AS) {
 		TokenType op = p->tokens[p->i].type;
 		Advance(p);
-		Node right = ParseBitwise(p);
+		Node right = ParseType(p);
+		Advance(p);
 
 		Node* leftPtr  = SafeMalloc(sizeof(Node));
 		Node* rightPtr = SafeMalloc(sizeof(Node));
@@ -312,7 +315,9 @@ 	while (
 		(p->tokens[p->i].type == TOKEN_EQUAL) ||
 		(p->tokens[p->i].type == TOKEN_LESS) ||
 		(p->tokens[p->i].type == TOKEN_GREATER) ||
-		(p->tokens[p->i].type == TOKEN_NOT_EQUAL)
+		(p->tokens[p->i].type == TOKEN_NOT_EQUAL) ||
+		(p->tokens[p->i].type == TOKEN_LESS_EQ) ||
+		(p->tokens[p->i].type == TOKEN_GREATER_EQ)
 	) {
 		TokenType op = p->tokens[p->i].type;
 		Advance(p);




diff --git a/basic/source/semanticAnalysis.c b/basic/source/semanticAnalysis.c
index 9efabd2fb2d98d781cb045fb12a6bd1bf4f3d41e..c1f50cea692fc5f7310006ff9200896b1320c462 100644
--- a/basic/source/semanticAnalysis.c
+++ b/basic/source/semanticAnalysis.c
@@ -352,8 +352,10 @@ 			switch (node->bin.op) {
 				case TOKEN_EQUAL:
 				case TOKEN_NOT_EQUAL:
 				case TOKEN_LESS:
-				case TOKEN_GREATER: return GET_PRIM("bool", 0);
-				case TOKEN_SUB:     return GET_PRIM("uint", 0);
+				case TOKEN_GREATER:
+				case TOKEN_LESS_EQ:
+				case TOKEN_GREATER_EQ: return GET_PRIM("bool", 0);
+				case TOKEN_SUB:        return GET_PRIM("uint", 0);
 				default: {
 					PrintError(
 						node->i.err, "Operation '%s' not allowed here",
@@ -424,9 +426,11 @@ 	}
 	else if (!right.ptr) {
 		switch (node->bin.op) {
 			case TOKEN_NOT_EQUAL:
-			case TOKEN_EQUAL: return GET_PRIM("bool", 0);
+			case TOKEN_EQUAL:
 			case TOKEN_LESS:
-			case TOKEN_GREATER: {
+			case TOKEN_GREATER:
+			case TOKEN_LESS_EQ:
+			case TOKEN_GREATER_EQ: {
 				if ((leftType->type != TYPE_PRIM) || (rightType->type != TYPE_PRIM)) {
 					PrintError(
 						node->i.err, "Operation '%s' only works on primitives",
@@ -447,7 +451,10 @@ 						Lexer_TypeVAsString(node->bin.op)
 					);
 				}
 
-				if (leftType->primType == rightType->primType) {
+				if (
+					(leftType->primType == rightType->primType) || (leftType->size == 0) ||
+					(rightType->size == 0)
+				) {
 					if (leftType->size > rightType->size) {
 						return left;
 					}




diff --git a/basic-std/std/heap.bas b/basic-std/std/heap.bas
new file mode 100644
index 0000000000000000000000000000000000000000..15710a45efe83cf7a4957f2ef68706010f4363fa
--- /dev/null
+++ b/basic-std/std/heap.bas
@@ -0,0 +1,17 @@
+'NITRON
+
+private extern func malloc(size as uint) ptr(unit)
+private extern func realloc(addr as ptr(unit), size as uint) ptr(unit)
+private extern sub  free(addr as ptr(unit))
+
+func Alloc(size as uint) ptr(unit)
+	return malloc(size)
+end
+
+func ReAlloc(addr as ptr(unit), size as uint) ptr(unit)
+	return realloc(addr, size)
+end
+
+sub Free(addr as ptr(unit))
+	free(addr)
+end




diff --git a/basic-std/std/stringView.bas b/basic-std/std/stringView.bas
index a426ab61411e71c12d77d3e6e51552ebf61c0092..497707ddc1081360227ffa119b77e8b13a790feb 100644
--- a/basic-std/std/stringView.bas
+++ b/basic-std/std/stringView.bas
@@ -7,11 +7,25 @@ 	string as ptr(char)
 	length as uint
 end
 
-const U8_1_BYTE_MASK 0x80
-const U8_2_BYTE_MASK 0xE0
-const U8_3_BYTE_MASK 0xF0
-const U8_4_BYTE_MASK 0xF8
+sub StringView_FromNTStr(this as ptr(StringView), string as ptr(char))
+	this.string = string
+	this.length = 0
 
-private func CPLength(cp as ptr(char)) uint
-	
+	while ^string != 0 do
+		this.length = this.length + 1
+		string      = string + 1
+	end
+end
+
+func StringView_Get(this as ptr(StringView), index as uint) Char
+	if index >= this.length then
+		' TODO: error
+		return 0
+	end
+
+	return this.string[index] as u32
+end
+
+func StringView_Length(this as ptr(StringView)) uint
+	return this.length
 end




diff --git a/basic-std/test.bas b/basic-std/test.bas
index 33e3ab3fd8da94275ecbc55df911105da664ec1d..88750300f26c5506342ac580d54a7442556fe783 100644
--- a/basic-std/test.bas
+++ b/basic-std/test.bas
@@ -4,8 +4,25 @@ program test
 
 import std.io
 import std.file
+import std.heap
 
 dim file as File
+dim size as uint
+
+file.Open("test.bas", false)
+file.Seek(SEEK_END, 0)
+size = file.Peek()
+file.Seek(SEEK_SET, 0)
+
+dim contents as ptr(char)
+contents = Alloc(size) as ptr(char)
 
-file.Open("std/file.bas", false)
+if ((contents as ptr(unit)) == null) then
+	PrintStrLn("Failed to allocate contents")
+end
+
+file.Read(size, contents as ptr(unit))
+
+PrintStr(contents)
+
 file.Close()