Author: mesyeti <mesyeti@mesyeti.uk>
add type definitions and pointers
basic/source/frontend/c89.c | 3 ++ basic/source/lexer.c | 6 +++++ basic/source/lexer.h | 4 ++ basic/source/parser.c | 6 ++++ basic/source/semanticAnalysis.c | 36 ++++++++++++++++++++++++++-------- basic/test.bas | 20 ++++++------------
diff --git a/basic/source/frontend/c89.c b/basic/source/frontend/c89.c index 422a6ce4fb8945257103789f2b856ad2247a0de1..465486d00c13b8885782044dc74308051d9451f3 100644 --- a/basic/source/frontend/c89.c +++ b/basic/source/frontend/c89.c @@ -134,9 +134,12 @@ switch (node->unary.op) { case TOKEN_ADD: fprintf(out, "+"); break; case TOKEN_SUBTRACT: fprintf(out, "-"); break; + case TOKEN_ADDRESS: fprintf(out, "&"); break; + case TOKEN_ACCESS: fprintf(out, "*"); break; default: assert(0); } + CompileExprNode(node->unary.operand); fprintf(out, ")"); break; } diff --git a/basic/source/lexer.c b/basic/source/lexer.c index ff940fc2b707be22ff79e91fa07f5f562395f927..f89957c27c34fce0e6732624e39f333853c991d0 100644 --- a/basic/source/lexer.c +++ b/basic/source/lexer.c @@ -35,6 +35,8 @@ case '=': case '<': case '>': case '\'': + case '^': + case '&': case ';': return true; default: return false; } @@ -125,6 +127,8 @@ return LEXER_TOKEN; } case '<': *token = TOKEN(TOKEN_LESS, NULL); return LEXER_TOKEN; case '>': *token = TOKEN(TOKEN_GREATER, NULL); return LEXER_TOKEN; + case '&': *token = TOKEN(TOKEN_ADDRESS, NULL); return LEXER_TOKEN; + case '^': *token = TOKEN(TOKEN_ACCESS, NULL); return LEXER_TOKEN; case '\n': *token = TOKEN(TOKEN_LINE, NULL); return LEXER_TOKEN; case '\'': { while (true) { @@ -225,6 +229,8 @@ case TOKEN_MOD: return "mod"; case TOKEN_EQUAL: return "equal"; case TOKEN_LESS: return "less"; case TOKEN_GREATER: return "greater"; + case TOKEN_ADDRESS: return "address"; + case TOKEN_ACCESS: return "access"; default: assert(0); } } diff --git a/basic/source/lexer.h b/basic/source/lexer.h index dcc26c65179b83f62e0d450574587b1c93411605..ae41e856addb88076f84857f63faf1732a4e6918 100644 --- a/basic/source/lexer.h +++ b/basic/source/lexer.h @@ -46,7 +46,9 @@ TOKEN_MOD, TOKEN_EQUAL, TOKEN_LESS, TOKEN_GREATER, - TOKEN_ASSIGN + TOKEN_ASSIGN, + TOKEN_ADDRESS, + TOKEN_ACCESS } TokenType; enum { diff --git a/basic/source/parser.c b/basic/source/parser.c index d15c1cc7833cc07e123e42265fc21629e2c56161..7d8deeac160ff733981d06c78d17548c4ef735db 100644 --- a/basic/source/parser.c +++ b/basic/source/parser.c @@ -126,7 +126,9 @@ static bool IsUnaryOperator(Token* tok) { switch (tok->type) { case TOKEN_ADD: - case TOKEN_SUBTRACT: return true; + case TOKEN_SUBTRACT: + case TOKEN_ADDRESS: + case TOKEN_ACCESS: return true; default: return false; } } @@ -645,6 +647,8 @@ case TOKEN_EXTERN: return ParseExtern(p); case TOKEN_IF: return ParseIf(p); case TOKEN_WHILE: return ParseWhile(p); case TOKEN_TYPE: return ParseTypeDef(p); + case TOKEN_LPAREN: + case TOKEN_ACCESS: case TOKEN_IDENTIFIER: { if (p->i == p->tokenNum - 1) { PrintError(p->tokens[p->i].err, "Unexpected EOF"); diff --git a/basic/source/semanticAnalysis.c b/basic/source/semanticAnalysis.c index 86137ff47ad93546256e5e75aeb39d198a306f45..8e98536f94be2c390d139f5f9bcf862b1f8f13d6 100644 --- a/basic/source/semanticAnalysis.c +++ b/basic/source/semanticAnalysis.c @@ -291,17 +291,35 @@ case NODE_UNARY_OP: { UsedType operand = SemanticAnalysis_EvalType(node->unary.operand); Type* type = State_GetTypeFromUsed(operand); - if (type->type != TYPE_PRIM) { - PrintError(node->i.err, - "Only primitive types can be used with unary operators" - ); - } + switch (node->unary.op) { + case TOKEN_ADD: + case TOKEN_SUBTRACT: { + if (type->type != TYPE_PRIM) { + PrintError(node->i.err, + "Only primitive types can be used with the +/- unary operators" + ); + } - if ((type->primType == PRIM_UINT) && (node->unary.op == TOKEN_SUBTRACT)) { - PrintWarning(node->i.err, "Using negative sign on unsigned value"); - } + if (type->primType == PRIM_UINT) { + PrintWarning(node->i.err, "Using negative sign on unsigned value"); + } - return operand; + return operand; + } + case TOKEN_ADDRESS: { + ++ operand.ptr; + return operand; + } + case TOKEN_ACCESS: { + if (operand.ptr <= 0) { + PrintError(node->i.err, "Used access operator on non-pointer type"); + } + + -- operand.ptr; + return operand; + } + default: assert(0); + } } case NODE_PTR: { UsedType type = SemanticAnalysis_EvalType(node->ptr.inner); diff --git a/basic/test.bas b/basic/test.bas index 3068b3bdf95fd46971f33ffeab1e095d2ecb58ac..a5731efea260b2d45a679be8a4c84801d8f33ac6 100644 --- a/basic/test.bas +++ b/basic/test.bas @@ -3,20 +3,14 @@ extern func puts(str as ptr(char)) i32 extern func printf(str as ptr(char), val as int) i32 -type MyStruct - bol as int - polly as int -end - -type MyInt = int +dim foo as int +foo = 5 -dim manul as MyStruct +dim fooPtr as ptr(int) +fooPtr = &foo -manul.bol = 11 -manul.polly = 10 +printf("foo = %d\n", ^fooPtr) -' should work -printf("bol: %d\n", manul.bol) +^fooPtr = 6 -' should also work -printf("polly: %d\n", manul.polly) +printf("foo = %d\n", foo)