Now compiles with some of the new structure in place

git-svn-id: http://picoc.googlecode.com/svn/trunk@34 21eae674-98b7-11dd-bd71-f92a316d2d60
This commit is contained in:
zik.saleeba 2009-01-21 09:02:05 +00:00
parent 626c29a639
commit a59be13de3
5 changed files with 196 additions and 103 deletions

9
TODO
View file

@ -8,3 +8,12 @@ TODO
* enum * enum
* interactive mode * interactive mode
New type system:
* basic types: picoc int, picoc char, native int, native char
* structs
* arrays of picoc types or structs
* pointers to:
Also:
* Change function store system to use dynamic allocation

View file

@ -2,11 +2,15 @@
#include <string.h> #include <string.h>
#include "picoc.h" #include "picoc.h"
#define NUM_INTRINSICS 3
Str IntrinsicFilename = { 9, "intrinsic" }; Str IntrinsicFilename = { 9, "intrinsic" };
struct Value IntrinsicValue[NUM_INTRINSICS];
int IntrinsicReferenceNo[NUM_INTRINSICS];
void IntrinsicPrintInt(void) void IntrinsicPrintInt(void)
{ {
printf("%d\n", Parameter[0].Val.Integer); printf("%d\n", Parameter[0].Val->Integer);
} }
void IntrinsicPrintf(void) void IntrinsicPrintf(void)
@ -32,14 +36,12 @@ struct IntrinsicFunction
void IntrinsicInit(struct Table *GlobalTable) void IntrinsicInit(struct Table *GlobalTable)
{ {
struct Value FuncVal;
struct LexState Lexer; struct LexState Lexer;
Str Source; Str Source;
int Count; int Count;
union AnyValue Identifier; union AnyValue Identifier;
enum ValueType Typ; struct ValueType *Typ;
FuncVal.Typ = TypeFunction;
for (Count = 0; Count < sizeof(Intrinsics) / sizeof(struct IntrinsicFunction); Count++) for (Count = 0; Count < sizeof(Intrinsics) / sizeof(struct IntrinsicFunction); Count++)
{ {
Source.Str = Intrinsics[Count].Prototype; Source.Str = Intrinsics[Count].Prototype;
@ -47,8 +49,11 @@ void IntrinsicInit(struct Table *GlobalTable)
LexInit(&Lexer, &Source, &IntrinsicFilename, Count+1); LexInit(&Lexer, &Source, &IntrinsicFilename, Count+1);
ParseType(&Lexer, &Typ); ParseType(&Lexer, &Typ);
LexGetToken(&Lexer, &Identifier); LexGetToken(&Lexer, &Identifier);
FuncVal.Val.Integer = -1 - Count; IntrinsicReferenceNo[Count] = -1 - Count;
TableSet(GlobalTable, &Identifier.String, &FuncVal); IntrinsicValue[Count].Typ = &FunctionType;
IntrinsicValue[Count].Val = (union AnyValue *)&IntrinsicReferenceNo[Count];
IntrinsicValue[Count].MustFree = FALSE;
TableSet(GlobalTable, &Identifier.String, &IntrinsicValue[Count]);
} }
} }
@ -60,9 +65,9 @@ void IntrinsicGetLexer(struct LexState *Lexer, int IntrinsicId)
Lexer->FileName = &IntrinsicFilename; Lexer->FileName = &IntrinsicFilename;
} }
void IntrinsicCall(struct LexState *Lexer, struct Value *Result, enum ValueType ReturnType, int IntrinsicId) void IntrinsicCall(struct LexState *Lexer, struct Value *Result, struct ValueType *ReturnType, int IntrinsicId)
{ {
Intrinsics[-1-IntrinsicId].Func(); Intrinsics[-1-IntrinsicId].Func();
Result->Typ = TypeVoid; Result->Typ = &VoidType;
} }

243
parse.c
View file

@ -20,6 +20,15 @@ struct Value Parameter[PARAMETER_MAX];
int ParameterUsed = 0; int ParameterUsed = 0;
struct Value ReturnValue; struct Value ReturnValue;
/* some basic types */
struct ValueType IntType;
struct ValueType CharType;
struct ValueType StringType;
struct ValueType FPType;
struct ValueType VoidType;
struct ValueType FunctionType;
struct ValueType MacroType;
/* local prototypes */ /* local prototypes */
int ParseExpression(struct LexState *Lexer, struct Value *Result, int RunIt); int ParseExpression(struct LexState *Lexer, struct Value *Result, int RunIt);
void ParseIntExpression(struct LexState *Lexer, struct Value *Result, int RunIt); void ParseIntExpression(struct LexState *Lexer, struct Value *Result, int RunIt);
@ -32,12 +41,76 @@ void ParseInit()
{ {
TableInit(&GlobalTable, &GlobalHashTable[0], GLOBAL_TABLE_SIZE); TableInit(&GlobalTable, &GlobalHashTable[0], GLOBAL_TABLE_SIZE);
IntrinsicInit(&GlobalTable); IntrinsicInit(&GlobalTable);
IntType.Base = TypeInt;
IntType.SubType = NULL;
CharType.Base = TypeChar;
CharType.SubType = NULL;
StringType.Base = TypeString;
StringType.SubType = NULL;
FPType.Base = TypeFP;
FPType.SubType = NULL;
VoidType.Base = TypeVoid;
VoidType.SubType = NULL;
FunctionType.Base = TypeFunction;
FunctionType.SubType = NULL;
MacroType.Base = TypeMacro;
MacroType.SubType = NULL;
}
/* find out the size of a type */
int ParseSizeofType(struct ValueType *Typ)
{
switch (Typ->Base)
{
case TypeVoid: return 0;
case TypeInt: return sizeof(int);
case TypeFP: return sizeof(double);
case TypeChar: return sizeof(char);
case TypeString: return sizeof(Str);
case TypeFunction: return sizeof(int);
case TypeMacro: return sizeof(int);
case TypePointer: return sizeof(struct PointerValue);
case TypeArray: return 0; // XXX - fixme
case TypeType: return sizeof(struct ValueType *);
}
return 0;
}
/* allocate a value either on the heap or the stack using space dependent on what type we want */
struct Value *ParseAllocValueFromType(struct ValueType *Typ)
{
struct Value *NewValue;
if (StackUsed == 0)
{ /* it's a global */
NewValue = HeapAlloc(sizeof(struct Value) + ParseSizeofType(Typ));
NewValue->MustFree = TRUE;
}
else
{ /* allocated on the stack */
NewValue = HeapAllocStack(sizeof(struct Value) + ParseSizeofType(Typ));
NewValue->MustFree = FALSE;
}
NewValue->Typ = Typ;
NewValue->Val = (union AnyValue *)((void *)NewValue + sizeof(struct Value));
return NewValue;
}
/* allocate a value either on the heap or the stack and copy its value */
struct Value *ParseAllocValueAndCopy(struct Value *FromValue)
{
struct Value *NewValue = ParseAllocValueFromType(FromValue->Typ);
memcpy(NewValue->Val, FromValue->Val, ParseSizeofType(FromValue->Typ));
return NewValue;
} }
/* define a variable */ /* define a variable */
void VariableDefine(struct LexState *Lexer, const Str *Ident, struct Value *InitValue) void VariableDefine(struct LexState *Lexer, const Str *Ident, struct Value *InitValue)
{ {
if (!TableSet((StackUsed == 0) ? &GlobalTable : &Stack[StackUsed-1].LocalTable, Ident, InitValue)) if (!TableSet((StackUsed == 0) ? &GlobalTable : &Stack[StackUsed-1].LocalTable, Ident, ParseAllocValueAndCopy(InitValue)))
ProgramFail(Lexer, "'%S' is already defined", Ident); ProgramFail(Lexer, "'%S' is already defined", Ident);
} }
@ -67,15 +140,15 @@ void StackFrameAdd(struct LexState *Lexer)
} }
/* parse a type specification */ /* parse a type specification */
int ParseType(struct LexState *Lexer, enum ValueType *Typ) int ParseType(struct LexState *Lexer, struct ValueType **Typ)
{ {
struct LexState Before = *Lexer; struct LexState Before = *Lexer;
enum LexToken Token = LexGetPlainToken(Lexer); enum LexToken Token = LexGetPlainToken(Lexer);
switch (Token) switch (Token)
{ {
case TokenIntType: case TokenCharType: *Typ = TypeInt; return TRUE; case TokenIntType: case TokenCharType: *Typ = &IntType; return TRUE;
case TokenFloatType: case TokenDoubleType: *Typ = TypeFP; return TRUE; case TokenFloatType: case TokenDoubleType: *Typ = &FPType; return TRUE;
case TokenVoidType: *Typ = TypeVoid; return TRUE; case TokenVoidType: *Typ = &VoidType; return TRUE;
default: *Lexer = Before; return FALSE; default: *Lexer = Before; return FALSE;
} }
} }
@ -83,7 +156,7 @@ int ParseType(struct LexState *Lexer, enum ValueType *Typ)
/* parse a parameter list, defining parameters as local variables in the current scope */ /* parse a parameter list, defining parameters as local variables in the current scope */
void ParseParameterList(struct LexState *CallLexer, struct LexState *FuncLexer, int RunIt) void ParseParameterList(struct LexState *CallLexer, struct LexState *FuncLexer, int RunIt)
{ {
enum ValueType Typ; struct ValueType *Typ;
union AnyValue Identifier; union AnyValue Identifier;
enum LexToken Token = LexGetPlainToken(FuncLexer); /* open bracket */ enum LexToken Token = LexGetPlainToken(FuncLexer); /* open bracket */
int ParamCount; int ParamCount;
@ -146,24 +219,24 @@ void ParseFunctionCall(struct LexState *Lexer, struct Value *Result, Str *FuncNa
if (RunIt) if (RunIt)
{ {
struct LexState FuncLexer; struct LexState FuncLexer;
enum ValueType ReturnType; struct ValueType *ReturnType;
struct Value *LValue; struct Value *LValue;
VariableGet(Lexer, FuncName, Result, &LValue); VariableGet(Lexer, FuncName, Result, &LValue);
if (Result->Typ != TypeFunction) if (Result->Typ->Base != TypeFunction)
ProgramFail(Lexer, "not a function - can't call"); ProgramFail(Lexer, "not a function - can't call");
StackFrameAdd(Lexer); StackFrameAdd(Lexer);
if (Result->Val.Integer >= 0) if (Result->Val->Integer >= 0)
FuncLexer = FunctionStore[Result->Val.Integer]; FuncLexer = FunctionStore[Result->Val->Integer];
else else
IntrinsicGetLexer(&FuncLexer, Result->Val.Integer); 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 (Result->Val.Integer >= 0) if (Result->Val->Integer >= 0)
{ {
if (LexPeekPlainToken(&FuncLexer) != TokenLeftBrace || !ParseStatement(&FuncLexer, TRUE)) if (LexPeekPlainToken(&FuncLexer) != TokenLeftBrace || !ParseStatement(&FuncLexer, TRUE))
ProgramFail(&FuncLexer, "function body expected"); ProgramFail(&FuncLexer, "function body expected");
@ -172,7 +245,7 @@ void ParseFunctionCall(struct LexState *Lexer, struct Value *Result, Str *FuncNa
ProgramFail(&FuncLexer, "bad return value"); ProgramFail(&FuncLexer, "bad return value");
} }
else else
IntrinsicCall(Lexer, Result, ReturnType, Result->Val.Integer); IntrinsicCall(Lexer, Result, ReturnType, Result->Val->Integer);
} }
} }
@ -180,14 +253,14 @@ void ParseFunctionCall(struct LexState *Lexer, struct Value *Result, Str *FuncNa
int ParseValue(struct LexState *Lexer, struct Value *Result, struct Value **LValue, int RunIt) int ParseValue(struct LexState *Lexer, struct Value *Result, struct Value **LValue, int RunIt)
{ {
struct LexState PreState = *Lexer; struct LexState PreState = *Lexer;
enum LexToken Token = LexGetToken(Lexer, &Result->Val); enum LexToken Token = LexGetToken(Lexer, Result->Val);
*LValue = NULL; *LValue = NULL;
switch (Token) switch (Token)
{ {
case TokenIntegerConstant: case TokenCharacterConstant: Result->Typ = TypeInt; break; case TokenIntegerConstant: case TokenCharacterConstant: Result->Typ = &IntType; break;
case TokenFPConstant: Result->Typ = TypeFP; break; case TokenFPConstant: Result->Typ = &FPType; break;
case TokenStringConstant: Result->Typ = TypeString; break; case TokenStringConstant: Result->Typ = &StringType; break;
case TokenMinus: case TokenUnaryExor: case TokenUnaryNot: case TokenMinus: case TokenUnaryExor: case TokenUnaryNot:
ParseIntExpression(Lexer, Result, RunIt); ParseIntExpression(Lexer, Result, RunIt);
@ -196,9 +269,9 @@ int ParseValue(struct LexState *Lexer, struct Value *Result, struct Value **LVal
{ {
switch(Token) switch(Token)
{ {
case TokenMinus: Result->Val.Integer = -(Result->Val.Integer); break; case TokenMinus: Result->Val->Integer = -(Result->Val->Integer); break;
case TokenUnaryExor: Result->Val.Integer = ~(Result->Val.Integer); break; case TokenUnaryExor: Result->Val->Integer = ~(Result->Val->Integer); break;
case TokenUnaryNot: Result->Val.Integer = !(Result->Val.Integer); break; case TokenUnaryNot: Result->Val->Integer = !(Result->Val->Integer); break;
default: break; default: break;
} }
} }
@ -218,15 +291,15 @@ int ParseValue(struct LexState *Lexer, struct Value *Result, struct Value **LVal
case TokenIdentifier: case TokenIdentifier:
if (LexPeekPlainToken(Lexer) == TokenOpenBracket) if (LexPeekPlainToken(Lexer) == TokenOpenBracket)
ParseFunctionCall(Lexer, Result, &Result->Val.String, RunIt); ParseFunctionCall(Lexer, Result, &Result->Val->String, RunIt);
else else
{ {
if (RunIt) if (RunIt)
{ {
VariableGet(Lexer, &Result->Val.String, Result, LValue); VariableGet(Lexer, &Result->Val->String, Result, LValue);
if (Result->Typ == TypeMacro) if (Result->Typ->Base == TypeMacro)
{ {
struct LexState MacroLexer = FunctionStore[Result->Val.Integer]; struct LexState MacroLexer = FunctionStore[Result->Val->Integer];
if (!ParseExpression(&MacroLexer, Result, TRUE)) if (!ParseExpression(&MacroLexer, Result, TRUE))
ProgramFail(&MacroLexer, "expression expected"); ProgramFail(&MacroLexer, "expression expected");
@ -258,7 +331,7 @@ int ParseExpression(struct LexState *Lexer, struct Value *Result, int RunIt)
while (TRUE) while (TRUE)
{ {
enum LexToken Token = LexPeekToken(Lexer, &CurrentValue.Val); enum LexToken Token = LexPeekToken(Lexer, CurrentValue.Val);
switch (Token) switch (Token)
{ {
case TokenPlus: case TokenMinus: case TokenAsterisk: case TokenSlash: case TokenPlus: case TokenMinus: case TokenAsterisk: case TokenSlash:
@ -276,14 +349,14 @@ int ParseExpression(struct LexState *Lexer, struct Value *Result, int RunIt)
if (RunIt) if (RunIt)
{ {
if (CurrentValue.Typ != TypeInt || TotalValue.Typ != TypeInt) if (CurrentValue.Typ->Base != TypeInt || TotalValue.Typ->Base != TypeInt)
ProgramFail(Lexer, "can't assign"); ProgramFail(Lexer, "can't assign");
switch (Token) switch (Token)
{ {
case TokenAddAssign: TotalValue.Val.Integer += CurrentValue.Val.Integer; break; case TokenAddAssign: TotalValue.Val->Integer += CurrentValue.Val->Integer; break;
case TokenSubtractAssign: TotalValue.Val.Integer -= CurrentValue.Val.Integer; break; case TokenSubtractAssign: TotalValue.Val->Integer -= CurrentValue.Val->Integer; break;
default: TotalValue.Val.Integer = CurrentValue.Val.Integer; break; default: TotalValue.Val->Integer = CurrentValue.Val->Integer; break;
} }
*TotalLValue = TotalValue; *TotalLValue = TotalValue;
} }
@ -300,30 +373,30 @@ int ParseExpression(struct LexState *Lexer, struct Value *Result, int RunIt)
if (RunIt) if (RunIt)
{ {
if (CurrentValue.Typ == TypeFP || TotalValue.Typ == TypeFP) if (CurrentValue.Typ->Base == TypeFP || TotalValue.Typ->Base == TypeFP)
{ /* convert both to floating point */ { /* convert both to floating point */
if (CurrentValue.Typ == TypeInt) if (CurrentValue.Typ->Base == TypeInt)
CurrentValue.Val.FP = (double)CurrentValue.Val.Integer; CurrentValue.Val->FP = (double)CurrentValue.Val->Integer; // XXX - fixme
else if (CurrentValue.Typ != TypeFP) else if (CurrentValue.Typ->Base != TypeFP)
ProgramFail(Lexer, "bad type for operator"); ProgramFail(Lexer, "bad type for operator");
if (TotalValue.Typ == TypeInt) if (TotalValue.Typ->Base == TypeInt)
TotalValue.Val.FP = (double)TotalValue.Val.Integer; TotalValue.Val->FP = (double)TotalValue.Val->Integer; // XXX - fixme
else if (TotalValue.Typ != TypeFP) else if (TotalValue.Typ->Base != TypeFP)
ProgramFail(Lexer, "bad type for operator"); ProgramFail(Lexer, "bad type for operator");
TotalValue.Typ = TypeInt; TotalValue.Typ = &IntType;
switch (Token) switch (Token)
{ {
case TokenPlus: TotalValue.Val.FP += CurrentValue.Val.FP; TotalValue.Typ = TypeFP; break; case TokenPlus: TotalValue.Val->FP += CurrentValue.Val->FP; TotalValue.Typ = &FPType; break;
case TokenMinus: TotalValue.Val.FP -= CurrentValue.Val.FP; TotalValue.Typ = TypeFP; break; case TokenMinus: TotalValue.Val->FP -= CurrentValue.Val->FP; TotalValue.Typ = &FPType; break;
case TokenAsterisk: TotalValue.Val.FP *= CurrentValue.Val.FP; TotalValue.Typ = TypeFP; break; case TokenAsterisk: TotalValue.Val->FP *= CurrentValue.Val->FP; TotalValue.Typ = &FPType; break;
case TokenSlash: TotalValue.Val.FP /= CurrentValue.Val.FP; TotalValue.Typ = TypeFP; break; case TokenSlash: TotalValue.Val->FP /= CurrentValue.Val->FP; TotalValue.Typ = &FPType; break;
case TokenEquality: TotalValue.Val.Integer = TotalValue.Val.FP == CurrentValue.Val.FP; break; case TokenEquality: TotalValue.Val->Integer = TotalValue.Val->FP == CurrentValue.Val->FP; break;
case TokenLessThan: TotalValue.Val.Integer = TotalValue.Val.FP < CurrentValue.Val.FP; break; case TokenLessThan: TotalValue.Val->Integer = TotalValue.Val->FP < CurrentValue.Val->FP; break;
case TokenGreaterThan: TotalValue.Val.Integer = TotalValue.Val.FP > CurrentValue.Val.FP; break; case TokenGreaterThan: TotalValue.Val->Integer = TotalValue.Val->FP > CurrentValue.Val->FP; break;
case TokenLessEqual: TotalValue.Val.Integer = TotalValue.Val.FP <= CurrentValue.Val.FP; break; case TokenLessEqual: TotalValue.Val->Integer = TotalValue.Val->FP <= CurrentValue.Val->FP; break;
case TokenGreaterEqual: TotalValue.Val.Integer = TotalValue.Val.FP >= CurrentValue.Val.FP; break; case TokenGreaterEqual: TotalValue.Val->Integer = TotalValue.Val->FP >= CurrentValue.Val->FP; break;
case TokenLogicalAnd: case TokenLogicalOr: case TokenAmpersand: case TokenArithmeticOr: case TokenArithmeticExor: ProgramFail(Lexer, "bad type for operator"); break; case TokenLogicalAnd: case TokenLogicalOr: case TokenAmpersand: case TokenArithmeticOr: case TokenArithmeticExor: ProgramFail(Lexer, "bad type for operator"); break;
case TokenDot: ProgramFail(Lexer, "operator not supported"); break; case TokenDot: ProgramFail(Lexer, "operator not supported"); break;
default: break; default: break;
@ -331,26 +404,26 @@ int ParseExpression(struct LexState *Lexer, struct Value *Result, int RunIt)
} }
else else
{ {
if (CurrentValue.Typ != TypeInt || TotalValue.Typ != TypeInt) if (CurrentValue.Typ->Base != TypeInt || TotalValue.Typ->Base != TypeInt)
ProgramFail(Lexer, "bad operand types"); ProgramFail(Lexer, "bad operand types");
/* integer arithmetic */ /* integer arithmetic */
switch (Token) switch (Token)
{ {
case TokenPlus: TotalValue.Val.Integer += CurrentValue.Val.Integer; break; case TokenPlus: TotalValue.Val->Integer += CurrentValue.Val->Integer; break;
case TokenMinus: TotalValue.Val.Integer -= CurrentValue.Val.Integer; break; case TokenMinus: TotalValue.Val->Integer -= CurrentValue.Val->Integer; break;
case TokenAsterisk: TotalValue.Val.Integer *= CurrentValue.Val.Integer; break; case TokenAsterisk: TotalValue.Val->Integer *= CurrentValue.Val->Integer; break;
case TokenSlash: TotalValue.Val.Integer /= CurrentValue.Val.Integer; break; case TokenSlash: TotalValue.Val->Integer /= CurrentValue.Val->Integer; break;
case TokenEquality: TotalValue.Val.Integer = TotalValue.Val.Integer == CurrentValue.Val.Integer; break; case TokenEquality: TotalValue.Val->Integer = TotalValue.Val->Integer == CurrentValue.Val->Integer; break;
case TokenLessThan: TotalValue.Val.Integer = TotalValue.Val.Integer < CurrentValue.Val.Integer; break; case TokenLessThan: TotalValue.Val->Integer = TotalValue.Val->Integer < CurrentValue.Val->Integer; break;
case TokenGreaterThan: TotalValue.Val.Integer = TotalValue.Val.Integer > CurrentValue.Val.Integer; break; case TokenGreaterThan: TotalValue.Val->Integer = TotalValue.Val->Integer > CurrentValue.Val->Integer; break;
case TokenLessEqual: TotalValue.Val.Integer = TotalValue.Val.Integer <= CurrentValue.Val.Integer; break; case TokenLessEqual: TotalValue.Val->Integer = TotalValue.Val->Integer <= CurrentValue.Val->Integer; break;
case TokenGreaterEqual: TotalValue.Val.Integer = TotalValue.Val.Integer >= CurrentValue.Val.Integer; break; case TokenGreaterEqual: TotalValue.Val->Integer = TotalValue.Val->Integer >= CurrentValue.Val->Integer; break;
case TokenLogicalAnd: TotalValue.Val.Integer = TotalValue.Val.Integer && CurrentValue.Val.Integer; break; case TokenLogicalAnd: TotalValue.Val->Integer = TotalValue.Val->Integer && CurrentValue.Val->Integer; break;
case TokenLogicalOr: TotalValue.Val.Integer = TotalValue.Val.Integer || CurrentValue.Val.Integer; break; case TokenLogicalOr: TotalValue.Val->Integer = TotalValue.Val->Integer || CurrentValue.Val->Integer; break;
case TokenAmpersand: TotalValue.Val.Integer = TotalValue.Val.Integer & CurrentValue.Val.Integer; break; case TokenAmpersand: TotalValue.Val->Integer = TotalValue.Val->Integer & CurrentValue.Val->Integer; break;
case TokenArithmeticOr: TotalValue.Val.Integer = TotalValue.Val.Integer | CurrentValue.Val.Integer; break; case TokenArithmeticOr: TotalValue.Val->Integer = TotalValue.Val->Integer | CurrentValue.Val->Integer; break;
case TokenArithmeticExor: TotalValue.Val.Integer = TotalValue.Val.Integer ^ CurrentValue.Val.Integer; break; case TokenArithmeticExor: TotalValue.Val->Integer = TotalValue.Val->Integer ^ CurrentValue.Val->Integer; break;
case TokenDot: ProgramFail(Lexer, "operator not supported"); break; case TokenDot: ProgramFail(Lexer, "operator not supported"); break;
default: break; default: break;
} }
@ -367,32 +440,34 @@ void ParseIntExpression(struct LexState *Lexer, struct Value *Result, int RunIt)
if (!ParseExpression(Lexer, Result, RunIt)) if (!ParseExpression(Lexer, Result, RunIt))
ProgramFail(Lexer, "expression expected"); ProgramFail(Lexer, "expression expected");
if (RunIt && Result->Typ != TypeInt) if (RunIt && Result->Typ->Base != TypeInt)
ProgramFail(Lexer, "integer value expected"); ProgramFail(Lexer, "integer value expected");
} }
/* parse a function definition and store it for later */ /* parse a function definition and store it for later */
void ParseFunctionDefinition(struct LexState *Lexer, Str *Identifier, struct LexState *PreState) void ParseFunctionDefinition(struct LexState *Lexer, Str *Identifier, struct LexState *PreState)
{ {
struct Value FuncValue; struct Value *FuncValue;
if (FunctionStoreUsed >= FUNCTION_STORE_MAX) if (FunctionStoreUsed >= FUNCTION_STORE_MAX)
ProgramFail(Lexer, "too many functions/macros defined"); ProgramFail(Lexer, "too many functions/macros defined");
FunctionStore[FunctionStoreUsed] = *PreState; FunctionStore[FunctionStoreUsed] = *PreState;
LexGetPlainToken(Lexer); LexGetPlainToken(Lexer);
if (LexGetPlainToken(Lexer) != TokenCloseBracket || LexPeekToken(Lexer, &FuncValue.Val) != TokenLeftBrace) if (LexGetPlainToken(Lexer) != TokenCloseBracket || LexPeekToken(Lexer, FuncValue->Val) != TokenLeftBrace)
ProgramFail(Lexer, "bad function definition"); ProgramFail(Lexer, "bad function definition");
if (!ParseStatement(Lexer, FALSE)) if (!ParseStatement(Lexer, FALSE))
ProgramFail(Lexer, "function definition expected"); ProgramFail(Lexer, "function definition expected");
FunctionStore[FunctionStoreUsed].End = Lexer->Pos; FunctionStore[FunctionStoreUsed].End = Lexer->Pos;
FuncValue.Typ = TypeFunction; FuncValue = HeapAlloc(sizeof(struct Value) + sizeof(int));
FuncValue.Val.Integer = FunctionStoreUsed; FuncValue->Typ = &FunctionType;
FuncValue->Val = (union AnyValue *)((void *)FuncValue + sizeof(struct Value));
FuncValue->Val->Integer = FunctionStoreUsed;
FunctionStoreUsed++; FunctionStoreUsed++;
if (!TableSet(&GlobalTable, Identifier, &FuncValue)) if (!TableSet(&GlobalTable, Identifier, FuncValue))
ProgramFail(Lexer, "'%S' is already defined", Identifier); ProgramFail(Lexer, "'%S' is already defined", Identifier);
} }
@ -400,7 +475,7 @@ void ParseFunctionDefinition(struct LexState *Lexer, Str *Identifier, struct Lex
void ParseMacroDefinition(struct LexState *Lexer) void ParseMacroDefinition(struct LexState *Lexer)
{ {
union AnyValue MacroName; union AnyValue MacroName;
struct Value MacroValue; struct Value *MacroValue;
if (LexGetToken(Lexer, &MacroName) != TokenIdentifier) if (LexGetToken(Lexer, &MacroName) != TokenIdentifier)
ProgramFail(Lexer, "identifier expected"); ProgramFail(Lexer, "identifier expected");
@ -411,11 +486,13 @@ void ParseMacroDefinition(struct LexState *Lexer)
FunctionStore[FunctionStoreUsed] = *Lexer; FunctionStore[FunctionStoreUsed] = *Lexer;
LexToEndOfLine(Lexer); LexToEndOfLine(Lexer);
FunctionStore[FunctionStoreUsed].End = Lexer->Pos; FunctionStore[FunctionStoreUsed].End = Lexer->Pos;
MacroValue.Typ = TypeMacro; MacroValue = HeapAlloc(sizeof(struct Value) + sizeof(int));
MacroValue.Val.Integer = FunctionStoreUsed; MacroValue->Typ = &MacroType;
MacroValue->Val = (union AnyValue *)((void *)MacroValue + sizeof(struct Value));
MacroValue->Val->Integer = FunctionStoreUsed;
FunctionStoreUsed++; FunctionStoreUsed++;
if (!TableSet(&GlobalTable, &MacroName.String, &MacroValue)) if (!TableSet(&GlobalTable, &MacroName.String, MacroValue))
ProgramFail(Lexer, "'%S' is already defined", &MacroName.String); ProgramFail(Lexer, "'%S' is already defined", &MacroName.String);
} }
@ -446,12 +523,12 @@ void ParseFor(struct LexState *Lexer, struct Value *Result, int RunIt)
ProgramFail(Lexer, "')' expected"); ProgramFail(Lexer, "')' expected");
PreStatement = *Lexer; PreStatement = *Lexer;
if (!ParseStatement(Lexer, RunIt && Conditional.Val.Integer)) if (!ParseStatement(Lexer, RunIt && Conditional.Val->Integer))
ProgramFail(Lexer, "statement expected"); ProgramFail(Lexer, "statement expected");
After = *Lexer; After = *Lexer;
while (Conditional.Val.Integer && RunIt) while (Conditional.Val->Integer && RunIt)
{ {
*Lexer = PreIncrement; *Lexer = PreIncrement;
ParseStatement(Lexer, TRUE); ParseStatement(Lexer, TRUE);
@ -459,7 +536,7 @@ void ParseFor(struct LexState *Lexer, struct Value *Result, int RunIt)
*Lexer = PreConditional; *Lexer = PreConditional;
ParseIntExpression(Lexer, &Conditional, RunIt); ParseIntExpression(Lexer, &Conditional, RunIt);
if (Conditional.Val.Integer) if (Conditional.Val->Integer)
{ {
*Lexer = PreStatement; *Lexer = PreStatement;
ParseStatement(Lexer, TRUE); ParseStatement(Lexer, TRUE);
@ -475,7 +552,7 @@ int ParseStatement(struct LexState *Lexer, int RunIt)
struct Value CValue; struct Value CValue;
struct LexState PreState = *Lexer; struct LexState PreState = *Lexer;
union AnyValue LexerValue; union AnyValue LexerValue;
enum ValueType Typ; struct ValueType *Typ;
enum LexToken Token = LexGetToken(Lexer, &LexerValue); enum LexToken Token = LexGetToken(Lexer, &LexerValue);
switch (Token) switch (Token)
@ -499,13 +576,13 @@ int ParseStatement(struct LexState *Lexer, int RunIt)
case TokenIf: case TokenIf:
ParseIntExpression(Lexer, &CValue, RunIt); ParseIntExpression(Lexer, &CValue, RunIt);
if (!ParseStatement(Lexer, RunIt && CValue.Val.Integer)) if (!ParseStatement(Lexer, RunIt && CValue.Val->Integer))
ProgramFail(Lexer, "statement expected"); ProgramFail(Lexer, "statement expected");
if (LexPeekToken(Lexer, &LexerValue) == TokenElse) if (LexPeekToken(Lexer, &LexerValue) == TokenElse)
{ {
LexGetToken(Lexer, &LexerValue); LexGetToken(Lexer, &LexerValue);
if (!ParseStatement(Lexer, RunIt && !CValue.Val.Integer)) if (!ParseStatement(Lexer, RunIt && !CValue.Val->Integer))
ProgramFail(Lexer, "statement expected"); ProgramFail(Lexer, "statement expected");
} }
break; break;
@ -518,10 +595,10 @@ int ParseStatement(struct LexState *Lexer, int RunIt)
*Lexer = PreConditional; *Lexer = PreConditional;
ParseIntExpression(Lexer, &CValue, RunIt); ParseIntExpression(Lexer, &CValue, RunIt);
if (!ParseStatement(Lexer, RunIt && CValue.Val.Integer)) if (!ParseStatement(Lexer, RunIt && CValue.Val->Integer))
ProgramFail(Lexer, "statement expected"); ProgramFail(Lexer, "statement expected");
} while (RunIt && CValue.Val.Integer); } while (RunIt && CValue.Val->Integer);
} }
break; break;
@ -536,7 +613,7 @@ int ParseStatement(struct LexState *Lexer, int RunIt)
ParseIntExpression(Lexer, &CValue, RunIt); ParseIntExpression(Lexer, &CValue, RunIt);
} while (CValue.Val.Integer && RunIt); } while (CValue.Val->Integer && RunIt);
} }
break; break;
@ -561,10 +638,10 @@ int ParseStatement(struct LexState *Lexer, int RunIt)
else else
{ {
struct Value InitValue; struct Value InitValue;
if (Typ == TokenFloatType) if (Typ->Base == TypeFP)
InitValue.Val.FP = 0.0; InitValue.Val->FP = 0.0;
else else
InitValue.Val.Integer = 0; InitValue.Val->Integer = 0;
InitValue.Typ = Typ; InitValue.Typ = Typ;
VariableDefine(Lexer, &LexerValue.String, &InitValue); VariableDefine(Lexer, &LexerValue.String, &InitValue);

22
picoc.h
View file

@ -35,7 +35,7 @@
#define PATH_MAX 1024 #define PATH_MAX 1024
#endif #endif
#define ISVALUETYPE(t) (((t) == TypeInt) || ((t) == TypeFP) || ((t) == TypeString)) #define ISVALUETYPE(t) (((t)->Base == TypeInt) || ((t)->Base == TypeFP) || ((t)->Base == TypeString))
/* lexical tokens */ /* lexical tokens */
enum LexToken enum LexToken
@ -152,10 +152,10 @@ struct PointerValue
union AnyValue union AnyValue
{ {
unsigned char *Character; unsigned char Character;
short *ShortInteger; short ShortInteger;
int *Integer; int Integer;
double *FP; double FP;
Str String; Str String;
struct ArrayValue Array; struct ArrayValue Array;
struct PointerValue Pointer; struct PointerValue Pointer;
@ -163,16 +163,16 @@ union AnyValue
struct Value struct Value
{ {
struct ValueType Typ; struct ValueType *Typ;
char MustFree;
union AnyValue *Val; union AnyValue *Val;
char MustFree;
}; };
/* hash table data structure */ /* hash table data structure */
struct TableEntry struct TableEntry
{ {
Str Key; Str Key;
struct Value Val; struct Value *Val;
}; };
struct Table struct Table
@ -203,6 +203,8 @@ struct Table GlobalTable;
extern struct Value Parameter[PARAMETER_MAX]; extern struct Value Parameter[PARAMETER_MAX];
extern int ParameterUsed; extern int ParameterUsed;
extern struct Value ReturnValue; extern struct Value ReturnValue;
extern struct ValueType VoidType;
extern struct ValueType FunctionType;
/* str.c */ /* str.c */
void StrToC(char *Dest, int DestSize, const Str *Source); void StrToC(char *Dest, int DestSize, const Str *Source);
@ -233,12 +235,12 @@ void LexToEndOfLine(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, struct ValueType *Typ); int ParseType(struct LexState *Lexer, struct ValueType **Typ);
/* intrinsic.c */ /* intrinsic.c */
void IntrinsicInit(struct Table *GlobalTable); void IntrinsicInit(struct Table *GlobalTable);
void IntrinsicGetLexer(struct LexState *Lexer, int IntrinsicId); void IntrinsicGetLexer(struct LexState *Lexer, int IntrinsicId);
void IntrinsicCall(struct LexState *Lexer, struct Value *Result, struct ValueType ReturnType, int IntrinsicId); void IntrinsicCall(struct LexState *Lexer, struct Value *Result, struct ValueType *ReturnType, int IntrinsicId);
/* heap.c */ /* heap.c */
void HeapInit(); void HeapInit();

View file

@ -87,7 +87,7 @@ int TableSet(struct Table *Tbl, const Str *Key, struct Value *Val)
{ /* add it to the table */ { /* add it to the table */
struct TableEntry *Entry = &Tbl->HashTable[AddAt]; struct TableEntry *Entry = &Tbl->HashTable[AddAt];
Entry->Key = *Key; Entry->Key = *Key;
Entry->Val = *Val; Entry->Val = Val;
} }
} }
@ -104,7 +104,7 @@ int TableGet(struct Table *Tbl, const Str *Key, struct Value **Val)
if (HashPos == -1) if (HashPos == -1)
return FALSE; return FALSE;
*Val = &Tbl->HashTable[HashPos].Val; *Val = Tbl->HashTable[HashPos].Val;
return TRUE; return TRUE;
} }