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 {