nitron

commit a497566a7254922beb55e0a218d318be1482ce86

Author: mesyeti <mesyeti@mesyeti.uk>

add private (untested)

 basic/source/lexer.c | 1 
 basic/source/lexer.h | 1 
 basic/source/parser.c | 59 +++++++++++++++++++++++-----
 basic/source/parser.h | 7 +++
 basic/source/semanticAnalysis.c | 71 +++++++++++++++++++++-------------
 basic/source/semanticAnalysis.h | 2 
 basic/source/state.c | 9 ++++
 basic/source/state.h | 3 +


diff --git a/basic/source/lexer.c b/basic/source/lexer.c
index 2986ed79bb635f290b2027d788d3c4237f4b5f8f..7710c99a03dc3b4634e9ef6b3e32fdf3b4012206 100644
--- a/basic/source/lexer.c
+++ b/basic/source/lexer.c
@@ -246,6 +246,7 @@ 		case TOKEN_NOT:         return "not";
 		case TOKEN_AND:         return "and";
 		case TOKEN_OR:          return "or";
 		case TOKEN_CONST:       return "const";
+		case TOKEN_PRIVATE:     return "private";
 		case TOKEN_IDENTIFIER:  return "identifier";
 		case TOKEN_STRING:      return "string";
 		case TOKEN_INT:         return "int";




diff --git a/basic/source/lexer.h b/basic/source/lexer.h
index a3ffa1c3ec96c91d1ac64d5dece90bd07e6c647a..ca68a1372327c1732ad60053afc078459e2334f3 100644
--- a/basic/source/lexer.h
+++ b/basic/source/lexer.h
@@ -31,6 +31,7 @@ 	TOKEN_NOT,
 	TOKEN_AND,
 	TOKEN_OR,
 	TOKEN_CONST,
+	TOKEN_PRIVATE,
 
 	// misc
 	TOKEN_IDENTIFIER,




diff --git a/basic/source/parser.c b/basic/source/parser.c
index 659863a3a28de7bf5e7ce9f963427f2931bcb678..f15b59aace8614f6b523e1fed08807c68800e203 100644
--- a/basic/source/parser.c
+++ b/basic/source/parser.c
@@ -39,6 +39,7 @@ 	tokens       = SafeRealloc(tokens, tokensLen * sizeof(Token));
 	ret.tokens   = tokens;
 	ret.tokenNum = tokensLen;
 	ret.i        = 0;
+	ret.private  = false;
 
 	if (printTokens) {
 		for (size_t i = 0; i < tokensLen; ++ i) {
@@ -475,9 +476,12 @@ }
 
 static Node ParseFuncDef(Parser* p) {
 	FuncDefNode ret;
-	ret.i   = INFO(NODE_FUNC_DEF);
-	ret.dec = ParseFuncDec(p);
+	ret.i       = INFO(NODE_FUNC_DEF);
+	ret.dec     = ParseFuncDec(p);
+	ret.private = p->private;
 	Advance(p);
+
+	p->private = false;
 
 	ret.body = ParseBody(p, &ret.bodyLen);
 	Expect(p, TOKEN_END);
@@ -492,7 +496,10 @@ }
 
 static Node ParseDim(Parser* p) {
 	DimNode ret;
-	ret.i = INFO(NODE_DIM);
+	ret.i       = INFO(NODE_DIM);
+	ret.private = p->private;
+
+	p->private = false;
 
 	Advance(p);
 	Expect(p, TOKEN_IDENTIFIER);
@@ -572,8 +579,11 @@ static Node ParseExtern(Parser* p) {
 	Advance(p);
 
 	ExternNode ret;
-	ret.i   = INFO(NODE_EXTERN);
-	ret.dec = ParseFuncDec(p);
+	ret.i       = INFO(NODE_EXTERN);
+	ret.dec     = ParseFuncDec(p);
+	ret.private = p->private;
+
+	p->private = false;
 
 	Node node;
 	node.external = ret;
@@ -659,6 +669,9 @@ 	return node;
 }
 
 static Node ParseTypeDef(Parser* p) {
+	bool private = p->private;
+	p->private = false;
+
 	Advance(p);
 
 	char* name;
@@ -671,9 +684,10 @@ 	if (p->tokens[p->i].type == TOKEN_ASSIGN) {
 		Advance(p);
 
 		TypeDefNode ret;
-		ret.i    = INFO(NODE_TYPE_DEF);
-		ret.name = name;
-		ret.type = NodeToHeap(ParseType(p));
+		ret.i       = INFO(NODE_TYPE_DEF);
+		ret.name    = name;
+		ret.type    = NodeToHeap(ParseType(p));
+		ret.private = private;
 
 		if (ret.type->i.type == NODE_PTR) {
 			PrintError(p->tokens[p->i].err, "Cannot use pointer for type definition");
@@ -688,8 +702,9 @@ 		return node;
 	}
 
 	TypeBlockNode ret;
-	ret.i    = INFO(NODE_TYPE_BLOCK);
-	ret.name = name;
+	ret.i       = INFO(NODE_TYPE_BLOCK);
+	ret.name    = name;
+	ret.private = private;
 
 	if (p->tokens[p->i].type == TOKEN_UNION) {
 		ret.isUnion = true;
@@ -789,7 +804,10 @@ }
 
 static Node ParseConst(Parser* p) {
 	ConstNode ret;
-	ret.i = INFO(NODE_CONST);
+	ret.i       = INFO(NODE_CONST);
+	ret.private = p->private;
+
+	p->private = false;
 
 	Advance(p);
 	Expect(p, TOKEN_IDENTIFIER);
@@ -813,6 +831,20 @@ 	Node ret;
 
 	switch (p->tokens[p->i].type) {
 		case TOKEN_FUNC:
+		case TOKEN_SUB:
+		case TOKEN_DIM:
+		case TOKEN_EXTERN:
+		case TOKEN_TYPE:
+		case TOKEN_CONST: break;
+		default: {
+			if (p->private) {
+				PrintError(p->tokens[p->i].err, "Invalid use of `private`");
+			}
+		}
+	}
+
+	switch (p->tokens[p->i].type) {
+		case TOKEN_FUNC:
 		case TOKEN_SUB:     ret = ParseFuncDef(p); break;
 		case TOKEN_DIM:     ret = ParseDim(p);     break;
 		case TOKEN_EXTERN:  ret = ParseExtern(p);  break;
@@ -823,6 +855,11 @@ 		case TOKEN_PROGRAM: ret = ParseProgram(p); break;
 		case TOKEN_IMPORT:  ret = ParseImport(p);  break;
 		case TOKEN_RETURN:  ret = ParseReturn(p);  break;
 		case TOKEN_CONST:   ret = ParseConst(p);   break;
+		case TOKEN_PRIVATE: {
+			p->private = true;
+			Advance(p);
+			break;
+		}
 		case TOKEN_LPAREN:
 		case TOKEN_ACCESS_XOR:
 		case TOKEN_IDENTIFIER: {




diff --git a/basic/source/parser.h b/basic/source/parser.h
index 70071ca547155ac1acd6bdec1151188d0665a9e9..b229eb5f9040b0c692cedfd91b979ac38f13626d 100644
--- a/basic/source/parser.h
+++ b/basic/source/parser.h
@@ -87,6 +87,7 @@ 	NodeInfo i;
 	FuncDec  dec;
 	Node*    body;
 	size_t   bodyLen;
+	bool     private;
 } FuncDefNode;
 
 typedef struct {
@@ -95,6 +96,7 @@ 	char*    name;
 	Node*    varType;
 	bool     array;
 	Node*    arrayLen;
+	bool     private;
 } DimNode;
 
 typedef struct {
@@ -106,6 +108,7 @@
 typedef struct {
 	NodeInfo i;
 	FuncDec  dec;
+	bool     private;
 } ExternNode;
 
 typedef struct {
@@ -128,6 +131,7 @@ typedef struct {
 	NodeInfo i;
 	char*    name;
 	Node*    type;
+	bool     private;
 } TypeDefNode;
 
 typedef struct {
@@ -141,6 +145,7 @@ 	char*           name;
 	bool            isUnion;
 	TypeBlockField* fields;
 	size_t          fieldsNum;
+	bool            private;
 } TypeBlockNode;
 
 typedef struct {
@@ -163,6 +168,7 @@ typedef struct {
 	NodeInfo i;
 	char*    name;
 	Node*    value;
+	bool     private;
 } ConstNode;
 
 union Node {
@@ -191,6 +197,7 @@ typedef struct {
 	Token* tokens;
 	size_t tokenNum;
 	size_t i;
+	bool   private;
 } Parser;
 
 Parser Parser_Init(FILE* file, const char* fileName, bool printTokens);




diff --git a/basic/source/semanticAnalysis.c b/basic/source/semanticAnalysis.c
index fcccab2144310a0cd934e5417fceff18c952f89f..0503c2ea998ae49ab59f321063fd2255f928fcc5 100644
--- a/basic/source/semanticAnalysis.c
+++ b/basic/source/semanticAnalysis.c
@@ -9,12 +9,13 @@ #include "semanticAnalysis.h"
 
 static Function* thisFunc = NULL;
 static size_t    wordSize;
+static bool      external;
 
 #define GET_PRIM(NAME, PTR) \
 	((UsedType) {(PTR), State_GetType(NAME) - state.types, 0, false})
 
 #define NEW_VAR(TYPE, NAME, PTR, STATIC) \
-	((Var) {GET_PRIM(TYPE, PTR), NAME, STATIC})
+	((Var) {GET_PRIM(TYPE, PTR), NAME, STATIC, false})
 
 void SemanticAnalysis_Init(size_t p_wordSize) {
 	wordSize = p_wordSize;
@@ -49,16 +50,24 @@
 	thisFunc = NULL;
 }
 
-void Expect(Node* node, NodeType type) {
-	if (node->i.type != type) {
-		PrintError(node->i.err,
-			"Expected %s, got %s", Parser_TypeStr(type),
-			Parser_TypeStr(node->i.type)
-		);
-	}
+void SemanticAnalysis_SetExternal(bool p_external) {
+	external = p_external;
 }
 
-void Unexpected(Node* node) {
+bool SemanticAnalysis_GetExternal(void) {
+	return external;
+}
+
+// static void Expect(Node* node, NodeType type) {
+// 	if (node->i.type != type) {
+// 		PrintError(node->i.err,
+// 			"Expected %s, got %s", Parser_TypeStr(type),
+// 			Parser_TypeStr(node->i.type)
+// 		);
+// 	}
+// }
+
+static void Unexpected(Node* node) {
 	PrintError(node->i.err, "Unexpected %s", Parser_TypeStr(node->i.type));
 }
 
@@ -587,10 +596,11 @@ 			Function func = DecToFunc(node->funcDef.dec);
 
  			// create type for this function
  			Type type;
- 			type.type = TYPE_FUNC;
- 			type.name = NULL;
- 			type.size = (size_t) -1;
- 			type.func = func;
+ 			type.type    = TYPE_FUNC;
+ 			type.name    = NULL;
+ 			type.size    = (size_t) -1;
+ 			type.func    = func;
+ 			type.private = external && node->funcDef.private;
 
  			size_t funcTypeIdx = State_AddType(type);
 
@@ -624,8 +634,9 @@ 			return GET_PRIM("unit", 0);
 		}
 		case NODE_DIM: {
 			Var var;
-			var.type = SemanticAnalysis_NodeAsUsedType(node->dim.varType);
-			var.name = NewString(node->dim.name);
+			var.type    = SemanticAnalysis_NodeAsUsedType(node->dim.varType);
+			var.name    = NewString(node->dim.name);
+			var.private = external && node->dim.private;
 
 			if (node->dim.array) {
 				if (node->dim.arrayLen->i.type != NODE_INT) {
@@ -645,14 +656,15 @@ 			if (inFunc) {
 				PrintError(node->i.err, "Nested function definitions are not allowed");
 			}
 
-			Function func = DecToFunc(node->funcDef.dec);
+			Function func = DecToFunc(node->external.dec);
 
  			// create type for this function
  			Type type;
- 			type.type = TYPE_FUNC;
- 			type.name = NULL;
- 			type.size = (size_t) -1;
- 			type.func = func;
+ 			type.type    = TYPE_FUNC;
+ 			type.name    = NULL;
+ 			type.size    = (size_t) -1;
+ 			type.func    = func;
+ 			type.private = external && node->external.private;
 
  			size_t funcTypeIdx = State_AddType(type);
 
@@ -712,8 +724,9 @@ 			if (!from) {
 				PrintError(node->i.err, "Type '%s' does not exist", fromName);
 			}
 
-			Type newType = *from;
-			newType.name = NewString(node->typeDef.name);
+			Type newType    = *from;
+			newType.name    = NewString(node->typeDef.name);
+			newType.private = external && node->typeDef.private;
 			State_AddType(newType);
 
 			return GET_PRIM("unit", 0);
@@ -724,9 +737,10 @@ 				PrintError(node->i.err, "Type '%s' already exists", node->typeBlock.name);
 			}
 
 			Type newType;
-			newType.type = TYPE_STRUCT;
-			newType.name = NewString(node->typeBlock.name);
-			newType.size = 0;
+			newType.type    = TYPE_STRUCT;
+			newType.name    = NewString(node->typeBlock.name);
+			newType.size    = 0;
+			newType.private = external && node->typeBlock.private;
 
 			newType.structure = SafeMalloc(node->typeBlock.fieldsNum * sizeof(TypeField));
 			newType.structLen = node->typeBlock.fieldsNum;
@@ -761,9 +775,10 @@ 				PrintError(node->i.err, "Constant value must be integer");
 			}
 
 			Const constant;
-			constant.type  = GET_PRIM("__lit", 0);
-			constant.name  = NewString(node->constant.name);
-			constant.value = (long long) node->constant.value->integer.value;
+			constant.type    = GET_PRIM("__lit", 0);
+			constant.name    = NewString(node->constant.name);
+			constant.value   = (long long) node->constant.value->integer.value;
+			constant.private = external && node->constant.private;
 
 			State_AddConst(constant);
 			return GET_PRIM("unit", 0);




diff --git a/basic/source/semanticAnalysis.h b/basic/source/semanticAnalysis.h
index b6b03e78938a703a3ad6b14b48db10a91cc0ee84..fa71914d6c6fdc586a04863ddd641af975bfb8bf 100644
--- a/basic/source/semanticAnalysis.h
+++ b/basic/source/semanticAnalysis.h
@@ -4,6 +4,8 @@
 #include "common.h"
 
 void SemanticAnalysis_Init(size_t wordSize);
+void SemanticAnalysis_SetExternal(bool p_external);
+bool SemanticAnalysis_GetExternal(void);
 void SemanticAnalysis_Analyse(Node* node);
 
 UsedType SemanticAnalysis_NodeAsUsedType(Node* node);




diff --git a/basic/source/state.c b/basic/source/state.c
index 407217d8c0262973793fc4d43c2a4d9ebe5c5ce7..fbf8a1d569ff6be04318d6976fbc0597d532f29a 100644
--- a/basic/source/state.c
+++ b/basic/source/state.c
@@ -67,6 +67,8 @@
 Var* State_GetVar(const char* name) {
 	for (size_t i = state.scopeNum; i --> 0;) {
 		for (size_t j = 0; j < state.scopeSize[i]; ++ j) {
+			if (!SemanticAnalysis_GetExternal() && state.scopes[i][j].private) continue;
+
 			if (strcmp(state.scopes[i][j].name, name) == 0) {
 				return &state.scopes[i][j];
 			}
@@ -78,6 +80,8 @@ }
 
 Const* State_GetConst(const char* name) {
 	for (size_t i = 0; i < state.constNum; ++ i) {
+		if (!SemanticAnalysis_GetExternal() && state.consts[i].private) continue;
+
 		if (strcmp(state.consts[i].name, name) == 0) {
 			return &state.consts[i];
 		}
@@ -89,6 +93,7 @@
 Type* State_GetType(const char* name) {
 	for (size_t i = 0; i < state.typeNum; ++ i) {
 		if (!state.types[i].name) continue;
+		if (!SemanticAnalysis_GetExternal() && state.types[i].private) continue;
 
 		if (strcmp(state.types[i].name, name) == 0) {
 			return &state.types[i];
@@ -156,8 +161,12 @@ 	size_t len;
 	Node*  nodes = Parser_Parse(&parser, &len);
 
 	for (size_t i = 0; i < len; ++ i) {
+		SemanticAnalysis_SetExternal(true);
+
 		SemanticAnalysis_EvalType(&nodes[i]);
 	}
+
+	SemanticAnalysis_SetExternal(false);
 
 	for (size_t i = 0; i < len; ++ i) {
 		Parser_FreeNode(&nodes[i]);




diff --git a/basic/source/state.h b/basic/source/state.h
index f7d32e3f1a1dd34bcbab2ae4f26064b6e7e86e89..a5991d02ce0172c20f09458bf1296cde3ab23917 100644
--- a/basic/source/state.h
+++ b/basic/source/state.h
@@ -47,6 +47,7 @@ typedef struct {
 	int    type;
 	char*  name;
 	size_t size;
+	bool   private;
 
 	// TODO: put the stuff below into a union
 
@@ -65,12 +66,14 @@ typedef struct {
 	UsedType type;
 	char*    name;
 	bool     isStatic;
+	bool     private;
 } Var;
 
 typedef struct {
 	UsedType  type;
 	char*     name;
 	long long value;
+	bool      private;
 } Const;
 
 typedef struct {