Added floating point support

git-svn-id: http://picoc.googlecode.com/svn/trunk@22 21eae674-98b7-11dd-bd71-f92a316d2d60
This commit is contained in:
zik.saleeba 2008-12-27 02:25:49 +00:00
parent a8008e9ac7
commit 704f20e1c4
4 changed files with 95 additions and 33 deletions

View file

@ -1,5 +1,6 @@
CC=gcc CC=gcc
CFLAGS=-Wall -g CFLAGS=-Wall -g
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
@ -8,7 +9,7 @@ OBJS := $(SRCS:%.c=%.o)
all: $(TARGET) all: $(TARGET)
$(TARGET): $(OBJS) $(TARGET): $(OBJS)
$(CC) $(CFLAGS) -o $(TARGET) $(OBJS) $(CC) $(CFLAGS) -o $(TARGET) $(OBJS) $(LIBS)
clean: clean:
rm -f $(TARGET) $(OBJS) *~ rm -f $(TARGET) $(OBJS) *~

26
lex.c
View file

@ -1,4 +1,5 @@
#include <ctype.h> #include <ctype.h>
#include <math.h>
#include "picoc.h" #include "picoc.h"
@ -25,7 +26,9 @@ static struct ReservedWord ReservedWords[] =
{ "char", TokenCharType }, { "char", TokenCharType },
{ "default", TokenDefault }, { "default", TokenDefault },
{ "do", TokenDo }, { "do", TokenDo },
{ "double", TokenDoubleType },
{ "else", TokenElse }, { "else", TokenElse },
{ "float", TokenFloatType },
{ "for", TokenFor }, { "for", TokenFor },
{ "if", TokenIf }, { "if", TokenIf },
{ "int", TokenIntType }, { "int", TokenIntType },
@ -59,15 +62,30 @@ enum LexToken LexCheckReservedWord(const Str *Word)
enum LexToken LexGetNumber(struct LexState *Lexer, union AnyValue *Value) enum LexToken LexGetNumber(struct LexState *Lexer, union AnyValue *Value)
{ {
int Result = 0; int Result = 0;
double FPResult;
double FPDiv;
while (Lexer->Pos != Lexer->End && isdigit(*Lexer->Pos)) for (; Lexer->Pos != Lexer->End && isdigit(*Lexer->Pos); Lexer->Pos++)
{
Result = Result * 10 + (*Lexer->Pos - '0'); Result = Result * 10 + (*Lexer->Pos - '0');
Lexer->Pos++;
}
Value->Integer = Result; Value->Integer = Result;
if (Lexer->Pos == Lexer->End || *Lexer->Pos != '.')
return TokenIntegerConstant; 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) enum LexToken LexGetWord(struct LexState *Lexer, union AnyValue *Value)

48
parse.c
View file

@ -81,6 +81,7 @@ int ParseType(struct LexState *Lexer, enum ValueType *Typ)
switch (Token) switch (Token)
{ {
case TokenIntType: case TokenCharType: *Typ = TypeInt; return TRUE; case TokenIntType: case TokenCharType: *Typ = TypeInt; return TRUE;
case TokenFloatType: case TokenDoubleType: *Typ = TypeFP; return TRUE;
case TokenVoidType: *Typ = TypeVoid; return TRUE; case TokenVoidType: *Typ = TypeVoid; return TRUE;
default: *Lexer = Before; return FALSE; default: *Lexer = Before; return FALSE;
} }
@ -179,11 +180,9 @@ int ParseValue(struct LexState *Lexer, struct Value *Result, struct Value **LVal
switch (Token) switch (Token)
{ {
case TokenIntegerConstant: case TokenCharacterConstant: case TokenStringConstant: case TokenIntegerConstant: case TokenCharacterConstant: Result->Typ = TypeInt; break;
Result->Typ = TypeInt; case TokenFPConstant: Result->Typ = TypeFP; break;
if (Token == TokenStringConstant) case TokenStringConstant: Result->Typ = TypeString; break;
Result->Typ = TypeString;
break;
case TokenMinus: case TokenUnaryExor: case TokenUnaryNot: case TokenMinus: case TokenUnaryExor: case TokenUnaryNot:
ParseIntExpression(Lexer, Result, RunIt); ParseIntExpression(Lexer, Result, RunIt);
@ -284,10 +283,42 @@ int ParseExpression(struct LexState *Lexer, struct Value *Result, int RunIt)
return FALSE; return FALSE;
if (RunIt) if (RunIt)
{
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
{ {
if (CurrentValue.Typ != TypeInt || TotalValue.Typ != TypeInt) if (CurrentValue.Typ != TypeInt || TotalValue.Typ != TypeInt)
ProgramFail(Lexer, "bad operand types"); ProgramFail(Lexer, "bad operand types");
/* integer arithmetic */
switch (Token) switch (Token)
{ {
case TokenPlus: TotalValue.Val.Integer += CurrentValue.Val.Integer; break; case TokenPlus: TotalValue.Val.Integer += CurrentValue.Val.Integer; break;
@ -309,6 +340,7 @@ int ParseExpression(struct LexState *Lexer, struct Value *Result, int RunIt)
} }
} }
} }
}
return TRUE; return TRUE;
} }
@ -473,6 +505,8 @@ int ParseStatement(struct LexState *Lexer, int RunIt)
case TokenIntType: case TokenIntType:
case TokenCharType: case TokenCharType:
case TokenFloatType:
case TokenDoubleType:
case TokenVoidType: case TokenVoidType:
*Lexer = PreState; *Lexer = PreState;
ParseType(Lexer, &Typ); ParseType(Lexer, &Typ);
@ -485,7 +519,11 @@ int ParseStatement(struct LexState *Lexer, int RunIt)
else else
{ {
struct Value InitValue; struct Value InitValue;
if (Typ == TokenFloatType)
InitValue.Val.FP = 0.0;
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);
} }

View file

@ -37,6 +37,7 @@ enum LexToken
TokenEOF, TokenEOF,
TokenIdentifier, TokenIdentifier,
TokenIntegerConstant, TokenIntegerConstant,
TokenFPConstant,
TokenStringConstant, TokenStringConstant,
TokenCharacterConstant, TokenCharacterConstant,
TokenType, TokenType,
@ -73,6 +74,8 @@ enum LexToken
TokenDecrement, TokenDecrement,
TokenIntType, TokenIntType,
TokenCharType, TokenCharType,
TokenFloatType,
TokenDoubleType,
TokenVoidType, TokenVoidType,
TokenDo, TokenDo,
TokenElse, TokenElse,
@ -106,6 +109,7 @@ enum ValueType
{ {
TypeVoid, TypeVoid,
TypeInt, TypeInt,
TypeFP,
TypeString, TypeString,
TypeFunction TypeFunction
}; };
@ -113,6 +117,7 @@ enum ValueType
union AnyValue union AnyValue
{ {
int Integer; int Integer;
double FP;
Str String; Str String;
}; };