diff --git a/intrinsic.c b/intrinsic.c index 40b48e8..baf1fe6 100644 --- a/intrinsic.c +++ b/intrinsic.c @@ -2,12 +2,6 @@ #include #include "picoc.h" -#define NUM_INTRINSICS 3 - -Str IntrinsicFilename = { 9, "intrinsic" }; -struct Value IntrinsicValue[NUM_INTRINSICS]; -int IntrinsicReferenceNo[NUM_INTRINSICS]; - void IntrinsicPrintInt(void) { printf("%d\n", Parameter[0]->Val->Integer); @@ -36,35 +30,17 @@ struct IntrinsicFunction void IntrinsicInit(struct Table *GlobalTable) { - struct LexState Lexer; - Str Source; + struct ParseState Parser; int Count; - Str Identifier; - struct ValueType *Typ; + const char *Identifier; + struct ValueType *ReturnType; + struct Value *NewValue; for (Count = 0; Count < sizeof(Intrinsics) / sizeof(struct IntrinsicFunction); Count++) { - LexInit(&Lexer, Intrinsics[Count].Prototype, strlen(Source.Str), &IntrinsicFilename, Count+1); - TypeParse(&Lexer, &Typ, &Identifier); - IntrinsicReferenceNo[Count] = -1 - Count; - IntrinsicValue[Count].Typ = &FunctionType; - IntrinsicValue[Count].Val = (union AnyValue *)&IntrinsicReferenceNo[Count]; - IntrinsicValue[Count].ValOnHeap = FALSE; - IntrinsicValue[Count].ValOnStack = FALSE; - TableSet(GlobalTable, &Identifier, &IntrinsicValue[Count]); + LexInit(&Parser, Intrinsics[Count].Prototype, strlen(Intrinsics[Count].Prototype), "", Count+1); + TypeParse(&Parser, &ReturnType, &Identifier); + NewValue = ParseFunctionDefinition(&Parser, ReturnType, Identifier, TRUE); + NewValue->Val->FuncDef.Intrinsic = Intrinsics[Count].Func; } } - -void IntrinsicGetLexer(struct LexState *Lexer, int IntrinsicId) -{ - Lexer->Line = -IntrinsicId; - Lexer->Pos = Intrinsics[-1-IntrinsicId].Prototype; - Lexer->End = Lexer->Pos + strlen(Lexer->Pos); - Lexer->FileName = &IntrinsicFilename; -} - -void IntrinsicCall(struct LexState *Lexer, struct Value *Result, struct ValueType *ReturnType, int IntrinsicId) -{ - Intrinsics[-1-IntrinsicId].Func(); - Result->Typ = &VoidType; -} diff --git a/parse.c b/parse.c index dd6feb0..201f018 100644 --- a/parse.c +++ b/parse.c @@ -360,7 +360,7 @@ int ParseIntExpression(struct ParseState *Parser, int RunIt) } /* parse a function definition and store it for later */ -void ParseFunctionDefinition(struct ParseState *Parser, struct ValueType *ReturnType, Str *Identifier) +struct Value *ParseFunctionDefinition(struct ParseState *Parser, struct ValueType *ReturnType, const char *Identifier, int IsProtoType) { struct ValueType *ParamTyp; Str Identifier; @@ -401,16 +401,21 @@ void ParseFunctionDefinition(struct ParseState *Parser, struct ValueType *Return ProgramFail(ParamParser, "comma expected"); } - if (LexGetToken(Parser, NULL, FALSE) != TokenLeftBrace) - ProgramFail(Parser, "bad function definition"); - - if (!ParseStatement(Parser, FALSE)) - ProgramFail(Parser, "function definition expected"); - - FuncValue->Val->FuncDef.Body.End = Parser->Pos; + if (!IsPrototype) + { + if (LexGetToken(Parser, NULL, FALSE) != TokenLeftBrace) + ProgramFail(Parser, "bad function definition"); + + if (!ParseStatement(Parser, FALSE)) + ProgramFail(Parser, "function definition expected"); + FuncValue->Val->FuncDef.Body.End = Parser->Pos; + } + if (!TableSet(&GlobalTable, Identifier, FuncValue)) ProgramFail(Parser, "'%S' is already defined", Identifier); + + return FuncValue; } /* parse a #define macro definition and store it for later */ @@ -572,7 +577,7 @@ int ParseStatement(struct ParseState *Parser, int RunIt) /* handle function definitions */ if (LexGetToken(Parser, NULL, FALSE) == TokenOpenBracket) - ParseFunctionDefinition(Parser, &Typ, &Identifier); + ParseFunctionDefinition(Parser, &Typ, &Identifier, FALSE); else VariableDefine(Parser, &Identifier, VariableAllocValueFromType(Parser, Typ, FALSE)); break; diff --git a/picoc.c b/picoc.c index f7f1c96..3f1daf5 100644 --- a/picoc.c +++ b/picoc.c @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -32,7 +33,7 @@ char *ReadFile(const char *FileName) if (stat(FileName, &FileInfo)) ProgramFail(NULL, "can't read file %s\n", FileName); - ReadText = HeapAlloc(FileInfo.st_size); + ReadText = HeapAlloc(FileInfo.st_size + 1); if (ReadText == NULL) ProgramFail(NULL, "out of memory\n"); @@ -43,6 +44,7 @@ char *ReadFile(const char *FileName) if (fread(ReadText, 1, FileInfo.st_size, InFile) != FileInfo.st_size) ProgramFail(NULL, "can't read file %s\n", FileName); + ReadText[FileInfo.st_size] = '\0'; fclose(InFile); return ReadText; @@ -52,7 +54,7 @@ char *ReadFile(const char *FileName) void ScanFile(const char *FileName) { char *SourceStr = ReadFile(FileName); - Parse(FileName, SourceStr, TRUE); + Parse(FileName, SourceStr, strlen(SourceStr), TRUE); HeapFree(SourceStr); } diff --git a/picoc.h b/picoc.h index 6141960..c847529 100644 --- a/picoc.h +++ b/picoc.h @@ -153,9 +153,17 @@ struct Value /* hash table data structure */ struct TableEntry { - const char *Key; - struct Value *Val; - struct TableEntry *Next; + struct TableEntry *Next; /* next item in this hash chain */ + union TableEntryPayload + { + struct ValueEntry + { + const char *Key; /* points to the shared string table */ + struct Value *Val; /* the value we're storing */ + } v; /* used for tables of values */ + + const char Key[1]; /* dummy size - used for the shared string table */ + } p; }; struct Table @@ -208,6 +216,7 @@ void ParseInit(void); int ParseExpression(struct ParseState *Parser, struct Value **Result, int ResultOnHeap, int RunIt); int ParseIntExpression(struct ParseState *Parser, int RunIt); int ParseStatement(struct ParseState *Parser, int RunIt); +struct Value *ParseFunctionDefinition(struct ParseState *Parser, struct ValueType *ReturnType, const char *Identifier, int IsProtoType); void Parse(const char *FileName, const char *Source, int SourceLen, int RunIt); /* type.c */ @@ -217,8 +226,6 @@ void TypeParse(struct ParseState *Parser, struct ValueType **Typ, const char **I /* intrinsic.c */ void IntrinsicInit(struct Table *GlobalTable); -void IntrinsicGetLexer(struct ParseState *Parser, int IntrinsicId); -void IntrinsicCall(struct ParseState *Parser, struct Value *Result, struct ValueType *ReturnType, int IntrinsicId); /* heap.c */ void HeapInit();