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:
parent
626c29a639
commit
a59be13de3
9
TODO
9
TODO
|
@ -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
|
||||||
|
|
21
intrinsic.c
21
intrinsic.c
|
@ -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
243
parse.c
|
@ -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
22
picoc.h
|
@ -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();
|
||||||
|
|
4
table.c
4
table.c
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue