t.kind = kind;
t.lexeme = strdup(lexeme);
t.intValue = 0;
+ t.floatValue = 0;
return t;
}
t.kind = TK_NUMBER;
t.intValue = value;
t.lexeme = strdup(lexeme);
+ t.floatValue = 0.0;
return t;
}
+/* makeFloatToken: create token for floating literals */
+static Token makeFloatToken(double value, const char* lexeme) {
+ Token t;
+ t.kind = TK_FLOATLIT;
+ t.floatValue = value;
+ t.lexeme = strdup(lexeme);
+ t.intValue = 0;
+ return t;
+}
+
+/* lexNum: lexing numeric literals */
+static Token lexNum(void) {
+ char buffer[256];
+ int idx = 0;
+ bool hasDot = false;
+ bool hasExponent = false;
+
+ /* capture digits */
+ while (isdigit(g_currentChar) && idx < 255) {
+ buffer[idx++] = (char)g_currentChar;
+ advance();
+ }
+
+ /* check for dot */
+ if (g_currentChar == '.') {
+ hasDot = true;
+ buffer[idx++] = (char)g_currentChar;
+ advance();
+ while (isdigit(g_currentChar) && idx < 255) {
+ buffer[idx++] = (char)g_currentChar;
+ advance();
+ }
+ }
+
+ /* check for exponent */
+ if (g_currentChar == 'e' || g_currentChar == 'E') {
+ hasExponent = true;
+ buffer[idx++] = (char)g_currentChar;
+ advance();
+ if (g_currentChar == '+' || g_currentChar == '-') {
+ buffer[idx++] = (char)g_currentChar;
+ advance();
+ }
+ while (isdigit(g_currentChar) && idx <255) {
+ buffer[idx++] = (char)g_currentChar;
+ advance();
+ }
+ }
+
+ buffer[idx] = '\0';
+
+ if (hasDot || hasExponent) {
+ double value = strtod(buffer, NULL);
+ return makeFloatToken(value, buffer);
+ } else {
+ int value = atoi(buffer);
+ return makeNumberToken(value, buffer);
+ }
+}
+
/* getNextToken: return next token from stream */
Token getNextToken(void) {
skipWhitespace();
}
}
- /* Handle operators and punctuation */
+ /* handle operators and punctuation */
if (g_currentChar == '=') {
int nextChar = fgetc(g_input);
if (nextChar == '=') {
}
}
+ /* dual equalities */
+ if (g_currentChar == '<') {
+ int nextChar = fgetc(g_input);
+ if (nextChar == '=') {
+ advance();
+ advance();
+ return makeToken(TK_LTEQ, "<=");
+ } else {
+ ungetc(nextChar, g_input);
+ advance();
+ return makeToken(TK_LT, "<");
+ }
+ }
+
+ if (g_currentChar == '>') {
+ int nextChar = fgetc(g_input);
+ if (nextChar == '=') {
+ advance();
+ advance();
+ return makeToken(TK_GTEQ, ">=");
+ } else {
+ ungetc(nextChar, g_input);
+ advance();
+ return makeToken(TK_GT, ">");
+ }
+ }
+
if (g_currentChar == '+') { advance(); return makeToken(TK_PLUS, "+"); }
if (g_currentChar == '-') { advance(); return makeToken(TK_MINUS, "-"); }
if (g_currentChar == '*') { advance(); return makeToken(TK_STAR, "*"); }
if (g_currentChar == '}') { advance(); return makeToken(TK_RBRACE, "}"); }
if (g_currentChar == ';') { advance(); return makeToken(TK_SEMICOLON, ";"); }
if (g_currentChar == ',') { advance(); return makeToken(TK_COMMA, ","); }
- if (g_currentChar == '>') { advance(); return makeToken(TK_GT, ">"); }
+ //if (g_currentChar == '>') { advance(); return makeToken(TK_GT, ">"); }
+ //if (g_currentChar == '<') { advance(); return makeToken(TK_LT, "<"); }
/* handle numeric literal */
if (isdigit(g_currentChar)) {
- char buffer[64];
- int idx = 0;
- while (isdigit(g_currentChar) && idx < 63) {
- buffer[idx++] = (char)g_currentChar;
- advance();
- }
- buffer[idx] = '\0';
- int value = atoi(buffer);
- return makeNumberToken(value, buffer);
+ return lexNum();
+ }
+ if (g_currentChar == '.') {
+ int next = fgetc(g_input);
+ ungetc(next, g_input);
+ if (isdigit(next)) return lexNum();
}
/* handle ident or keyword */
AST_EXPR_STMT, // expresison statement
AST_BINARY, // bunary expression
AST_NUM, // numeric literal
+ AST_FLOAT, // fp literal
AST_IDENT, // identifier
AST_DECL, // variable declaration
AST_CALL // function calls
char* funcName; // for function definitions
ASTNode* funcBody; // body block
int intValue; // numeric literals
+ double floatValue;
char* identName; // identifiers and operator string in binary nodes
ASTNode** args; // array of argument nodes
int argCount; // number of arguments
return node;
}
+static ASTNode* newFloatNode(double value) {
+ ASTNode* node = newASTNode(AST_FLOAT);
+ node->floatValue = value;
+ return node;
+}
+
static ASTNode* newIdentNode(const char* name) {
ASTNode* node = newASTNode(AST_IDENT);
node->identName = strdup(name);
/* equality := additive ( "==" additive )* */
static ASTNode* parseEquality(void) {
ASTNode* node = parseAdditive();
- while (g_currentToken.kind == TK_EQ || g_currentToken.kind == TK_GT) {
+ while (g_currentToken.kind == TK_EQ || g_currentToken.kind == TK_GT
+ || g_currentToken.kind == TK_LTEQ
+ || g_currentToken.kind == TK_GTEQ) {
TokenKind op = g_currentToken.kind;
nextToken();
ASTNode* rhs = parseAdditive();
node = newBinaryNode(node, rhs, "==");
else if (op == TK_GT)
node = newBinaryNode(node, rhs, ">");
+ else if (op == TK_LTEQ)
+ node = newBinaryNode(node, rhs, "<=");
+ else if (op == TK_GTEQ)
+ node = newBinaryNode(node, rhs, ">=");
}
return node;
}
nextToken();
return node;
}
+ if (g_currentToken.kind == TK_FLOATLIT) {
+ ASTNode* node = newFloatNode(g_currentToken.floatValue);
+ return node;
+ }
fprintf(stderr, "Parse err: unexpected token '%s' in factor\n", g_currentToken.lexeme);
exit(1);
return NULL; // unreachable, but silences compiler warnings.
printIndent(indent);
printf("Number (%d)\n", node->intValue);
break;
+ case AST_FLOAT:
+ printIndent(indent);
+ printf("Float (%d)\n", node->floatValue);
+ break;
case AST_IDENT:
printIndent(indent);
printf("Identifier (%s)\n", node->identName);