Intrinsic functions implemented
git-svn-id: http://picoc.googlecode.com/svn/trunk@25 21eae674-98b7-11dd-bd71-f92a316d2d60
This commit is contained in:
parent
bf0fe101e5
commit
939c68cd4d
2
Makefile
2
Makefile
|
@ -3,7 +3,7 @@ CFLAGS=-Wall -g
|
|||
LIBS=-lm
|
||||
|
||||
TARGET = picoc
|
||||
SRCS = picoc.c table.c str.c parse.c lex.c
|
||||
SRCS = picoc.c table.c str.c parse.c lex.c intrinsic.c
|
||||
OBJS := $(SRCS:%.c=%.o)
|
||||
|
||||
all: $(TARGET)
|
||||
|
|
62
intrinsic.c
Normal file
62
intrinsic.c
Normal file
|
@ -0,0 +1,62 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "picoc.h"
|
||||
|
||||
Str IntrinsicFilename = { 9, "intrinsic" };
|
||||
|
||||
void IntrinsicPrintf(void)
|
||||
{
|
||||
printf("IntrinsicPrintf\n");
|
||||
}
|
||||
|
||||
void IntrinsicSayHello(void)
|
||||
{
|
||||
printf("Hello\n");
|
||||
}
|
||||
|
||||
struct IntrinsicFunction
|
||||
{
|
||||
void (*Func)(void);
|
||||
const char *Prototype;
|
||||
} Intrinsics[] =
|
||||
{
|
||||
{ IntrinsicSayHello, "void sayhello()" }, /* -1 */
|
||||
{ IntrinsicPrintf, "void printf()" }, /* -2 */
|
||||
};
|
||||
|
||||
void IntrinsicInit(struct Table *GlobalTable)
|
||||
{
|
||||
struct Value FuncVal;
|
||||
struct LexState Lexer;
|
||||
Str Source;
|
||||
int Count;
|
||||
union AnyValue Identifier;
|
||||
enum ValueType Typ;
|
||||
|
||||
FuncVal.Typ = TypeFunction;
|
||||
for (Count = 0; Count < sizeof(Intrinsics) / sizeof(struct IntrinsicFunction); Count++)
|
||||
{
|
||||
Source.Str = Intrinsics[Count].Prototype;
|
||||
Source.Len = strlen(Source.Str);
|
||||
LexInit(&Lexer, &Source, &IntrinsicFilename, Count+1);
|
||||
ParseType(&Lexer, &Typ);
|
||||
LexGetToken(&Lexer, &Identifier);
|
||||
FuncVal.Val.Integer = -1 - Count;
|
||||
TableSet(GlobalTable, &Identifier.String, &FuncVal);
|
||||
}
|
||||
}
|
||||
|
||||
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, enum ValueType ReturnType, int IntrinsicId)
|
||||
{
|
||||
Intrinsics[-1-IntrinsicId].Func();
|
||||
Result->Typ = TypeVoid;
|
||||
}
|
||||
|
22
parse.c
22
parse.c
|
@ -31,6 +31,7 @@ int ParseArguments(struct LexState *Lexer, int RunIt);
|
|||
void ParseInit()
|
||||
{
|
||||
TableInit(&GlobalTable, &GlobalHashTable[0], GLOBAL_TABLE_SIZE);
|
||||
IntrinsicInit(&GlobalTable);
|
||||
}
|
||||
|
||||
/* define a variable */
|
||||
|
@ -43,7 +44,7 @@ void VariableDefine(struct LexState *Lexer, const Str *Ident, struct Value *Init
|
|||
/* get the value of a variable. must be defined */
|
||||
void VariableGet(struct LexState *Lexer, Str *Ident, struct Value *Val, struct Value **LVal)
|
||||
{
|
||||
if (!TableGet(&Stack[StackUsed-1].LocalTable, Ident, LVal))
|
||||
if (StackUsed == 0 || !TableGet(&Stack[StackUsed-1].LocalTable, Ident, LVal))
|
||||
{
|
||||
if (!TableGet(&GlobalTable, Ident, LVal))
|
||||
ProgramFail(Lexer, "'%S' is undefined", Ident);
|
||||
|
@ -150,16 +151,25 @@ void ParseFunctionCall(struct LexState *Lexer, struct Value *Result, Str *FuncNa
|
|||
ProgramFail(Lexer, "not a function - can't call");
|
||||
|
||||
StackFrameAdd(Lexer);
|
||||
FuncLexer = FunctionStore[Result->Val.Integer];
|
||||
if (Result->Val.Integer >= 0)
|
||||
FuncLexer = FunctionStore[Result->Val.Integer];
|
||||
else
|
||||
IntrinsicGetLexer(&FuncLexer, Result->Val.Integer);
|
||||
|
||||
ParseType(&FuncLexer, &ReturnType); /* return type */
|
||||
Result->Typ = TypeVoid;
|
||||
LexGetPlainToken(&FuncLexer); /* function name again */
|
||||
ParseParameterList(Lexer, &FuncLexer, TRUE); /* parameters */
|
||||
if (LexPeekPlainToken(&FuncLexer) != TokenLeftBrace || !ParseStatement(&FuncLexer, TRUE))
|
||||
ProgramFail(&FuncLexer, "function body expected");
|
||||
if (Result->Val.Integer >= 0)
|
||||
{
|
||||
if (LexPeekPlainToken(&FuncLexer) != TokenLeftBrace || !ParseStatement(&FuncLexer, TRUE))
|
||||
ProgramFail(&FuncLexer, "function body expected");
|
||||
|
||||
if (ReturnType != Result->Typ)
|
||||
ProgramFail(&FuncLexer, "bad return value");
|
||||
if (ReturnType != Result->Typ)
|
||||
ProgramFail(&FuncLexer, "bad return value");
|
||||
}
|
||||
else
|
||||
IntrinsicCall(Lexer, Result, ReturnType, Result->Val.Integer);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
8
picoc.h
8
picoc.h
|
@ -159,6 +159,8 @@ struct StackFrame
|
|||
struct TableEntry LocalHashTable[LOCAL_TABLE_SIZE];
|
||||
};
|
||||
|
||||
/* globals */
|
||||
extern struct Table GlobalTable;
|
||||
|
||||
/* str.c */
|
||||
void StrToC(char *Dest, int DestSize, const Str *Source);
|
||||
|
@ -188,6 +190,12 @@ enum LexToken LexPeekPlainToken(struct LexState *Lexer);
|
|||
/* parse.c */
|
||||
void ParseInit(void);
|
||||
void Parse(const Str *FileName, const Str *Source, int RunIt);
|
||||
int ParseType(struct LexState *Lexer, enum ValueType *Typ);
|
||||
|
||||
/* intrinsic.c */
|
||||
void IntrinsicInit(struct Table *GlobalTable);
|
||||
void IntrinsicGetLexer(struct LexState *Lexer, int IntrinsicId);
|
||||
void IntrinsicCall(struct LexState *Lexer, struct Value *Result, enum ValueType ReturnType, int IntrinsicId);
|
||||
|
||||
#endif /* PICOC_H */
|
||||
|
||||
|
|
Loading…
Reference in a new issue