Added floating point support
git-svn-id: http://picoc.googlecode.com/svn/trunk@22 21eae674-98b7-11dd-bd71-f92a316d2d60
This commit is contained in:
parent
a8008e9ac7
commit
704f20e1c4
3
Makefile
3
Makefile
|
@ -1,5 +1,6 @@
|
|||
CC=gcc
|
||||
CFLAGS=-Wall -g
|
||||
LIBS=-lm
|
||||
|
||||
TARGET = picoc
|
||||
SRCS = picoc.c table.c str.c parse.c lex.c
|
||||
|
@ -8,7 +9,7 @@ OBJS := $(SRCS:%.c=%.o)
|
|||
all: $(TARGET)
|
||||
|
||||
$(TARGET): $(OBJS)
|
||||
$(CC) $(CFLAGS) -o $(TARGET) $(OBJS)
|
||||
$(CC) $(CFLAGS) -o $(TARGET) $(OBJS) $(LIBS)
|
||||
|
||||
clean:
|
||||
rm -f $(TARGET) $(OBJS) *~
|
||||
|
|
30
lex.c
30
lex.c
|
@ -1,4 +1,5 @@
|
|||
#include <ctype.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "picoc.h"
|
||||
|
||||
|
@ -25,7 +26,9 @@ static struct ReservedWord ReservedWords[] =
|
|||
{ "char", TokenCharType },
|
||||
{ "default", TokenDefault },
|
||||
{ "do", TokenDo },
|
||||
{ "double", TokenDoubleType },
|
||||
{ "else", TokenElse },
|
||||
{ "float", TokenFloatType },
|
||||
{ "for", TokenFor },
|
||||
{ "if", TokenIf },
|
||||
{ "int", TokenIntType },
|
||||
|
@ -59,15 +62,30 @@ enum LexToken LexCheckReservedWord(const Str *Word)
|
|||
enum LexToken LexGetNumber(struct LexState *Lexer, union AnyValue *Value)
|
||||
{
|
||||
int Result = 0;
|
||||
double FPResult;
|
||||
double FPDiv;
|
||||
|
||||
while (Lexer->Pos != Lexer->End && isdigit(*Lexer->Pos))
|
||||
{
|
||||
Result = Result * 10 + (*Lexer->Pos - '0');
|
||||
Lexer->Pos++;
|
||||
}
|
||||
for (; Lexer->Pos != Lexer->End && isdigit(*Lexer->Pos); Lexer->Pos++)
|
||||
Result = Result * 10 + (*Lexer->Pos - '0');
|
||||
|
||||
Value->Integer = Result;
|
||||
return TokenIntegerConstant;
|
||||
if (Lexer->Pos == Lexer->End || *Lexer->Pos != '.')
|
||||
return TokenIntegerConstant;
|
||||
|
||||
Lexer->Pos++;
|
||||
for (FPDiv = 0.1, FPResult = (double)Result; Lexer->Pos != Lexer->End && isdigit(*Lexer->Pos); Lexer->Pos++, FPDiv /= 10.0)
|
||||
FPResult += (*Lexer->Pos - '0') * FPDiv;
|
||||
|
||||
if (Lexer->Pos != Lexer->End && (*Lexer->Pos == 'e' || *Lexer->Pos == 'E'))
|
||||
{
|
||||
Lexer->Pos++;
|
||||
for (Result = 0; Lexer->Pos != Lexer->End && isdigit(*Lexer->Pos); Lexer->Pos++)
|
||||
Result = Result * 10 + (*Lexer->Pos - '0');
|
||||
|
||||
FPResult *= pow(10.0, (double)Result);
|
||||
}
|
||||
|
||||
return TokenFPConstant;
|
||||
}
|
||||
|
||||
enum LexToken LexGetWord(struct LexState *Lexer, union AnyValue *Value)
|
||||
|
|
90
parse.c
90
parse.c
|
@ -81,6 +81,7 @@ int ParseType(struct LexState *Lexer, enum ValueType *Typ)
|
|||
switch (Token)
|
||||
{
|
||||
case TokenIntType: case TokenCharType: *Typ = TypeInt; return TRUE;
|
||||
case TokenFloatType: case TokenDoubleType: *Typ = TypeFP; return TRUE;
|
||||
case TokenVoidType: *Typ = TypeVoid; return TRUE;
|
||||
default: *Lexer = Before; return FALSE;
|
||||
}
|
||||
|
@ -179,11 +180,9 @@ int ParseValue(struct LexState *Lexer, struct Value *Result, struct Value **LVal
|
|||
|
||||
switch (Token)
|
||||
{
|
||||
case TokenIntegerConstant: case TokenCharacterConstant: case TokenStringConstant:
|
||||
Result->Typ = TypeInt;
|
||||
if (Token == TokenStringConstant)
|
||||
Result->Typ = TypeString;
|
||||
break;
|
||||
case TokenIntegerConstant: case TokenCharacterConstant: Result->Typ = TypeInt; break;
|
||||
case TokenFPConstant: Result->Typ = TypeFP; break;
|
||||
case TokenStringConstant: Result->Typ = TypeString; break;
|
||||
|
||||
case TokenMinus: case TokenUnaryExor: case TokenUnaryNot:
|
||||
ParseIntExpression(Lexer, Result, RunIt);
|
||||
|
@ -285,27 +284,60 @@ int ParseExpression(struct LexState *Lexer, struct Value *Result, int RunIt)
|
|||
|
||||
if (RunIt)
|
||||
{
|
||||
if (CurrentValue.Typ != TypeInt || TotalValue.Typ != TypeInt)
|
||||
ProgramFail(Lexer, "bad operand types");
|
||||
|
||||
switch (Token)
|
||||
if (CurrentValue.Typ == TypeFP || TotalValue.Typ == TypeFP)
|
||||
{ /* convert both to floating point */
|
||||
if (CurrentValue.Typ == TypeInt)
|
||||
CurrentValue.Val.FP = (double)CurrentValue.Val.Integer;
|
||||
else if (CurrentValue.Typ != TypeFP)
|
||||
ProgramFail(Lexer, "bad type for operator");
|
||||
|
||||
if (TotalValue.Typ == TypeInt)
|
||||
TotalValue.Val.FP = (double)TotalValue.Val.Integer;
|
||||
else if (TotalValue.Typ != TypeFP)
|
||||
ProgramFail(Lexer, "bad type for operator");
|
||||
|
||||
TotalValue.Typ = TypeInt;
|
||||
switch (Token)
|
||||
{
|
||||
case TokenPlus: TotalValue.Val.FP += CurrentValue.Val.FP; TotalValue.Typ = TypeFP; break;
|
||||
case TokenMinus: TotalValue.Val.FP -= CurrentValue.Val.FP; TotalValue.Typ = TypeFP; break;
|
||||
case TokenAsterisk: TotalValue.Val.FP *= CurrentValue.Val.FP; TotalValue.Typ = TypeFP; break;
|
||||
case TokenSlash: TotalValue.Val.FP /= CurrentValue.Val.FP; TotalValue.Typ = TypeFP; 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 TokenGreaterThan: 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 TokenLogicalAnd: case TokenLogicalOr: case TokenAmpersand: case TokenArithmeticOr: case TokenArithmeticExor: ProgramFail(Lexer, "bad type for operator"); break;
|
||||
case TokenDot: ProgramFail(Lexer, "operator not supported"); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
case TokenPlus: 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 TokenSlash: 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 TokenGreaterThan: TotalValue.Val.Integer = TotalValue.Val.Integer > CurrentValue.Val.Integer; break;
|
||||
case TokenLessEqual: printf("compare %d <= %d\n", TotalValue.Val.Integer, CurrentValue.Val.Integer); 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 TokenLogicalOr: 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 TokenArithmeticExor: TotalValue.Val.Integer = TotalValue.Val.Integer ^ CurrentValue.Val.Integer; break;
|
||||
case TokenDot: ProgramFail(Lexer, "operator not supported"); break;
|
||||
default: break;
|
||||
if (CurrentValue.Typ != TypeInt || TotalValue.Typ != TypeInt)
|
||||
ProgramFail(Lexer, "bad operand types");
|
||||
|
||||
/* integer arithmetic */
|
||||
switch (Token)
|
||||
{
|
||||
case TokenPlus: 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 TokenSlash: 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 TokenGreaterThan: TotalValue.Val.Integer = TotalValue.Val.Integer > CurrentValue.Val.Integer; break;
|
||||
case TokenLessEqual: printf("compare %d <= %d\n", TotalValue.Val.Integer, CurrentValue.Val.Integer); 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 TokenLogicalOr: 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 TokenArithmeticExor: TotalValue.Val.Integer = TotalValue.Val.Integer ^ CurrentValue.Val.Integer; break;
|
||||
case TokenDot: ProgramFail(Lexer, "operator not supported"); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -473,6 +505,8 @@ int ParseStatement(struct LexState *Lexer, int RunIt)
|
|||
|
||||
case TokenIntType:
|
||||
case TokenCharType:
|
||||
case TokenFloatType:
|
||||
case TokenDoubleType:
|
||||
case TokenVoidType:
|
||||
*Lexer = PreState;
|
||||
ParseType(Lexer, &Typ);
|
||||
|
@ -485,7 +519,11 @@ int ParseStatement(struct LexState *Lexer, int RunIt)
|
|||
else
|
||||
{
|
||||
struct Value InitValue;
|
||||
InitValue.Val.Integer = 0;
|
||||
if (Typ == TokenFloatType)
|
||||
InitValue.Val.FP = 0.0;
|
||||
else
|
||||
InitValue.Val.Integer = 0;
|
||||
|
||||
InitValue.Typ = Typ;
|
||||
VariableDefine(Lexer, &LexerValue.String, &InitValue);
|
||||
}
|
||||
|
|
5
picoc.h
5
picoc.h
|
@ -37,6 +37,7 @@ enum LexToken
|
|||
TokenEOF,
|
||||
TokenIdentifier,
|
||||
TokenIntegerConstant,
|
||||
TokenFPConstant,
|
||||
TokenStringConstant,
|
||||
TokenCharacterConstant,
|
||||
TokenType,
|
||||
|
@ -73,6 +74,8 @@ enum LexToken
|
|||
TokenDecrement,
|
||||
TokenIntType,
|
||||
TokenCharType,
|
||||
TokenFloatType,
|
||||
TokenDoubleType,
|
||||
TokenVoidType,
|
||||
TokenDo,
|
||||
TokenElse,
|
||||
|
@ -106,6 +109,7 @@ enum ValueType
|
|||
{
|
||||
TypeVoid,
|
||||
TypeInt,
|
||||
TypeFP,
|
||||
TypeString,
|
||||
TypeFunction
|
||||
};
|
||||
|
@ -113,6 +117,7 @@ enum ValueType
|
|||
union AnyValue
|
||||
{
|
||||
int Integer;
|
||||
double FP;
|
||||
Str String;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue