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
|
LIBS=-lm
|
||||||
|
|
||||||
TARGET = picoc
|
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)
|
OBJS := $(SRCS:%.c=%.o)
|
||||||
|
|
||||||
all: $(TARGET)
|
all: $(TARGET)
|
||||||
|
|
2
hello.c
2
hello.c
|
@ -1,6 +1,6 @@
|
||||||
void fred()
|
void fred()
|
||||||
{
|
{
|
||||||
default
|
sayhello();
|
||||||
}
|
}
|
||||||
|
|
||||||
fred();
|
fred();
|
||||||
|
|
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()
|
void ParseInit()
|
||||||
{
|
{
|
||||||
TableInit(&GlobalTable, &GlobalHashTable[0], GLOBAL_TABLE_SIZE);
|
TableInit(&GlobalTable, &GlobalHashTable[0], GLOBAL_TABLE_SIZE);
|
||||||
|
IntrinsicInit(&GlobalTable);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* define a variable */
|
/* 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 */
|
/* get the value of a variable. must be defined */
|
||||||
void VariableGet(struct LexState *Lexer, Str *Ident, struct Value *Val, struct Value **LVal)
|
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))
|
if (!TableGet(&GlobalTable, Ident, LVal))
|
||||||
ProgramFail(Lexer, "'%S' is undefined", Ident);
|
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");
|
ProgramFail(Lexer, "not a function - can't call");
|
||||||
|
|
||||||
StackFrameAdd(Lexer);
|
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 */
|
ParseType(&FuncLexer, &ReturnType); /* return type */
|
||||||
Result->Typ = TypeVoid;
|
Result->Typ = TypeVoid;
|
||||||
LexGetPlainToken(&FuncLexer); /* function name again */
|
LexGetPlainToken(&FuncLexer); /* function name again */
|
||||||
ParseParameterList(Lexer, &FuncLexer, TRUE); /* parameters */
|
ParseParameterList(Lexer, &FuncLexer, TRUE); /* parameters */
|
||||||
if (LexPeekPlainToken(&FuncLexer) != TokenLeftBrace || !ParseStatement(&FuncLexer, TRUE))
|
if (Result->Val.Integer >= 0)
|
||||||
ProgramFail(&FuncLexer, "function body expected");
|
{
|
||||||
|
if (LexPeekPlainToken(&FuncLexer) != TokenLeftBrace || !ParseStatement(&FuncLexer, TRUE))
|
||||||
|
ProgramFail(&FuncLexer, "function body expected");
|
||||||
|
|
||||||
if (ReturnType != Result->Typ)
|
if (ReturnType != Result->Typ)
|
||||||
ProgramFail(&FuncLexer, "bad return value");
|
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];
|
struct TableEntry LocalHashTable[LOCAL_TABLE_SIZE];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* globals */
|
||||||
|
extern struct Table GlobalTable;
|
||||||
|
|
||||||
/* str.c */
|
/* str.c */
|
||||||
void StrToC(char *Dest, int DestSize, const Str *Source);
|
void StrToC(char *Dest, int DestSize, const Str *Source);
|
||||||
|
@ -188,6 +190,12 @@ enum LexToken LexPeekPlainToken(struct LexState *Lexer);
|
||||||
/* parse.c */
|
/* parse.c */
|
||||||
void ParseInit(void);
|
void ParseInit(void);
|
||||||
void Parse(const Str *FileName, const Str *Source, int RunIt);
|
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 */
|
#endif /* PICOC_H */
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue