Author: mesyeti <mesyeti@mesyeti.uk>
hello world achieved
basic/.gitignore | 2 basic/Makefile | 5 basic/example.bas | 6 basic/source/compiler.c | 80 ++++++++++++ basic/source/compiler.h | 34 +++++ basic/source/frontend/c89.c | 222 +++++++++++++++++++++++++++++++++++ basic/source/frontend/c89.h | 8 + basic/source/main.c | 5 basic/source/parser.c | 64 ++++++--- basic/source/parser.h | 9 + basic/source/semanticAnalysis.c | 94 ++++++++------ basic/source/semanticAnalysis.h | 3 basic/source/state.c | 4 basic/source/state.h | 1 basic/test.bas | 19 --
diff --git a/basic/.gitignore b/basic/.gitignore index 631d23f7093ec4d51a6bf2ededb3b33c0630dd30..b90a85c211481d2cb7ba7b0a32c146c7ad776785 100644 --- a/basic/.gitignore +++ b/basic/.gitignore @@ -1 +1,3 @@ nitronb +out +out.c diff --git a/basic/Makefile b/basic/Makefile index 785906776db0027224492a1270d26eb186a99c75..50851ae95c50284161fc2542734b430db4db7734 100644 --- a/basic/Makefile +++ b/basic/Makefile @@ -37,7 +37,10 @@ bin/: mkdir -p bin -bin/%.o: source/%.c $(call deps,source/%.c) | bin/ +bin/frontend: + mkdir -p bin/frontend + +bin/%.o: source/%.c $(call deps,source/%.c) | bin/ bin/frontend $(CC) $(CFLAGS) $(CPPFLAGS) $< -c -o $@ clean: diff --git a/basic/example.bas b/basic/example.bas index 2267bac07513ff4c398f934c27ab667969854ed0..3f5370765d92e62b5eed64bb0c6a601a4b0ce3da 100644 --- a/basic/example.bas +++ b/basic/example.bas @@ -1,10 +1,8 @@ 'NITRON -extern C func puts(ptr(char)) int +extern func puts(str as ptr(char)) int puts "Hello, world!" dim ret as int -ret = puts("Hello again, world!") - -quit ret +ret = 4 diff --git a/basic/source/compiler.c b/basic/source/compiler.c new file mode 100644 index 0000000000000000000000000000000000000000..6ac6c1818c1a418820ccbb9af6385a2f98a33589 --- /dev/null +++ b/basic/source/compiler.c @@ -0,0 +1,80 @@ +#include "compiler.h" + +static Frontend frontend; +static Compiler compiler; + +void Frontend_Init(Frontend p_frontend) { + frontend = p_frontend; +} + +void Frontend_Finish(void) { + frontend.finish(); +} + +void Frontend_BeginMain(void) { + frontend.beginMain(); +} + +void Frontend_CompileFuncDef(FuncDefNode* node) { + frontend.compileFuncDef(node); +} + +void Frontend_CompileDim(DimNode* node) { + frontend.compileDim(node); +} + +void Frontend_CompileFuncCall(FuncCallNode* node) { + frontend.compileFuncCall(node); +} + +void Frontend_CompileAssign(AssignNode* node) { + frontend.compileAssign(node); +} + +void Frontend_CompileExtern(ExternNode* node) { + frontend.compileExtern(node); +} + +void Compiler_Init(Node* nodes, size_t len) { + compiler.nodes = nodes; + compiler.len = len; +} + +void Compiler_Compile(Node* node, bool inMain) { + if (inMain) { + switch (node->i.type) { + case NODE_FUNC_DEF: break; + case NODE_DIM: break; + case NODE_FUNC_CALL: Frontend_CompileFuncCall(&node->funcCall); break; + case NODE_ASSIGN: Frontend_CompileAssign(&node->assign); break; + case NODE_EXTERN: Frontend_CompileExtern(&node->external); break; + default: { + PrintError(node->i.err, "Unexpected '%s'", Parser_TypeStr(node->i.type)); + } + } + } + else { + switch (node->i.type) { + case NODE_FUNC_DEF: Frontend_CompileFuncDef(&node->funcDef); break; + case NODE_DIM: Frontend_CompileDim(&node->dim); break; + default: break; + } + } +} + +void Compiler_Run(void) { + for (size_t i = 0; i < compiler.len; ++ i) { + Node* node = &compiler.nodes[i]; + Compiler_Compile(node, false); + } + + Frontend_BeginMain(); + + for (size_t i = 0; i < compiler.len; ++ i) { + Node* node = &compiler.nodes[i]; + + Compiler_Compile(node, true); + } + + Frontend_Finish(); +} diff --git a/basic/source/compiler.h b/basic/source/compiler.h new file mode 100644 index 0000000000000000000000000000000000000000..6d00872338df8c25bdd2f28c73284b786324b51a --- /dev/null +++ b/basic/source/compiler.h @@ -0,0 +1,34 @@ +#ifndef N_COMPILER_H +#define N_COMPILER_H + +#include "parser.h" + +typedef struct { + void (*finish)(void); + void (*beginMain)(void); + void (*compileFuncDef)(FuncDefNode* node); + void (*compileDim)(DimNode* node); + void (*compileFuncCall)(FuncCallNode* node); + void (*compileAssign)(AssignNode* node); + void (*compileExtern)(ExternNode* node); +} Frontend; + +void Frontend_Init(Frontend p_frontend); +void Frontend_Finish(void); +void Frontend_BeginMain(void); +void Frontend_CompileFuncDef(FuncDefNode* node); +void Frontend_CompileDim(DimNode* node); +void Frontend_CompileFuncCall(FuncCallNode* node); +void Frontend_CompileAssign(AssignNode* node); +void Frontend_CompileExtern(ExternNode* node); + +typedef struct { + Node* nodes; + size_t len; +} Compiler; + +void Compiler_Init(Node* nodes, size_t len); +void Compiler_Compile(Node* node, bool inMain); +void Compiler_Run(void); + +#endif diff --git a/basic/source/frontend/c89.c b/basic/source/frontend/c89.c new file mode 100644 index 0000000000000000000000000000000000000000..1cf6d655b1c753f97e829db8fe88c95d50529ef8 --- /dev/null +++ b/basic/source/frontend/c89.c @@ -0,0 +1,222 @@ +#include <stdio.h> +#include <assert.h> +#include "c89.h" +#include "../state.h" +#include "../semanticAnalysis.h" + +static FILE* out; +static bool inMain; + +static void Finish(void) { + fprintf(out, "}\n"); + fflush(out); + + const char* cmd = "gcc out.c -o out"; + puts(cmd); + system(cmd); +} + +static void BeginMain(void) { + inMain = true; + + fprintf(out, "int main(int argc, char** argv) {\n"); +} + +static void Unexpected(ErrorInfo err, NodeType type) { + PrintError(err, "Unexpected '%s'", Parser_TypeStr(type)); +} + +static void CompileUsedType(UsedType used) { + Type* type = State_GetTypeFromUsed(used); + + fprintf(out, "nitron_%s", type->name); + + for (size_t i = 0; i < used.ptr; ++ i) { + fprintf(out, "*"); + } +} + +static void CompileType(Node* node) { + UsedType used = SemanticAnalysis_NodeAsUsedType(node); + CompileUsedType(used); +} + +static void CompileDec(FuncDec dec) { + if (dec.ret) { + CompileType(dec.ret); + fprintf(out, " "); + } + else { + fprintf(out, "void "); + } + + fprintf(out, "%s(", dec.name); + + for (size_t i = 0; i < dec.paramsNum; ++ i) { + CompileType(dec.params[i].type); + fprintf(out, " %s", dec.params[i].name); + + if (i < dec.paramsNum - 1) { + fprintf(out, ", "); + } + } + + fprintf(out, ")"); +} + +static void CompileFuncDef(FuncDefNode* node) { + CompileDec(node->dec); + fprintf(out, " {\n"); + + for (size_t i = 0; i < node->bodyLen; ++ i) { + Compiler_Compile(&node->body[i], false); + } + + fprintf(out, "}\n"); +} + +static void CompileDim(DimNode* node) { + if (inMain) return; + + CompileType(node->varType); + fprintf(out, " nitron_%s;\n", node->name); +} + +static void CompileExprNode(Node* node); + +static void CompileFuncCallExpr(FuncCallNode* node) { + fprintf(out, "%s(", node->func); + + for (size_t i = 0; i < node->paramsNum; ++ i) { + CompileExprNode(&node->params[i]); + + if (i < node->paramsNum - 1){ + fprintf(out, ", "); + } + } + + fprintf(out, ")"); +} + +static void CompileExprNode(Node* node) { + switch (node->i.type) { + case NODE_INT: fprintf(out, "%d", node->integer.value); break; + case NODE_STRING: fprintf(out, "\"%s\"", node->string.value); break; + case NODE_IDENTIFIER: fprintf(out, "nitron_%s", node->ident.name); break; + case NODE_BINARY_OP: { + fprintf(out, "("); + CompileExprNode(node->bin.left); + + switch (node->bin.op) { + case TOKEN_ADD: fprintf(out, "+"); break; + case TOKEN_SUBTRACT: fprintf(out, "-"); break; + case TOKEN_MULTIPLY: fprintf(out, "*"); break; + case TOKEN_DIVIDE: fprintf(out, "/"); break; + case TOKEN_MOD: fprintf(out, "%%"); break; + case TOKEN_EQUAL: fprintf(out, "=="); break; + case TOKEN_LESS: fprintf(out, "<"); break; + case TOKEN_GREATER: fprintf(out, ">"); break; + default: assert(0); + } + + CompileExprNode(node->bin.right); + fprintf(out, ")"); + break; + } + case NODE_UNARY_OP: { + fprintf(out, "("); + + switch (node->unary.op) { + case TOKEN_ADD: fprintf(out, "+"); break; + case TOKEN_SUBTRACT: fprintf(out, "-"); break; + default: assert(0); + } + + fprintf(out, ")"); + break; + } + case NODE_FUNC_CALL: CompileFuncCallExpr(&node->funcCall); break; + default: assert(0); + } +} + +static void CompileFuncCall(FuncCallNode* node) { + CompileFuncCallExpr(node); + fprintf(out, ";\n"); +} + +static void CompileAssign(AssignNode* node) { + +} + +static void CompileExtern(ExternNode* node) { + CompileDec(node->dec); + fprintf(out, ";\n"); +} + +static void CompilePrim(Type* type) { + switch (type->primType) { + case PRIM_UINT: { + switch (type->size) { + case 1: fprintf(out, "typedef uint8_t nitron_%s;\n", type->name); break; + case 2: fprintf(out, "typedef uint16_t nitron_%s;\n", type->name); break; + case 4: fprintf(out, "typedef uint32_t nitron_%s;\n", type->name); break; + case 8: fprintf(out, "typedef uint64_t nitron_%s;\n", type->name); break; + } + break; + } + case PRIM_INT: { + switch (type->size) { + case 1: fprintf(out, "typedef int8_t nitron_%s;\n", type->name); break; + case 2: fprintf(out, "typedef int16_t nitron_%s;\n", type->name); break; + case 4: fprintf(out, "typedef int32_t nitron_%s;\n", type->name); break; + case 8: fprintf(out, "typedef int64_t nitron_%s;\n", type->name); break; + } + break; + } + case PRIM_FLOAT: { + switch (type->size) { + case 4: fprintf(out, "typedef float nitron_%s;\n", type->name); break; + case 8: fprintf(out, "typedef double nitron_%s;\n", type->name); break; + } + break; + } + } +} + +Frontend Frontend_C89(void) { + out = fopen("out.c", "w"); + inMain = false; + + fprintf(out, "#include <stdint.h>\n"); + fprintf(out, "#include <stdlib.h>\n"); + + // define all types + for (size_t i = 0; i < state.typeNum; ++ i) { + Type* type = &state.types[i]; + + switch (type->type) { + case TYPE_PRIM: CompilePrim(type); break; + case TYPE_UNIT: break; + default: assert(0); + } + } + + // declare all globals + for (size_t i = 0; i < state.scopeSize[0]; ++ i) { + Var* var = &state.scopes[0][i]; + + CompileUsedType(var->type); + fprintf(out, " nitron_%s;\n", var->name); + } + + return (Frontend) { + .finish = &Finish, + .beginMain = &BeginMain, + .compileFuncDef = &CompileFuncDef, + .compileDim = &CompileDim, + .compileFuncCall = &CompileFuncCall, + .compileAssign = &CompileAssign, + .compileExtern = &CompileExtern + }; +} diff --git a/basic/source/frontend/c89.h b/basic/source/frontend/c89.h new file mode 100644 index 0000000000000000000000000000000000000000..6edada43c8f3f07c258e762f901b999433737a98 --- /dev/null +++ b/basic/source/frontend/c89.h @@ -0,0 +1,8 @@ +#ifndef N_FRONTEND_C89_H +#define N_FRONTEND_C89_H + +#include "../compiler.h" + +Frontend Frontend_C89(void); + +#endif diff --git a/basic/source/main.c b/basic/source/main.c index a8e3fa95d0afaa3a9ac44b0c75f86f336a150b30..6c2baa46efe19dc613bea1c4f69f295514d9fa0a 100644 --- a/basic/source/main.c +++ b/basic/source/main.c @@ -5,6 +5,7 @@ #include "state.h" #include "parser.h" #include "common.h" #include "semanticAnalysis.h" +#include "frontend/c89.h" int main(int argc, char** argv) { const char* source = NULL; @@ -70,7 +71,9 @@ for (size_t i = 0; i < len; ++ i){ SemanticAnalysis_Analyse(&ret[i]); } - State_DumpInfo(); + Compiler_Init(ret, len); + Frontend_Init(Frontend_C89()); + Compiler_Run(); return 0; } diff --git a/basic/source/parser.c b/basic/source/parser.c index 2ae234724509cccb38c4a2cc5db7aacef610e5c1..d8fe1957fdb7a916fb3bef3758776721086b4de5 100644 --- a/basic/source/parser.c +++ b/basic/source/parser.c @@ -428,11 +428,24 @@ node.assign = ret; return node; } +static Node ParseExtern(Parser* p) { + Advance(p); + + ExternNode ret; + ret.i = INFO(NODE_EXTERN); + ret.dec = ParseFuncDec(p); + + Node node; + node.external = ret; + return node; +} + static Node ParseNode(Parser* p) { switch (p->tokens[p->i].type) { case TOKEN_FUNC: - case TOKEN_SUB: return ParseFuncDef(p); - case TOKEN_DIM: return ParseDim(p); + case TOKEN_SUB: return ParseFuncDef(p); + case TOKEN_DIM: return ParseDim(p); + case TOKEN_EXTERN: return ParseExtern(p); case TOKEN_IDENTIFIER: { if (p->i == p->tokenNum - 1) { PrintError(p->tokens[p->i].err, "Unexpected EOF"); @@ -454,6 +467,28 @@ } } } +static void PrintDec(FuncDec dec) { + if (dec.ret) { + printf("func "); + } + else { + printf("sub "); + } + + printf("%s(", dec.name); + + for (size_t i = 0; i < dec.paramsNum; ++ i) { + printf("%s as ", dec.params[i].name); + Parser_PrintNode(dec.params[i].type); + + if (i < dec.paramsNum - 1) { + printf(", "); + } + } + + printf(")\n"); +} + void Parser_PrintNode(Node* node) { switch (node->i.type) { case NODE_INT: printf("%d", node->integer.value); break; @@ -498,25 +533,7 @@ Parser_PrintNode(node->ptr.inner); break; } case NODE_FUNC_DEF: { - if (node->funcDef.dec.ret) { - printf("func "); - } - else { - printf("sub "); - } - - printf("%s(", node->funcDef.dec.name); - - for (size_t i = 0; i < node->funcDef.dec.paramsNum; ++ i) { - printf("%s as ", node->funcDef.dec.params[i].name); - Parser_PrintNode(node->funcDef.dec.params[i].type); - - if (i < node->funcDef.dec.paramsNum - 1) { - printf(", "); - } - } - - printf(")\n"); + PrintDec(node->funcDef.dec); for (size_t i = 0; i < node->funcDef.bodyLen; ++ i) { printf("\t"); @@ -549,6 +566,11 @@ case NODE_ASSIGN: { printf("%s = ", node->assign.variable); Parser_PrintNode(node->assign.rValue); puts(""); + break; + } + case NODE_EXTERN: { + printf("extern "); + PrintDec(node->external.dec); break; } default: { diff --git a/basic/source/parser.h b/basic/source/parser.h index 9e643df70c4de70613cbcd791b17f86efca21126..2a3183738fdda807fa4471325c70c89e02a7ce9b 100644 --- a/basic/source/parser.h +++ b/basic/source/parser.h @@ -16,7 +16,8 @@ NODE_PTR, NODE_FUNC_DEF, NODE_DIM, NODE_FUNC_CALL, - NODE_ASSIGN + NODE_ASSIGN, + NODE_EXTERN } NodeType; typedef struct { @@ -97,6 +98,11 @@ char* variable; Node* rValue; } AssignNode; +typedef struct { + NodeInfo i; + FuncDec dec; +} ExternNode; + union Node { NodeInfo i; IntNode integer; @@ -109,6 +115,7 @@ FuncDefNode funcDef; DimNode dim; FuncCallNode funcCall; AssignNode assign; + ExternNode external; }; typedef struct { diff --git a/basic/source/semanticAnalysis.c b/basic/source/semanticAnalysis.c index c275153bb71bcc85fc06e2e5a9372f795796eb04..7a6ca3ddc77eca434ebfe3d4384815fc9c2fbe7f 100644 --- a/basic/source/semanticAnalysis.c +++ b/basic/source/semanticAnalysis.c @@ -46,7 +46,7 @@ void Unexpected(Node* node) { PrintError(node->i.err, "Unexpected %s", Parser_TypeStr(node->i.type)); } -static UsedType NodeAsUsedType(Node* node) { +UsedType SemanticAnalysis_NodeAsUsedType(Node* node) { UsedType ret; ret.ptr = 0; ret.array = false; // no arrays yet @@ -76,21 +76,15 @@ } } } -static Type* GetTypeFromUsed(UsedType type) { - return &state.types[type.typeIdx]; -} - #define GET_PRIM(NAME, PTR) \ ((UsedType) {(PTR), State_GetType(NAME) - state.types, 0}) -static UsedType EvalType(Node* node); - static UsedType EvalBinOp(Node* node) { - UsedType left = EvalType(node->bin.left); - UsedType right = EvalType(node->bin.right); + UsedType left = SemanticAnalysis_EvalType(node->bin.left); + UsedType right = SemanticAnalysis_EvalType(node->bin.right); - Type* leftType = GetTypeFromUsed(left); - Type* rightType = GetTypeFromUsed(right); + Type* leftType = State_GetTypeFromUsed(left); + Type* rightType = State_GetTypeFromUsed(right); if ((leftType->type != TYPE_PRIM) || (rightType->type != TYPE_PRIM)) { PrintError(node->i.err, "You can only use primitive types in binary expressions"); @@ -198,7 +192,29 @@ exit(1); } -static UsedType EvalType(Node* node) { +static Function DecToFunc(FuncDec dec) { + Function func; + func.sub = dec.ret != NULL; + + if (!func.sub) { + func.ret = SemanticAnalysis_NodeAsUsedType(dec.ret); + } + + func.paramsLen = dec.paramsNum; + func.params = SafeMalloc(func.paramsLen * sizeof(FuncParam)); + + for (size_t i = 0; i < func.paramsLen; ++ i) { + func.params[i].type = SemanticAnalysis_NodeAsUsedType( + dec.params[i].type + ); + func.params[i].name = dec.params[i].name; + } + + func.name = NewString(dec.name); + return func; +} + +UsedType SemanticAnalysis_EvalType(Node* node) { static bool inFunc = false; switch (node->i.type) { @@ -217,8 +233,8 @@ return var->type; } case NODE_BINARY_OP: return EvalBinOp(node); case NODE_UNARY_OP: { - UsedType operand = EvalType(node->unary.operand); - Type* type = GetTypeFromUsed(operand); + UsedType operand = SemanticAnalysis_EvalType(node->unary.operand); + Type* type = State_GetTypeFromUsed(operand); if (type->type != TYPE_PRIM) { PrintError(node->i.err, @@ -233,7 +249,7 @@ return operand; } case NODE_PTR: { - UsedType type = EvalType(node->ptr.inner); + UsedType type = SemanticAnalysis_EvalType(node->ptr.inner); ++ type.ptr; return type; } @@ -242,24 +258,7 @@ if (inFunc) { PrintError(node->i.err, "Nested function definitions are not allowed"); } - Function func; - func.sub = node->funcDef.dec.ret != NULL; - - if (!func.sub) { - func.ret = NodeAsUsedType(node->funcDef.dec.ret); - } - - func.paramsLen = node->funcDef.dec.paramsNum; - func.params = SafeMalloc(func.paramsLen * sizeof(FuncParam)); - - for (size_t i = 0; i < func.paramsLen; ++ i) { - func.params[i].type = NodeAsUsedType( - node->funcDef.dec.params[i].type - ); - func.params[i].name = node->funcDef.dec.params[i].name; - } - - func.name = NewString(node->funcDef.dec.name); + Function func = DecToFunc(node->funcDef.dec); State_AddFunc(func); // now analyse the body @@ -275,7 +274,7 @@ State_AddVar(var); } for (size_t i = 0; i < node->funcDef.bodyLen; ++ i) { - EvalType(&node->funcDef.body[i]); + SemanticAnalysis_EvalType(&node->funcDef.body[i]); } inFunc = false; State_FreeScope(); @@ -295,10 +294,10 @@ ); } for (size_t i = 0; i < func->paramsLen; ++ i) { - UsedType type = EvalType(&node->funcCall.params[i]); + UsedType type = SemanticAnalysis_EvalType(&node->funcCall.params[i]); UsedType param = func->params[i].type; - Type* paramType = GetTypeFromUsed(param); - Type* callType = GetTypeFromUsed(type); + Type* paramType = State_GetTypeFromUsed(param); + Type* callType = State_GetTypeFromUsed(type); bool paramLit = strcmp(callType->name, "__lit") == 0; @@ -329,7 +328,7 @@ } } case NODE_DIM: { Var var; - var.type = NodeAsUsedType(node->dim.varType); + var.type = SemanticAnalysis_NodeAsUsedType(node->dim.varType); var.name = NewString(node->dim.name); State_AddVar(var); return GET_PRIM("unit", 0); @@ -345,10 +344,10 @@ ); } UsedType left = var->type; - UsedType right = EvalType(node->assign.rValue); + UsedType right = SemanticAnalysis_EvalType(node->assign.rValue); - Type* leftType = GetTypeFromUsed(left); - Type* rightType = GetTypeFromUsed(right); + Type* leftType = State_GetTypeFromUsed(left); + Type* rightType = State_GetTypeFromUsed(right); bool compatible = true; @@ -363,12 +362,21 @@ if (!compatible) { PrintError( node->i.err, "Type '%s' cannot be assigned to '%s' variable", - GetTypeFromUsed(left)->name, GetTypeFromUsed(right)->name + State_GetTypeFromUsed(left)->name, State_GetTypeFromUsed(right)->name ); } return GET_PRIM("unit", 0); } + case NODE_EXTERN: { + if (inFunc) { + PrintError(node->i.err, "Nested function definitions are not allowed"); + } + + Function func = DecToFunc(node->funcDef.dec); + State_AddFunc(func); + return GET_PRIM("unit", 0); + } default: { Unexpected(node); } @@ -378,5 +386,5 @@ assert(0); } void SemanticAnalysis_Analyse(Node* node) { - EvalType(node); + SemanticAnalysis_EvalType(node); } diff --git a/basic/source/semanticAnalysis.h b/basic/source/semanticAnalysis.h index 341ccb8ac4a96ebcd1d94b58b4aad9fa914a881e..b6b03e78938a703a3ad6b14b48db10a91cc0ee84 100644 --- a/basic/source/semanticAnalysis.h +++ b/basic/source/semanticAnalysis.h @@ -6,4 +6,7 @@ void SemanticAnalysis_Init(size_t wordSize); void SemanticAnalysis_Analyse(Node* node); +UsedType SemanticAnalysis_NodeAsUsedType(Node* node); +UsedType SemanticAnalysis_EvalType(Node* node); + #endif diff --git a/basic/source/state.c b/basic/source/state.c index c2d901ca81d47638cf32a652631f8562859bda74..e3af9ad34f6183431adfe58cb1b6f1f8a5882b05 100644 --- a/basic/source/state.c +++ b/basic/source/state.c @@ -125,3 +125,7 @@ printf("- %s\n", state.funcs[i].name); } puts("\n"); } + +Type* State_GetTypeFromUsed(UsedType type) { + return &state.types[type.typeIdx]; +} diff --git a/basic/source/state.h b/basic/source/state.h index bff6a6faeea769784107c85cb53b3b8e1e1da066..fcdc210ea2c966a5ad728911dd116899fd68d4b9 100644 --- a/basic/source/state.h +++ b/basic/source/state.h @@ -76,5 +76,6 @@ Function* State_GetFunc(const char* name); void State_MakePrimitive(const char* name, size_t size, int primType); bool State_UsedTypeEq(UsedType a, UsedType b); void State_DumpInfo(void); +Type* State_GetTypeFromUsed(UsedType type); #endif diff --git a/basic/test.bas b/basic/test.bas index af13a8b74c4cbcb49dd5ac303c39c0578ebf48fb..f8cce0e700c79dff0671a0cf3685cc543aeb28fe 100644 --- a/basic/test.bas +++ b/basic/test.bas @@ -1,20 +1,5 @@ 'NITRON -dim foo as int - -func manul(foo as int, bar as int) int - dim bar as u32 -end +extern func puts(str as ptr(char)) int -manul 1, (2 * 3) + -5 * 4 - -foo = 3 + 4 - -dim a as int -dim b as f32 -dim c as int - -manul a + c, 5 - -dim myPtr as ptr(int) -myPtr = myPtr * 5 +puts "Hello, world!"