summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/ast-tree.c219
-rw-r--r--src/compiler/ast-tree.h19
-rw-r--r--src/compiler/lexer.c21
-rw-r--r--src/compiler/lexer.h4
-rw-r--r--src/compiler/parser.c86
-rw-r--r--src/compiler/parser.h31
-rw-r--r--src/main.c3
-rw-r--r--src/runner/runner.c308
-rw-r--r--src/utils/string.c39
-rw-r--r--src/utils/string.h6
-rw-r--r--src/utils/type.c21
-rw-r--r--src/utils/type.h20
-rw-r--r--test/main.felan18
13 files changed, 610 insertions, 185 deletions
diff --git a/src/compiler/ast-tree.c b/src/compiler/ast-tree.c
index df00517..9347303 100644
--- a/src/compiler/ast-tree.c
+++ b/src/compiler/ast-tree.c
@@ -74,6 +74,30 @@ AstTree AST_TREE_U64_TYPE = {
.type = &AST_TREE_TYPE_TYPE,
};
+AstTree AST_TREE_F16_TYPE = {
+ .token = AST_TREE_TOKEN_TYPE_F16,
+ .metadata = NULL,
+ .type = &AST_TREE_TYPE_TYPE,
+};
+
+AstTree AST_TREE_F32_TYPE = {
+ .token = AST_TREE_TOKEN_TYPE_F32,
+ .metadata = NULL,
+ .type = &AST_TREE_TYPE_TYPE,
+};
+
+AstTree AST_TREE_F64_TYPE = {
+ .token = AST_TREE_TOKEN_TYPE_F64,
+ .metadata = NULL,
+ .type = &AST_TREE_TYPE_TYPE,
+};
+
+AstTree AST_TREE_F128_TYPE = {
+ .token = AST_TREE_TOKEN_TYPE_F128,
+ .metadata = NULL,
+ .type = &AST_TREE_TYPE_TYPE,
+};
+
AstTree AST_TREE_VOID_VALUE = {
.token = AST_TREE_TOKEN_VALUE_VOID,
.metadata = NULL,
@@ -85,6 +109,7 @@ const char *AST_TREE_TOKEN_STRINGS[] = {
"AST_TREE_TOKEN_KEYWORD_PRINT_U64",
"AST_TREE_TOKEN_KEYWORD_RETURN",
+ "AST_TREE_TOKEN_KEYWORD_IF",
"AST_TREE_TOKEN_TYPE_FUNCTION",
"AST_TREE_TOKEN_TYPE_TYPE",
@@ -97,21 +122,36 @@ const char *AST_TREE_TOKEN_STRINGS[] = {
"AST_TREE_TOKEN_TYPE_U32",
"AST_TREE_TOKEN_TYPE_I64",
"AST_TREE_TOKEN_TYPE_U64",
+ "AST_TREE_TOKEN_TYPE_F16",
+ "AST_TREE_TOKEN_TYPE_F32",
+ "AST_TREE_TOKEN_TYPE_F64",
+ "AST_TREE_TOKEN_TYPE_F128",
"AST_TREE_TOKEN_TYPE_BOOL",
"AST_TREE_TOKEN_FUNCTION_CALL",
"AST_TREE_TOKEN_VARIABLE",
"AST_TREE_TOKEN_VARIABLE_DEFINE",
+ "AST_TREE_TOKEN_VALUE_VOID",
"AST_TREE_TOKEN_VALUE_INT",
+ "AST_TREE_TOKEN_VALUE_FLOAT",
"AST_TREE_TOKEN_VALUE_BOOL",
- "AST_TREE_TOKEN_VALUE_VOID",
"AST_TREE_TOKEN_OPERATOR_ASSIGN",
+ "AST_TREE_TOKEN_OPERATOR_PLUS",
+ "AST_TREE_TOKEN_OPERATOR_MINUS",
"AST_TREE_TOKEN_OPERATOR_SUM",
"AST_TREE_TOKEN_OPERATOR_SUB",
"AST_TREE_TOKEN_OPERATOR_MULTIPLY",
"AST_TREE_TOKEN_OPERATOR_DIVIDE",
"AST_TREE_TOKEN_OPERATOR_MODULO",
+ "AST_TREE_TOKEN_OPERATOR_EQUAL",
+ "AST_TREE_TOKEN_OPERATOR_NOT_EQUAL",
+ "AST_TREE_TOKEN_OPERATOR_GREATER",
+ "AST_TREE_TOKEN_OPERATOR_SMALLER",
+ "AST_TREE_TOKEN_OPERATOR_GREATER_OR_EQUAL",
+ "AST_TREE_TOKEN_OPERATOR_SMALLER_OR_EQUAL",
+
+ "AST_TREE_TOKEN_SCOPE",
"AST_TREE_TOKEN_NONE",
};
@@ -365,12 +405,20 @@ void astTreeDestroy(AstTree tree) {
case AST_TREE_TOKEN_TYPE_U32:
case AST_TREE_TOKEN_TYPE_I64:
case AST_TREE_TOKEN_TYPE_U64:
+ case AST_TREE_TOKEN_TYPE_F16:
+ case AST_TREE_TOKEN_TYPE_F32:
+ case AST_TREE_TOKEN_TYPE_F64:
+ case AST_TREE_TOKEN_TYPE_F128:
case AST_TREE_TOKEN_TYPE_BOOL:
case AST_TREE_TOKEN_VALUE_VOID:
case AST_TREE_TOKEN_VALUE_INT:
case AST_TREE_TOKEN_VALUE_BOOL:
case AST_TREE_TOKEN_VARIABLE_DEFINE:
return;
+ case AST_TREE_TOKEN_VALUE_FLOAT: {
+ free(tree.metadata);
+ return;
+ }
case AST_TREE_TOKEN_OPERATOR_PLUS:
case AST_TREE_TOKEN_OPERATOR_MINUS:
case AST_TREE_TOKEN_KEYWORD_PRINT_U64: {
@@ -502,6 +550,7 @@ AstTree *copyAstTree(AstTree *tree) {
switch (tree->token) {
case AST_TREE_TOKEN_TYPE_TYPE:
case AST_TREE_TOKEN_TYPE_VOID:
+ case AST_TREE_TOKEN_TYPE_BOOL:
case AST_TREE_TOKEN_TYPE_I8:
case AST_TREE_TOKEN_TYPE_U8:
case AST_TREE_TOKEN_TYPE_I16:
@@ -510,13 +559,23 @@ AstTree *copyAstTree(AstTree *tree) {
case AST_TREE_TOKEN_TYPE_U32:
case AST_TREE_TOKEN_TYPE_I64:
case AST_TREE_TOKEN_TYPE_U64:
- case AST_TREE_TOKEN_TYPE_BOOL:
+ case AST_TREE_TOKEN_TYPE_F16:
+ case AST_TREE_TOKEN_TYPE_F32:
+ case AST_TREE_TOKEN_TYPE_F64:
+ case AST_TREE_TOKEN_TYPE_F128:
case AST_TREE_TOKEN_VALUE_VOID:
return tree;
case AST_TREE_TOKEN_VALUE_INT:
case AST_TREE_TOKEN_VALUE_BOOL:
return newAstTree(tree->token, tree->metadata, tree->type, tree->str_begin,
tree->str_end);
+ case AST_TREE_TOKEN_VALUE_FLOAT: {
+ AstTreeFloat *metadata = tree->metadata;
+ AstTreeFloat *newMetadata = a404m_malloc(sizeof(*newMetadata));
+ *newMetadata = *metadata;
+ return newAstTree(tree->token, newMetadata, tree->type, tree->str_begin,
+ tree->str_end);
+ }
case AST_TREE_TOKEN_VARIABLE:
case AST_TREE_TOKEN_VARIABLE_DEFINE:
return newAstTree(tree->token, tree->metadata, copyAstTree(tree->type),
@@ -900,6 +959,14 @@ AstTree *astTreeParse(ParserNode *parserNode, AstTreeHelper *helper) {
return &AST_TREE_I64_TYPE;
case PARSER_TOKEN_TYPE_U64:
return &AST_TREE_U64_TYPE;
+ case PARSER_TOKEN_TYPE_F16:
+ return &AST_TREE_F16_TYPE;
+ case PARSER_TOKEN_TYPE_F32:
+ return &AST_TREE_F32_TYPE;
+ case PARSER_TOKEN_TYPE_F64:
+ return &AST_TREE_F64_TYPE;
+ case PARSER_TOKEN_TYPE_F128:
+ return &AST_TREE_F128_TYPE;
case PARSER_TOKEN_TYPE_BOOL:
return &AST_TREE_BOOL_TYPE;
case PARSER_TOKEN_FUNCTION_CALL:
@@ -911,6 +978,8 @@ AstTree *astTreeParse(ParserNode *parserNode, AstTreeHelper *helper) {
AST_TREE_TOKEN_VALUE_INT,
(void *)(AstTreeInt)(ParserNodeIntMetadata)parserNode->metadata, NULL,
parserNode->str_begin, parserNode->str_end);
+ case PARSER_TOKEN_VALUE_FLOAT:
+ return astTreeParseFloat(parserNode);
case PARSER_TOKEN_VALUE_BOOL:
return newAstTree(
AST_TREE_TOKEN_VALUE_BOOL,
@@ -1243,6 +1312,17 @@ AstTree *astTreeParseIdentifier(ParserNode *parserNode, AstTreeHelper *helper) {
parserNode->str_end);
}
+AstTree *astTreeParseFloat(ParserNode *parserNode) {
+ AstTreeFloat *metadata = a404m_malloc(sizeof(*metadata));
+
+ ParserNodeFloatMetadata *node_metadata = parserNode->metadata;
+
+ *metadata = *node_metadata;
+
+ return newAstTree(AST_TREE_TOKEN_VALUE_FLOAT, metadata, NULL,
+ parserNode->str_begin, parserNode->str_end);
+}
+
AstTree *astTreeParsePrintU64(ParserNode *parserNode, AstTreeHelper *helper) {
ParserNodeSingleChildMetadata *node_metadata = parserNode->metadata;
@@ -1750,6 +1830,7 @@ bool typeIsEqual(const AstTree *type0, const AstTree *type1) {
case AST_TREE_TOKEN_KEYWORD_IF:
case AST_TREE_TOKEN_VALUE_VOID:
case AST_TREE_TOKEN_VALUE_INT:
+ case AST_TREE_TOKEN_VALUE_FLOAT:
case AST_TREE_TOKEN_VALUE_BOOL:
case AST_TREE_TOKEN_VARIABLE_DEFINE:
case AST_TREE_TOKEN_OPERATOR_ASSIGN:
@@ -1779,6 +1860,10 @@ bool typeIsEqual(const AstTree *type0, const AstTree *type1) {
case AST_TREE_TOKEN_TYPE_I64:
case AST_TREE_TOKEN_TYPE_U64:
case AST_TREE_TOKEN_TYPE_BOOL:
+ case AST_TREE_TOKEN_TYPE_F16:
+ case AST_TREE_TOKEN_TYPE_F32:
+ case AST_TREE_TOKEN_TYPE_F64:
+ case AST_TREE_TOKEN_TYPE_F128:
return type1->token == type0->token;
case AST_TREE_TOKEN_TYPE_FUNCTION:
if (type1->token != AST_TREE_TOKEN_TYPE_FUNCTION) {
@@ -1914,6 +1999,7 @@ bool setAllTypes(AstTree *tree, AstTreeSetTypesHelper helper,
switch (tree->token) {
case AST_TREE_TOKEN_TYPE_TYPE:
case AST_TREE_TOKEN_TYPE_VOID:
+ case AST_TREE_TOKEN_TYPE_BOOL:
case AST_TREE_TOKEN_TYPE_I8:
case AST_TREE_TOKEN_TYPE_U8:
case AST_TREE_TOKEN_TYPE_I16:
@@ -1922,12 +2008,17 @@ bool setAllTypes(AstTree *tree, AstTreeSetTypesHelper helper,
case AST_TREE_TOKEN_TYPE_U32:
case AST_TREE_TOKEN_TYPE_I64:
case AST_TREE_TOKEN_TYPE_U64:
- case AST_TREE_TOKEN_TYPE_BOOL:
+ case AST_TREE_TOKEN_TYPE_F16:
+ case AST_TREE_TOKEN_TYPE_F32:
+ case AST_TREE_TOKEN_TYPE_F64:
+ case AST_TREE_TOKEN_TYPE_F128:
case AST_TREE_TOKEN_VALUE_VOID:
case AST_TREE_TOKEN_VALUE_BOOL:
return true;
case AST_TREE_TOKEN_VALUE_INT:
return setTypesValueInt(tree, helper);
+ case AST_TREE_TOKEN_VALUE_FLOAT:
+ return setTypesValueFloat(tree, helper);
case AST_TREE_TOKEN_FUNCTION:
return setTypesFunction(tree, helper);
case AST_TREE_TOKEN_KEYWORD_PRINT_U64:
@@ -1977,46 +2068,146 @@ bool setTypesValueInt(AstTree *tree, AstTreeSetTypesHelper helper) {
tree->type = &AST_TREE_U64_TYPE;
} else if (helper.lookingType == &AST_TREE_I32_TYPE) {
AstTreeInt value = (AstTreeInt)tree->metadata;
- if (value & 0xffffffff00000000) {
+ i32 newValue = value;
+ tree->metadata = (void *)(u64)newValue;
+ if (value - newValue != 0) {
printWarning(tree->str_begin, tree->str_end, "Value is overflowing");
}
tree->type = &AST_TREE_I32_TYPE;
} else if (helper.lookingType == &AST_TREE_U32_TYPE) {
AstTreeInt value = (AstTreeInt)tree->metadata;
- if (value & 0xffffffff00000000) {
+ u32 newValue = value;
+ tree->metadata = (void *)(u64)newValue;
+ if (value - newValue != 0) {
printWarning(tree->str_begin, tree->str_end, "Value is overflowing");
}
tree->type = &AST_TREE_U32_TYPE;
} else if (helper.lookingType == &AST_TREE_I16_TYPE) {
AstTreeInt value = (AstTreeInt)tree->metadata;
- if (value & 0xffffffffffff0000) {
+ i16 newValue = value;
+ tree->metadata = (void *)(u64)newValue;
+ if (value - newValue != 0) {
printWarning(tree->str_begin, tree->str_end, "Value is overflowing");
}
tree->type = &AST_TREE_I16_TYPE;
} else if (helper.lookingType == &AST_TREE_U16_TYPE) {
AstTreeInt value = (AstTreeInt)tree->metadata;
- if (value & 0xffffffffffff0000) {
+ u16 newValue = value;
+ tree->metadata = (void *)(u64)newValue;
+ if (value - newValue != 0) {
printWarning(tree->str_begin, tree->str_end, "Value is overflowing");
}
tree->type = &AST_TREE_U16_TYPE;
} else if (helper.lookingType == &AST_TREE_I8_TYPE) {
AstTreeInt value = (AstTreeInt)tree->metadata;
- if (value & 0xffffffffffffff00) {
+ i8 newValue = value;
+ tree->metadata = (void *)(u64)newValue;
+ if (value - newValue != 0) {
printWarning(tree->str_begin, tree->str_end, "Value is overflowing");
}
tree->type = &AST_TREE_I8_TYPE;
} else if (helper.lookingType == &AST_TREE_U8_TYPE) {
AstTreeInt value = (AstTreeInt)tree->metadata;
- if (value & 0xffffffffffffff00) {
+ u8 newValue = value;
+ tree->metadata = (void *)(u64)newValue;
+ if (value - newValue != 0) {
printWarning(tree->str_begin, tree->str_end, "Value is overflowing");
}
tree->type = &AST_TREE_U8_TYPE;
+ } else if (helper.lookingType == &AST_TREE_F16_TYPE) {
+ tree->token = AST_TREE_TOKEN_VALUE_FLOAT;
+ AstTreeInt value = (AstTreeInt)tree->metadata;
+ f16 newValue = value;
+ tree->metadata = a404m_malloc(sizeof(f128));
+ *(f128 *)tree->metadata = value;
+ if (value - newValue != 0) {
+ printWarning(tree->str_begin, tree->str_end, "Value is overflowing");
+ }
+ tree->type = &AST_TREE_F16_TYPE;
+ } else if (helper.lookingType == &AST_TREE_F32_TYPE) {
+ tree->token = AST_TREE_TOKEN_VALUE_FLOAT;
+ AstTreeInt value = (AstTreeInt)tree->metadata;
+ f32 newValue = value;
+ tree->metadata = a404m_malloc(sizeof(f128));
+ *(f128 *)tree->metadata = value;
+ if (value - newValue != 0) {
+ printWarning(tree->str_begin, tree->str_end, "Value is overflowing");
+ }
+ tree->type = &AST_TREE_F32_TYPE;
+ } else if (helper.lookingType == &AST_TREE_F64_TYPE) {
+ tree->token = AST_TREE_TOKEN_VALUE_FLOAT;
+ AstTreeInt value = (AstTreeInt)tree->metadata;
+ f64 newValue = value;
+ tree->metadata = a404m_malloc(sizeof(f128));
+ *(f128 *)tree->metadata = value;
+ if (value - newValue != 0) {
+ printWarning(tree->str_begin, tree->str_end, "Value is overflowing");
+ }
+ tree->type = &AST_TREE_F64_TYPE;
+ } else if (helper.lookingType == &AST_TREE_F128_TYPE) {
+ tree->token = AST_TREE_TOKEN_VALUE_FLOAT;
+ AstTreeInt value = (AstTreeInt)tree->metadata;
+ f128 newValue = value;
+ tree->metadata = a404m_malloc(sizeof(f128));
+ *(f128 *)tree->metadata = value;
+ if (value - newValue != 0) {
+ printWarning(tree->str_begin, tree->str_end, "Value is overflowing");
+ }
+ tree->type = &AST_TREE_F128_TYPE;
} else {
UNREACHABLE;
}
return true;
}
+bool setTypesValueFloat(AstTree *tree, AstTreeSetTypesHelper helper) {
+ if (helper.lookingType == &AST_TREE_F16_TYPE) {
+ tree->token = AST_TREE_TOKEN_VALUE_FLOAT;
+ AstTreeFloat value = *(AstTreeFloat *)tree->metadata;
+ f16 newValue = value;
+ tree->metadata = a404m_malloc(sizeof(f128));
+ *(f128 *)tree->metadata = value;
+ if (value - newValue != 0) {
+ printWarning(tree->str_begin, tree->str_end, "Value is overflowing");
+ }
+ tree->type = &AST_TREE_F16_TYPE;
+ } else if (helper.lookingType == &AST_TREE_F32_TYPE) {
+ tree->token = AST_TREE_TOKEN_VALUE_FLOAT;
+ AstTreeFloat value = *(AstTreeFloat *)tree->metadata;
+ f32 newValue = value;
+ tree->metadata = a404m_malloc(sizeof(f128));
+ *(f128 *)tree->metadata = value;
+ if (value - newValue != 0) {
+ printWarning(tree->str_begin, tree->str_end, "Value is overflowing");
+ }
+ tree->type = &AST_TREE_F32_TYPE;
+ } else if (helper.lookingType == &AST_TREE_F64_TYPE) {
+ tree->token = AST_TREE_TOKEN_VALUE_FLOAT;
+ AstTreeFloat value = *(AstTreeFloat *)tree->metadata;
+ f64 newValue = value;
+ tree->metadata = a404m_malloc(sizeof(f128));
+ *(f128 *)tree->metadata = value;
+ if (value - newValue != 0) {
+ printWarning(tree->str_begin, tree->str_end, "Value is overflowing");
+ }
+ tree->type = &AST_TREE_F64_TYPE;
+ } else if (helper.lookingType == &AST_TREE_F128_TYPE) {
+ tree->token = AST_TREE_TOKEN_VALUE_FLOAT;
+ AstTreeFloat value = *(AstTreeFloat *)tree->metadata;
+ f128 newValue = value;
+ tree->metadata = a404m_malloc(sizeof(f128));
+ *(f128 *)tree->metadata = value;
+ if (value - newValue != 0) {
+ printWarning(tree->str_begin, tree->str_end, "Value is overflowing");
+ }
+ tree->type = &AST_TREE_F128_TYPE;
+ } else {
+ UNREACHABLE;
+ }
+
+ return true;
+}
+
bool setTypesFunction(AstTree *tree, AstTreeSetTypesHelper helper) {
AstTreeFunction *metadata = tree->metadata;
@@ -2225,7 +2416,8 @@ bool setTypesAstVariable(AstTreeVariable *variable,
return false;
} else if (variable->value != NULL &&
!typeIsEqual(variable->value->type, variable->type)) {
- printError(variable->name_begin, variable->name_end, "Type mismatch");
+ printError(variable->name_begin, variable->name_end, "Type mismatch %s",
+ AST_TREE_TOKEN_STRINGS[variable->value->token]);
return false;
}
@@ -2311,6 +2503,7 @@ bool astTreeClean(AstTree *tree) {
case AST_TREE_TOKEN_TYPE_TYPE:
case AST_TREE_TOKEN_TYPE_FUNCTION:
case AST_TREE_TOKEN_TYPE_VOID:
+ case AST_TREE_TOKEN_TYPE_BOOL:
case AST_TREE_TOKEN_TYPE_I8:
case AST_TREE_TOKEN_TYPE_U8:
case AST_TREE_TOKEN_TYPE_I16:
@@ -2319,11 +2512,15 @@ bool astTreeClean(AstTree *tree) {
case AST_TREE_TOKEN_TYPE_U32:
case AST_TREE_TOKEN_TYPE_I64:
case AST_TREE_TOKEN_TYPE_U64:
- case AST_TREE_TOKEN_TYPE_BOOL:
+ case AST_TREE_TOKEN_TYPE_F16:
+ case AST_TREE_TOKEN_TYPE_F32:
+ case AST_TREE_TOKEN_TYPE_F64:
+ case AST_TREE_TOKEN_TYPE_F128:
case AST_TREE_TOKEN_FUNCTION_CALL:
case AST_TREE_TOKEN_VALUE_VOID:
case AST_TREE_TOKEN_VALUE_INT:
case AST_TREE_TOKEN_VALUE_BOOL:
+ case AST_TREE_TOKEN_VALUE_FLOAT:
case AST_TREE_TOKEN_VARIABLE_DEFINE:
case AST_TREE_TOKEN_OPERATOR_ASSIGN:
case AST_TREE_TOKEN_OPERATOR_PLUS:
diff --git a/src/compiler/ast-tree.h b/src/compiler/ast-tree.h
index c7253a0..eaf8b07 100644
--- a/src/compiler/ast-tree.h
+++ b/src/compiler/ast-tree.h
@@ -23,6 +23,10 @@ typedef enum AstTreeToken {
AST_TREE_TOKEN_TYPE_U32,
AST_TREE_TOKEN_TYPE_I64,
AST_TREE_TOKEN_TYPE_U64,
+ AST_TREE_TOKEN_TYPE_F16,
+ AST_TREE_TOKEN_TYPE_F32,
+ AST_TREE_TOKEN_TYPE_F64,
+ AST_TREE_TOKEN_TYPE_F128,
AST_TREE_TOKEN_TYPE_BOOL,
AST_TREE_TOKEN_STATIC_VARS_END = AST_TREE_TOKEN_TYPE_BOOL,
@@ -31,6 +35,7 @@ typedef enum AstTreeToken {
AST_TREE_TOKEN_VARIABLE_DEFINE,
AST_TREE_TOKEN_VALUE_VOID,
AST_TREE_TOKEN_VALUE_INT,
+ AST_TREE_TOKEN_VALUE_FLOAT,
AST_TREE_TOKEN_VALUE_BOOL,
AST_TREE_TOKEN_OPERATOR_ASSIGN,
@@ -74,6 +79,10 @@ extern AstTree AST_TREE_I32_TYPE;
extern AstTree AST_TREE_U32_TYPE;
extern AstTree AST_TREE_I64_TYPE;
extern AstTree AST_TREE_U64_TYPE;
+extern AstTree AST_TREE_F16_TYPE;
+extern AstTree AST_TREE_F32_TYPE;
+extern AstTree AST_TREE_F64_TYPE;
+extern AstTree AST_TREE_F128_TYPE;
extern AstTree AST_TREE_VOID_VALUE;
typedef struct AstTreeVariable {
@@ -117,7 +126,9 @@ typedef struct AstTreeFunctionCall {
size_t parameters_size;
} AstTreeFunctionCall;
-typedef uint64_t AstTreeInt;
+typedef u64 AstTreeInt;
+
+typedef f128 AstTreeFloat;
typedef bool AstTreeBool;
@@ -177,6 +188,7 @@ AstTree *astTreeParseTypeFunction(ParserNode *parserNode,
AstTree *astTreeParseFunctionCall(ParserNode *parserNode,
AstTreeHelper *helper);
AstTree *astTreeParseIdentifier(ParserNode *parserNode, AstTreeHelper *helper);
+AstTree *astTreeParseFloat(ParserNode *parserNode);
AstTree *astTreeParsePrintU64(ParserNode *parserNode, AstTreeHelper *helper);
AstTree *astTreeParseReturn(ParserNode *parserNode, AstTreeHelper *helper);
AstTree *astTreeParseBinaryOperator(ParserNode *parserNode,
@@ -188,9 +200,7 @@ AstTree *astTreeParseVariable(ParserNode *parserNode, AstTreeHelper *helper);
AstTree *astTreeParseIf(ParserNode *parserNode, AstTreeHelper *helper);
AstTree *astTreeParseCurlyBracket(ParserNode *parserNode,
AstTreeHelper *helper);
-AstTree *astTreeParseParenthesis(ParserNode *parserNode,
- AstTreeHelper *helper);
-
+AstTree *astTreeParseParenthesis(ParserNode *parserNode, AstTreeHelper *helper);
AstTreeFunction *getFunction(AstTree *value);
bool isConst(AstTree *value);
@@ -204,6 +214,7 @@ bool setAllTypesRoot(AstTreeRoot *root, AstTreeHelper *helper);
bool setAllTypes(AstTree *tree, AstTreeSetTypesHelper helper,
AstTreeFunction *function);
bool setTypesValueInt(AstTree *tree, AstTreeSetTypesHelper helper);
+bool setTypesValueFloat(AstTree *tree, AstTreeSetTypesHelper helper);
bool setTypesFunction(AstTree *tree, AstTreeSetTypesHelper helper);
bool setTypesPrintU64(AstTree *tree, AstTreeSetTypesHelper helper);
bool setTypesReturn(AstTree *tree, AstTreeSetTypesHelper helper,
diff --git a/src/compiler/lexer.c b/src/compiler/lexer.c
index c740dd3..7fef9be 100644
--- a/src/compiler/lexer.c
+++ b/src/compiler/lexer.c
@@ -22,6 +22,10 @@ const char *LEXER_TOKEN_STRINGS[] = {
"LEXER_TOKEN_KEYWORD_U32",
"LEXER_TOKEN_KEYWORD_I64",
"LEXER_TOKEN_KEYWORD_U64",
+ "LEXER_TOKEN_KEYWORD_F16",
+ "LEXER_TOKEN_KEYWORD_F32",
+ "LEXER_TOKEN_KEYWORD_F64",
+ "LEXER_TOKEN_KEYWORD_F128",
"LEXER_TOKEN_KEYWORD_BOOL",
"LEXER_TOKEN_KEYWORD_PRINT_U64",
"LEXER_TOKEN_KEYWORD_RETURN",
@@ -89,9 +93,9 @@ const size_t LEXER_SYMBOL_SIZE =
sizeof(LEXER_SYMBOL_TOKENS) / sizeof(*LEXER_SYMBOL_TOKENS);
const char *LEXER_KEYWORD_STRINGS[] = {
- "type", "void", "i8", "u8", "i16", "u16",
- "i32", "u32", "i64", "u64", "bool", "print_u64",
- "return", "true", "false", "if", "else",
+ "type", "void", "i8", "u8", "i16", "u16", "i32",
+ "u32", "i64", "u64", "f16", "f32", "f64", "f128",
+ "bool", "print_u64", "return", "true", "false", "if", "else",
};
const LexerToken LEXER_KEYWORD_TOKENS[] = {
LEXER_TOKEN_KEYWORD_TYPE, LEXER_TOKEN_KEYWORD_VOID,
@@ -99,6 +103,8 @@ const LexerToken LEXER_KEYWORD_TOKENS[] = {
LEXER_TOKEN_KEYWORD_I16, LEXER_TOKEN_KEYWORD_U16,
LEXER_TOKEN_KEYWORD_I32, LEXER_TOKEN_KEYWORD_U32,
LEXER_TOKEN_KEYWORD_I64, LEXER_TOKEN_KEYWORD_U64,
+ LEXER_TOKEN_KEYWORD_F16, LEXER_TOKEN_KEYWORD_F32,
+ LEXER_TOKEN_KEYWORD_F64, LEXER_TOKEN_KEYWORD_F128,
LEXER_TOKEN_KEYWORD_BOOL, LEXER_TOKEN_KEYWORD_PRINT_U64,
LEXER_TOKEN_KEYWORD_RETURN, LEXER_TOKEN_KEYWORD_TRUE,
LEXER_TOKEN_KEYWORD_FALSE, LEXER_TOKEN_KEYWORD_IF,
@@ -172,7 +178,8 @@ LexerNodeArray lexer(char *str) {
lexerPushClear(&result, &result_size, iter, &node_str_begin, &node_token,
LEXER_TOKEN_NONE);
} else if (isIdentifier(c)) {
- if (node_token != LEXER_TOKEN_IDENTIFIER) {
+ if (node_token != LEXER_TOKEN_IDENTIFIER &&
+ node_token != LEXER_TOKEN_NUMBER) {
lexerPushClear(&result, &result_size, iter, &node_str_begin,
&node_token, LEXER_TOKEN_IDENTIFIER);
}
@@ -237,6 +244,10 @@ void lexerPushClear(LexerNodeArray *array, size_t *array_size, char *iter,
case LEXER_TOKEN_KEYWORD_U32:
case LEXER_TOKEN_KEYWORD_I64:
case LEXER_TOKEN_KEYWORD_U64:
+ case LEXER_TOKEN_KEYWORD_F16:
+ case LEXER_TOKEN_KEYWORD_F32:
+ case LEXER_TOKEN_KEYWORD_F64:
+ case LEXER_TOKEN_KEYWORD_F128:
case LEXER_TOKEN_KEYWORD_BOOL:
case LEXER_TOKEN_KEYWORD_PRINT_U64:
case LEXER_TOKEN_KEYWORD_RETURN:
@@ -295,7 +306,7 @@ bool isIdentifier(char c) {
return ('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z') || c == '_';
}
-bool isNumber(char c) { return '0' <= c && c <= '9'; }
+bool isNumber(char c) { return ('0' <= c && c <= '9') || c == '.'; }
bool isSymbol(char c) {
switch (c) {
diff --git a/src/compiler/lexer.h b/src/compiler/lexer.h
index af2e7a3..0a6da3a 100644
--- a/src/compiler/lexer.h
+++ b/src/compiler/lexer.h
@@ -15,6 +15,10 @@ typedef enum LexerToken {
LEXER_TOKEN_KEYWORD_U32,
LEXER_TOKEN_KEYWORD_I64,
LEXER_TOKEN_KEYWORD_U64,
+ LEXER_TOKEN_KEYWORD_F16,
+ LEXER_TOKEN_KEYWORD_F32,
+ LEXER_TOKEN_KEYWORD_F64,
+ LEXER_TOKEN_KEYWORD_F128,
LEXER_TOKEN_KEYWORD_BOOL,
LEXER_TOKEN_KEYWORD_PRINT_U64,
LEXER_TOKEN_KEYWORD_RETURN,
diff --git a/src/compiler/parser.c b/src/compiler/parser.c
index 367c490..84dca1c 100644
--- a/src/compiler/parser.c
+++ b/src/compiler/parser.c
@@ -15,11 +15,13 @@ const char *PARSER_TOKEN_STRINGS[] = {
"PARSER_TOKEN_IDENTIFIER",
"PARSER_TOKEN_VALUE_INT",
+ "PARSER_TOKEN_VALUE_FLOAT",
"PARSER_TOKEN_VALUE_BOOL",
"PARSER_TOKEN_TYPE_TYPE",
"PARSER_TOKEN_TYPE_FUNCTION",
"PARSER_TOKEN_TYPE_VOID",
+ "PARSER_TOKEN_TYPE_BOOL",
"PARSER_TOKEN_TYPE_I8",
"PARSER_TOKEN_TYPE_U8",
"PARSER_TOKEN_TYPE_I16",
@@ -28,7 +30,10 @@ const char *PARSER_TOKEN_STRINGS[] = {
"PARSER_TOKEN_TYPE_U32",
"PARSER_TOKEN_TYPE_I64",
"PARSER_TOKEN_TYPE_U64",
- "PARSER_TOKEN_TYPE_BOOL",
+ "PARSER_TOKEN_TYPE_F16",
+ "PARSER_TOKEN_TYPE_F32",
+ "PARSER_TOKEN_TYPE_F64",
+ "PARSER_TOKEN_TYPE_F128",
"PARSER_TOKEN_KEYWORD_PRINT_U64",
"PARSER_TOKEN_KEYWORD_RETURN",
@@ -75,6 +80,8 @@ static constexpr ParserOrder PARSER_ORDER[] = {
LEXER_TOKEN_KEYWORD_U8, LEXER_TOKEN_KEYWORD_I16,
LEXER_TOKEN_KEYWORD_U16, LEXER_TOKEN_KEYWORD_I32,
LEXER_TOKEN_KEYWORD_U32, LEXER_TOKEN_KEYWORD_I64,
+ LEXER_TOKEN_KEYWORD_F16, LEXER_TOKEN_KEYWORD_F32,
+ LEXER_TOKEN_KEYWORD_F64, LEXER_TOKEN_KEYWORD_F128,
LEXER_TOKEN_KEYWORD_U64, LEXER_TOKEN_KEYWORD_BOOL,
LEXER_TOKEN_KEYWORD_TRUE, LEXER_TOKEN_KEYWORD_FALSE,
LEXER_TOKEN_NUMBER, ),
@@ -158,6 +165,7 @@ void parserNodePrint(const ParserNode *node, int indent) {
case PARSER_TOKEN_IDENTIFIER:
case PARSER_TOKEN_TYPE_TYPE:
case PARSER_TOKEN_TYPE_VOID:
+ case PARSER_TOKEN_TYPE_BOOL:
case PARSER_TOKEN_TYPE_I8:
case PARSER_TOKEN_TYPE_U8:
case PARSER_TOKEN_TYPE_I16:
@@ -166,13 +174,21 @@ void parserNodePrint(const ParserNode *node, int indent) {
case PARSER_TOKEN_TYPE_U32:
case PARSER_TOKEN_TYPE_I64:
case PARSER_TOKEN_TYPE_U64:
- case PARSER_TOKEN_TYPE_BOOL:
+ case PARSER_TOKEN_TYPE_F16:
+ case PARSER_TOKEN_TYPE_F32:
+ case PARSER_TOKEN_TYPE_F64:
+ case PARSER_TOKEN_TYPE_F128:
goto RETURN_SUCCESS;
case PARSER_TOKEN_VALUE_INT: {
ParserNodeIntMetadata metadata = (ParserNodeIntMetadata)node->metadata;
printf(",operand=%ld", metadata);
}
goto RETURN_SUCCESS;
+ case PARSER_TOKEN_VALUE_FLOAT: {
+ ParserNodeFloatMetadata *metadata = node->metadata;
+ printf(",operand=%Lf", *metadata);
+ }
+ goto RETURN_SUCCESS;
case PARSER_TOKEN_VALUE_BOOL: {
ParserNodeIntMetadata metadata = (ParserNodeIntMetadata)node->metadata;
printf(",value=%b", (ParserNodeBoolMetadata)metadata);
@@ -368,6 +384,7 @@ void parserNodeDelete(ParserNode *node) {
case PARSER_TOKEN_IDENTIFIER:
case PARSER_TOKEN_TYPE_TYPE:
case PARSER_TOKEN_TYPE_VOID:
+ case PARSER_TOKEN_TYPE_BOOL:
case PARSER_TOKEN_TYPE_I8:
case PARSER_TOKEN_TYPE_U8:
case PARSER_TOKEN_TYPE_I16:
@@ -376,10 +393,18 @@ void parserNodeDelete(ParserNode *node) {
case PARSER_TOKEN_TYPE_U32:
case PARSER_TOKEN_TYPE_I64:
case PARSER_TOKEN_TYPE_U64:
- case PARSER_TOKEN_TYPE_BOOL:
+ case PARSER_TOKEN_TYPE_F16:
+ case PARSER_TOKEN_TYPE_F32:
+ case PARSER_TOKEN_TYPE_F64:
+ case PARSER_TOKEN_TYPE_F128:
case PARSER_TOKEN_VALUE_INT:
case PARSER_TOKEN_VALUE_BOOL:
goto RETURN_SUCCESS;
+ case PARSER_TOKEN_VALUE_FLOAT: {
+ ParserNodeFloatMetadata *metadata = node->metadata;
+ free(metadata);
+ }
+ goto RETURN_SUCCESS;
case PARSER_TOKEN_CONSTANT:
case PARSER_TOKEN_VARIABLE: {
ParserNodeVariableMetadata *metadata = node->metadata;
@@ -586,6 +611,14 @@ ParserNode *parseNode(LexerNode *node, LexerNode *begin, LexerNode *end,
return parserNoMetadata(node, parent, PARSER_TOKEN_TYPE_U64);
case LEXER_TOKEN_KEYWORD_BOOL:
return parserNoMetadata(node, parent, PARSER_TOKEN_TYPE_BOOL);
+ case LEXER_TOKEN_KEYWORD_F16:
+ return parserNoMetadata(node, parent, PARSER_TOKEN_TYPE_F16);
+ case LEXER_TOKEN_KEYWORD_F32:
+ return parserNoMetadata(node, parent, PARSER_TOKEN_TYPE_F32);
+ case LEXER_TOKEN_KEYWORD_F64:
+ return parserNoMetadata(node, parent, PARSER_TOKEN_TYPE_F64);
+ case LEXER_TOKEN_KEYWORD_F128:
+ return parserNoMetadata(node, parent, PARSER_TOKEN_TYPE_F128);
case LEXER_TOKEN_KEYWORD_PRINT_U64:
return parserPrintU64(node, end, parent);
case LEXER_TOKEN_KEYWORD_RETURN:
@@ -804,13 +837,22 @@ ParserNode *parserNumber(LexerNode *node, ParserNode *parent) {
default: {
bool success;
uint64_t value = decimalToU64(node->str_begin, node->str_end, &success);
- if (!success) {
- printError(node->str_begin, node->str_end, "Error in parsing number");
- return NULL;
+ if (success) {
+ parserNode =
+ newParserNode(PARSER_TOKEN_VALUE_INT, node->str_begin, node->str_end,
+ (void *)(ParserNodeIntMetadata)value, parent);
+ } else {
+ ParserNodeFloatMetadata *metadata = a404m_malloc(sizeof(*metadata));
+ *metadata = numberToFloat(node->str_begin, node->str_end, &success);
+
+ if (success) {
+ parserNode = newParserNode(PARSER_TOKEN_VALUE_FLOAT, node->str_begin,
+ node->str_end, metadata, parent);
+ } else {
+ printError(node->str_begin, node->str_end, "Error in parsing number");
+ return NULL;
+ }
}
- parserNode =
- newParserNode(PARSER_TOKEN_VALUE_INT, node->str_begin, node->str_end,
- (void *)(ParserNodeIntMetadata)value, parent);
}
}
return node->parserNode = parserNode;
@@ -1020,10 +1062,12 @@ ParserNode *parserFunction(LexerNode *node, LexerNode *begin, LexerNode *end,
case PARSER_TOKEN_ROOT:
case PARSER_TOKEN_IDENTIFIER:
case PARSER_TOKEN_VALUE_INT:
+ case PARSER_TOKEN_VALUE_FLOAT:
case PARSER_TOKEN_VALUE_BOOL:
case PARSER_TOKEN_TYPE_TYPE:
case PARSER_TOKEN_TYPE_FUNCTION:
case PARSER_TOKEN_TYPE_VOID:
+ case PARSER_TOKEN_TYPE_BOOL:
case PARSER_TOKEN_TYPE_I8:
case PARSER_TOKEN_TYPE_U8:
case PARSER_TOKEN_TYPE_I16:
@@ -1032,7 +1076,10 @@ ParserNode *parserFunction(LexerNode *node, LexerNode *begin, LexerNode *end,
case PARSER_TOKEN_TYPE_U32:
case PARSER_TOKEN_TYPE_I64:
case PARSER_TOKEN_TYPE_U64:
- case PARSER_TOKEN_TYPE_BOOL:
+ case PARSER_TOKEN_TYPE_F16:
+ case PARSER_TOKEN_TYPE_F32:
+ case PARSER_TOKEN_TYPE_F64:
+ case PARSER_TOKEN_TYPE_F128:
case PARSER_TOKEN_KEYWORD_PRINT_U64:
case PARSER_TOKEN_KEYWORD_RETURN:
case PARSER_TOKEN_CONSTANT:
@@ -1352,6 +1399,7 @@ bool isExpression(ParserNode *node) {
case PARSER_TOKEN_OPERATOR_GREATER_OR_EQUAL:
case PARSER_TOKEN_OPERATOR_SMALLER_OR_EQUAL:
case PARSER_TOKEN_VALUE_INT:
+ case PARSER_TOKEN_VALUE_FLOAT:
case PARSER_TOKEN_VALUE_BOOL:
case PARSER_TOKEN_KEYWORD_IF:
return true;
@@ -1359,6 +1407,7 @@ bool isExpression(ParserNode *node) {
case PARSER_TOKEN_TYPE_TYPE:
case PARSER_TOKEN_TYPE_FUNCTION:
case PARSER_TOKEN_TYPE_VOID:
+ case PARSER_TOKEN_TYPE_BOOL:
case PARSER_TOKEN_TYPE_I8:
case PARSER_TOKEN_TYPE_U8:
case PARSER_TOKEN_TYPE_I16:
@@ -1367,7 +1416,10 @@ bool isExpression(ParserNode *node) {
case PARSER_TOKEN_TYPE_U32:
case PARSER_TOKEN_TYPE_I64:
case PARSER_TOKEN_TYPE_U64:
- case PARSER_TOKEN_TYPE_BOOL:
+ case PARSER_TOKEN_TYPE_F16:
+ case PARSER_TOKEN_TYPE_F32:
+ case PARSER_TOKEN_TYPE_F64:
+ case PARSER_TOKEN_TYPE_F128:
case PARSER_TOKEN_SYMBOL_EOL:
case PARSER_TOKEN_SYMBOL_CURLY_BRACKET:
case PARSER_TOKEN_SYMBOL_COMMA:
@@ -1390,6 +1442,10 @@ bool isType(ParserNode *node) {
case PARSER_TOKEN_TYPE_U32:
case PARSER_TOKEN_TYPE_I64:
case PARSER_TOKEN_TYPE_U64:
+ case PARSER_TOKEN_TYPE_F16:
+ case PARSER_TOKEN_TYPE_F32:
+ case PARSER_TOKEN_TYPE_F64:
+ case PARSER_TOKEN_TYPE_F128:
case PARSER_TOKEN_TYPE_BOOL:
return true;
case PARSER_TOKEN_IDENTIFIER:
@@ -1403,6 +1459,7 @@ bool isType(ParserNode *node) {
case PARSER_TOKEN_SYMBOL_COMMA:
case PARSER_TOKEN_FUNCTION_CALL:
case PARSER_TOKEN_VALUE_INT:
+ case PARSER_TOKEN_VALUE_FLOAT:
case PARSER_TOKEN_VALUE_BOOL:
case PARSER_TOKEN_KEYWORD_PRINT_U64:
case PARSER_TOKEN_KEYWORD_RETURN:
@@ -1432,6 +1489,7 @@ bool isValue(ParserNode *node) {
case PARSER_TOKEN_FUNCTION_DEFINITION:
case PARSER_TOKEN_FUNCTION_CALL:
case PARSER_TOKEN_VALUE_INT:
+ case PARSER_TOKEN_VALUE_FLOAT:
case PARSER_TOKEN_VALUE_BOOL:
case PARSER_TOKEN_IDENTIFIER:
case PARSER_TOKEN_OPERATOR_ASSIGN:
@@ -1450,6 +1508,7 @@ bool isValue(ParserNode *node) {
case PARSER_TOKEN_OPERATOR_SMALLER_OR_EQUAL:
case PARSER_TOKEN_TYPE_TYPE:
case PARSER_TOKEN_TYPE_VOID:
+ case PARSER_TOKEN_TYPE_BOOL:
case PARSER_TOKEN_TYPE_I8:
case PARSER_TOKEN_TYPE_U8:
case PARSER_TOKEN_TYPE_I16:
@@ -1458,7 +1517,10 @@ bool isValue(ParserNode *node) {
case PARSER_TOKEN_TYPE_U32:
case PARSER_TOKEN_TYPE_I64:
case PARSER_TOKEN_TYPE_U64:
- case PARSER_TOKEN_TYPE_BOOL:
+ case PARSER_TOKEN_TYPE_F16:
+ case PARSER_TOKEN_TYPE_F32:
+ case PARSER_TOKEN_TYPE_F64:
+ case PARSER_TOKEN_TYPE_F128:
case PARSER_TOKEN_KEYWORD_IF:
return true;
case PARSER_TOKEN_TYPE_FUNCTION:
diff --git a/src/compiler/parser.h b/src/compiler/parser.h
index 4e8c298..3af47e7 100644
--- a/src/compiler/parser.h
+++ b/src/compiler/parser.h
@@ -1,6 +1,7 @@
#pragma once
#include "compiler/lexer.h"
+#include "utils/type.h"
#include <stddef.h>
#include <stdint.h>
@@ -10,11 +11,13 @@ typedef enum ParserToken {
PARSER_TOKEN_IDENTIFIER,
PARSER_TOKEN_VALUE_INT,
+ PARSER_TOKEN_VALUE_FLOAT,
PARSER_TOKEN_VALUE_BOOL,
PARSER_TOKEN_TYPE_TYPE,
PARSER_TOKEN_TYPE_FUNCTION,
PARSER_TOKEN_TYPE_VOID,
+ PARSER_TOKEN_TYPE_BOOL,
PARSER_TOKEN_TYPE_I8,
PARSER_TOKEN_TYPE_U8,
PARSER_TOKEN_TYPE_I16,
@@ -23,7 +26,10 @@ typedef enum ParserToken {
PARSER_TOKEN_TYPE_U32,
PARSER_TOKEN_TYPE_I64,
PARSER_TOKEN_TYPE_U64,
- PARSER_TOKEN_TYPE_BOOL,
+ PARSER_TOKEN_TYPE_F16,
+ PARSER_TOKEN_TYPE_F32,
+ PARSER_TOKEN_TYPE_F64,
+ PARSER_TOKEN_TYPE_F128,
PARSER_TOKEN_KEYWORD_PRINT_U64,
PARSER_TOKEN_KEYWORD_RETURN,
@@ -104,7 +110,9 @@ typedef struct ParserNodeFunctionCall {
typedef ParserNode ParserNodeSingleChildMetadata;
-typedef uint64_t ParserNodeIntMetadata;
+typedef u64 ParserNodeIntMetadata;
+
+typedef f128 ParserNodeFloatMetadata;
typedef struct ParserNodeInfixMetadata {
ParserNode *left;
@@ -121,7 +129,7 @@ typedef struct ParserNodeIfMetadata {
ParserNode *condition;
ParserNode *ifBody;
ParserNode *elseBody;
-}ParserNodeIfMetadata;
+} ParserNodeIfMetadata;
void parserNodePrint(const ParserNode *node, int indent);
void parserNodeDelete(ParserNode *node);
@@ -136,11 +144,15 @@ ParserNode *parseNode(LexerNode *node, LexerNode *begin, LexerNode *end,
ParserNode *parent, bool *conti);
ParserNode *getUntilCommonParent(ParserNode *node, ParserNode *parent);
-ParserNode *getUntilCommonParents(ParserNode *node, ParserNode *parent,ParserNode *parent2);
-ParserNode *getNextUsingCommonParent(LexerNode *node,LexerNode *end, ParserNode *parent);
-LexerNode *getNextLexerNodeUsingCommonParent(LexerNode *node,LexerNode *end, ParserNode *parent);
-
-ParserNode *parserNoMetadata(LexerNode *node, ParserNode *parent,ParserToken token);
+ParserNode *getUntilCommonParents(ParserNode *node, ParserNode *parent,
+ ParserNode *parent2);
+ParserNode *getNextUsingCommonParent(LexerNode *node, LexerNode *end,
+ ParserNode *parent);
+LexerNode *getNextLexerNodeUsingCommonParent(LexerNode *node, LexerNode *end,
+ ParserNode *parent);
+
+ParserNode *parserNoMetadata(LexerNode *node, ParserNode *parent,
+ ParserToken token);
ParserNode *parserPrintU64(LexerNode *node, LexerNode *end, ParserNode *parent);
ParserNode *parserReturn(LexerNode *node, LexerNode *end, ParserNode *parent);
ParserNode *parserNumber(LexerNode *node, ParserNode *parent);
@@ -162,8 +174,7 @@ ParserNode *parserBinaryOrLeftOperator(LexerNode *node, LexerNode *begin,
LexerNode *end, ParserNode *parent,
ParserToken token,
LexerToken laterToken);
-ParserNode *parserIf(LexerNode *node, LexerNode *end,
- ParserNode *parent);
+ParserNode *parserIf(LexerNode *node, LexerNode *end, ParserNode *parent);
bool isAllArguments(const ParserNodeArray *nodes);
diff --git a/src/main.c b/src/main.c
index 8a61324..8e8bf3f 100644
--- a/src/main.c
+++ b/src/main.c
@@ -2,6 +2,7 @@
#include "runner/runner.h"
#include "utils/file.h"
#include "utils/log.h"
+#include "utils/type.h"
#include <stdio.h>
#include <stdlib.h>
@@ -103,7 +104,9 @@ static int run(const char *filePath, bool shouldPrint) {
}
int main(int argc, char *argv[]) {
+ checkTypes();
fileInit();
+
if (argc < 2) {
// compileRun("test/main.felan", "build/out", false);
// run("test/main.felan", false);
diff --git a/src/runner/runner.c b/src/runner/runner.c
index 4f2a002..4c9dc2e 100644
--- a/src/runner/runner.c
+++ b/src/runner/runner.c
@@ -6,6 +6,123 @@
#include <stdlib.h>
#include <string.h>
+#define doOperation(op0, op1, operator, originalType, type) \
+ (op0)->metadata = (void *)(u64)((type)(originalType)(op0) \
+ ->metadata \
+ operator(type)(originalType)(op1) \
+ ->metadata)
+
+#define doOperationFloat(op0, op1, operator, originalType, type) \
+ (op0)->metadata = \
+ (void *)(u64)((type) * (originalType *)(op0)->metadata operator(type) * \
+ (originalType *)(op1)->metadata)
+
+#define doLogicalOperation(op0, op1, operator, originalType, type) \
+ (op0)->metadata = (void *)(u64)(bool)((type)(originalType)(op0) \
+ ->metadata \
+ operator(type)(originalType)(op1) \
+ ->metadata)
+
+#define doLogicalOperationFloat(op0, op1, operator, originalType, type) \
+ (op0)->metadata = \
+ (void *)(u64)(bool)((type) * \
+ (originalType *)(op0)->metadata operator(type) * \
+ (originalType *)(op1)->metadata)
+
+#define doLeftOperation(op0, operator, originalType, type) \
+ (op0)->metadata = (void *)(u64)(operator(type)(originalType)(op0)->metadata)
+
+#define doLeftOperationFloat(op0, operator, originalType, type) \
+ (op0)->metadata = \
+ (void *)(u64)(operator(type) * (originalType *)(op0)->metadata)
+
+#define doAllOperationsInt(op0, op1, operator, originalType, type) \
+ switch (operator) { \
+ case AST_TREE_TOKEN_OPERATOR_SUM: \
+ doOperation(op0, op1, +, originalType, type); \
+ break; \
+ case AST_TREE_TOKEN_OPERATOR_SUB: \
+ doOperation(op0, op1, -, originalType, type); \
+ break; \
+ case AST_TREE_TOKEN_OPERATOR_MULTIPLY: \
+ doOperation(op0, op1, *, originalType, type); \
+ break; \
+ case AST_TREE_TOKEN_OPERATOR_DIVIDE: \
+ doOperation(op0, op1, /, originalType, type); \
+ break; \
+ case AST_TREE_TOKEN_OPERATOR_MODULO: \
+ doOperation(op0, op1, %, originalType, type); \
+ break; \
+ case AST_TREE_TOKEN_OPERATOR_PLUS: \
+ doLeftOperation(op0, +, originalType, type); \
+ break; \
+ case AST_TREE_TOKEN_OPERATOR_MINUS: \
+ doLeftOperation(op0, -, originalType, type); \
+ break; \
+ case AST_TREE_TOKEN_OPERATOR_EQUAL: \
+ doLogicalOperation(op0, op1, ==, originalType, type); \
+ break; \
+ case AST_TREE_TOKEN_OPERATOR_NOT_EQUAL: \
+ doLogicalOperation(op0, op1, !=, originalType, type); \
+ break; \
+ case AST_TREE_TOKEN_OPERATOR_GREATER: \
+ doLogicalOperation(op0, op1, >, originalType, type); \
+ break; \
+ case AST_TREE_TOKEN_OPERATOR_GREATER_OR_EQUAL: \
+ doLogicalOperation(op0, op1, >=, originalType, type); \
+ break; \
+ case AST_TREE_TOKEN_OPERATOR_SMALLER: \
+ doLogicalOperation(op0, op1, <, originalType, type); \
+ break; \
+ case AST_TREE_TOKEN_OPERATOR_SMALLER_OR_EQUAL: \
+ doLogicalOperation(op0, op1, <=, originalType, type); \
+ break; \
+ default: \
+ UNREACHABLE; \
+ }
+
+#define doAllOperationsFloat(op0, op1, operator, originalType, type) \
+ switch (operator) { \
+ case AST_TREE_TOKEN_OPERATOR_SUM: \
+ doOperationFloat(op0, op1, +, originalType, type); \
+ break; \
+ case AST_TREE_TOKEN_OPERATOR_SUB: \
+ doOperationFloat(op0, op1, -, originalType, type); \
+ break; \
+ case AST_TREE_TOKEN_OPERATOR_MULTIPLY: \
+ doOperationFloat(op0, op1, *, originalType, type); \
+ break; \
+ case AST_TREE_TOKEN_OPERATOR_DIVIDE: \
+ doOperationFloat(op0, op1, /, originalType, type); \
+ break; \
+ case AST_TREE_TOKEN_OPERATOR_PLUS: \
+ doLeftOperationFloat(op0, +, originalType, type); \
+ break; \
+ case AST_TREE_TOKEN_OPERATOR_MINUS: \
+ doLeftOperationFloat(op0, -, originalType, type); \
+ break; \
+ case AST_TREE_TOKEN_OPERATOR_EQUAL: \
+ doLogicalOperationFloat(op0, op1, ==, originalType, type); \
+ break; \
+ case AST_TREE_TOKEN_OPERATOR_NOT_EQUAL: \
+ doLogicalOperationFloat(op0, op1, !=, originalType, type); \
+ break; \
+ case AST_TREE_TOKEN_OPERATOR_GREATER: \
+ doLogicalOperationFloat(op0, op1, >, originalType, type); \
+ break; \
+ case AST_TREE_TOKEN_OPERATOR_GREATER_OR_EQUAL: \
+ doLogicalOperationFloat(op0, op1, >=, originalType, type); \
+ break; \
+ case AST_TREE_TOKEN_OPERATOR_SMALLER: \
+ doLogicalOperationFloat(op0, op1, <, originalType, type); \
+ break; \
+ case AST_TREE_TOKEN_OPERATOR_SMALLER_OR_EQUAL: \
+ doLogicalOperationFloat(op0, op1, <=, originalType, type); \
+ break; \
+ default: \
+ UNREACHABLE; \
+ }
+
void runnerVariablesDelete(RunnerVariables *variables) {
for (size_t i = 0; i < variables->size; ++i) {
if (variables->data[i]->value != NULL) {
@@ -277,12 +394,23 @@ AstTree *runExpression(AstTree *expr, RunnerVariablePages *pages) {
case AST_TREE_TOKEN_TYPE_TYPE:
case AST_TREE_TOKEN_TYPE_FUNCTION:
case AST_TREE_TOKEN_TYPE_VOID:
+ case AST_TREE_TOKEN_TYPE_BOOL:
+ case AST_TREE_TOKEN_TYPE_I8:
+ case AST_TREE_TOKEN_TYPE_U8:
+ case AST_TREE_TOKEN_TYPE_I16:
+ case AST_TREE_TOKEN_TYPE_U16:
+ case AST_TREE_TOKEN_TYPE_I32:
+ case AST_TREE_TOKEN_TYPE_U32:
case AST_TREE_TOKEN_TYPE_I64:
case AST_TREE_TOKEN_TYPE_U64:
- case AST_TREE_TOKEN_TYPE_BOOL:
+ case AST_TREE_TOKEN_TYPE_F16:
+ case AST_TREE_TOKEN_TYPE_F32:
+ case AST_TREE_TOKEN_TYPE_F64:
+ case AST_TREE_TOKEN_TYPE_F128:
case AST_TREE_TOKEN_VARIABLE:
case AST_TREE_TOKEN_VALUE_VOID:
case AST_TREE_TOKEN_VALUE_INT:
+ case AST_TREE_TOKEN_VALUE_FLOAT:
case AST_TREE_TOKEN_VALUE_BOOL:
case AST_TREE_TOKEN_NONE:
}
@@ -294,7 +422,8 @@ AstTree *calcAstTreeValue(AstTree *tree, RunnerVariablePages *pages) {
case AST_TREE_TOKEN_VALUE_VOID:
case AST_TREE_TOKEN_VALUE_INT:
case AST_TREE_TOKEN_VALUE_BOOL:
- return deepCopyAstTree(tree);
+ case AST_TREE_TOKEN_VALUE_FLOAT:
+ return copyAstTree(tree);
case AST_TREE_TOKEN_VARIABLE: {
AstTreeVariable *variable = tree->metadata;
return calcAstTreeValue(runnerVariableGetValue(pages, variable), pages);
@@ -325,91 +454,46 @@ AstTree *calcAstTreeValue(AstTree *tree, RunnerVariablePages *pages) {
AstTree *left = calcAstTreeValue(&metadata->left, pages);
AstTree *right = calcAstTreeValue(&metadata->right, pages);
- if ((left->type == &AST_TREE_U64_TYPE &&
- right->type == &AST_TREE_U64_TYPE) ||
- (left->type == &AST_TREE_I64_TYPE &&
- right->type == &AST_TREE_I64_TYPE) ||
- (left->type == &AST_TREE_U32_TYPE &&
- right->type == &AST_TREE_U32_TYPE) ||
- (left->type == &AST_TREE_I32_TYPE &&
- right->type == &AST_TREE_I32_TYPE) ||
- (left->type == &AST_TREE_U16_TYPE &&
- right->type == &AST_TREE_U16_TYPE) ||
- (left->type == &AST_TREE_I16_TYPE &&
- right->type == &AST_TREE_I16_TYPE) ||
- (left->type == &AST_TREE_U8_TYPE &&
- right->type == &AST_TREE_U8_TYPE) ||
- (left->type == &AST_TREE_I8_TYPE &&
- right->type == &AST_TREE_I8_TYPE)) {
- if (left->token == AST_TREE_TOKEN_VALUE_INT &&
- right->token == AST_TREE_TOKEN_VALUE_INT) {
- switch (tree->token) {
- case AST_TREE_TOKEN_OPERATOR_SUM:
- left->metadata = (void *)((AstTreeInt)left->metadata +
- (AstTreeInt)right->metadata);
- break;
- case AST_TREE_TOKEN_OPERATOR_SUB:
- left->metadata = (void *)((AstTreeInt)left->metadata -
- (AstTreeInt)right->metadata);
- break;
- case AST_TREE_TOKEN_OPERATOR_MULTIPLY:
- left->metadata = (void *)((AstTreeInt)left->metadata *
- (AstTreeInt)right->metadata);
- break;
- case AST_TREE_TOKEN_OPERATOR_DIVIDE:
- left->metadata = (void *)((AstTreeInt)left->metadata /
- (AstTreeInt)right->metadata);
- break;
- case AST_TREE_TOKEN_OPERATOR_MODULO:
- left->metadata = (void *)((AstTreeInt)left->metadata %
- (AstTreeInt)right->metadata);
- break;
- case AST_TREE_TOKEN_OPERATOR_EQUAL:
- left->metadata = (void *)(bool)((AstTreeInt)left->metadata ==
- (AstTreeInt)right->metadata);
- astTreeDelete(left->type);
- left->type = &AST_TREE_U64_TYPE;
- break;
- case AST_TREE_TOKEN_OPERATOR_NOT_EQUAL:
- left->metadata = (void *)(bool)((AstTreeInt)left->metadata ==
- (AstTreeInt)right->metadata);
- astTreeDelete(left->type);
- left->type = &AST_TREE_U64_TYPE;
- break;
- case AST_TREE_TOKEN_OPERATOR_GREATER:
- left->metadata = (void *)(bool)((AstTreeInt)left->metadata >
- (AstTreeInt)right->metadata);
- astTreeDelete(left->type);
- left->type = &AST_TREE_U64_TYPE;
- break;
- case AST_TREE_TOKEN_OPERATOR_SMALLER:
- left->metadata = (void *)(bool)((AstTreeInt)left->metadata <
- (AstTreeInt)right->metadata);
- astTreeDelete(left->type);
- left->type = &AST_TREE_U64_TYPE;
- break;
- case AST_TREE_TOKEN_OPERATOR_GREATER_OR_EQUAL:
- left->metadata = (void *)(bool)((AstTreeInt)left->metadata >=
- (AstTreeInt)right->metadata);
- astTreeDelete(left->type);
- left->type = &AST_TREE_U64_TYPE;
- break;
- case AST_TREE_TOKEN_OPERATOR_SMALLER_OR_EQUAL:
- left->metadata = (void *)(bool)((AstTreeInt)left->metadata <=
- (AstTreeInt)right->metadata);
- astTreeDelete(left->type);
- left->type = &AST_TREE_U64_TYPE;
- break;
- default:
- UNREACHABLE;
- }
- astTreeDelete(right);
- return left;
- } else {
- UNREACHABLE;
- }
+ if (left->type == &AST_TREE_U64_TYPE && right->type == &AST_TREE_U64_TYPE) {
+ doAllOperationsInt(left, right, tree->token, AstTreeInt, u64);
+ } else if (left->type == &AST_TREE_I64_TYPE &&
+ right->type == &AST_TREE_I64_TYPE) {
+ doAllOperationsInt(left, right, tree->token, AstTreeInt, i64);
+ } else if (left->type == &AST_TREE_U32_TYPE &&
+ right->type == &AST_TREE_U32_TYPE) {
+ doAllOperationsInt(left, right, tree->token, AstTreeInt, u32);
+ } else if (left->type == &AST_TREE_I32_TYPE &&
+ right->type == &AST_TREE_I32_TYPE) {
+ doAllOperationsInt(left, right, tree->token, AstTreeInt, i32);
+ } else if (left->type == &AST_TREE_U16_TYPE &&
+ right->type == &AST_TREE_U16_TYPE) {
+ doAllOperationsInt(left, right, tree->token, AstTreeInt, u16);
+ } else if (left->type == &AST_TREE_I16_TYPE &&
+ right->type == &AST_TREE_I16_TYPE) {
+ doAllOperationsInt(left, right, tree->token, AstTreeInt, i16);
+ } else if (left->type == &AST_TREE_U8_TYPE &&
+ right->type == &AST_TREE_U8_TYPE) {
+ doAllOperationsInt(left, right, tree->token, AstTreeInt, u8);
+ } else if (left->type == &AST_TREE_I8_TYPE &&
+ right->type == &AST_TREE_I8_TYPE) {
+ doAllOperationsInt(left, right, tree->token, AstTreeInt, i8);
+ } else if (left->type == &AST_TREE_F128_TYPE &&
+ right->type == &AST_TREE_F128_TYPE) {
+ doAllOperationsFloat(left, right, tree->token, AstTreeFloat, f128);
+ } else if (left->type == &AST_TREE_F64_TYPE &&
+ right->type == &AST_TREE_F64_TYPE) {
+ doAllOperationsFloat(left, right, tree->token, AstTreeFloat, f64);
+ } else if (left->type == &AST_TREE_F32_TYPE &&
+ right->type == &AST_TREE_F32_TYPE) {
+ doAllOperationsFloat(left, right, tree->token, AstTreeFloat, f32);
+ } else if (left->type == &AST_TREE_F16_TYPE &&
+ right->type == &AST_TREE_F16_TYPE) {
+ doAllOperationsFloat(left, right, tree->token, AstTreeFloat, f16);
+ } else {
+ UNREACHABLE;
}
- UNREACHABLE;
+ astTreeDelete(right);
+ return left;
}
case AST_TREE_TOKEN_OPERATOR_PLUS:
case AST_TREE_TOKEN_OPERATOR_MINUS: {
@@ -442,51 +526,21 @@ AstTree *calcAstTreeValue(AstTree *tree, RunnerVariablePages *pages) {
case AST_TREE_TOKEN_TYPE_TYPE:
case AST_TREE_TOKEN_TYPE_FUNCTION:
case AST_TREE_TOKEN_TYPE_VOID:
- case AST_TREE_TOKEN_TYPE_I64:
- case AST_TREE_TOKEN_TYPE_U64:
case AST_TREE_TOKEN_TYPE_BOOL:
- case AST_TREE_TOKEN_VARIABLE_DEFINE:
- case AST_TREE_TOKEN_OPERATOR_ASSIGN:
- case AST_TREE_TOKEN_SCOPE:
- case AST_TREE_TOKEN_NONE:
- }
- UNREACHABLE;
-}
-
-AstTree *deepCopyAstTree(AstTree *tree) {
- switch (tree->token) {
- case AST_TREE_TOKEN_VALUE_VOID:
- case AST_TREE_TOKEN_VALUE_INT:
- case AST_TREE_TOKEN_VALUE_BOOL:
- return newAstTree(tree->token, tree->metadata, copyAstTree(tree->type),
- NULL, NULL);
- case AST_TREE_TOKEN_VARIABLE:
- case AST_TREE_TOKEN_FUNCTION:
- case AST_TREE_TOKEN_KEYWORD_PRINT_U64:
- case AST_TREE_TOKEN_KEYWORD_RETURN:
- case AST_TREE_TOKEN_TYPE_TYPE:
- case AST_TREE_TOKEN_TYPE_FUNCTION:
- case AST_TREE_TOKEN_TYPE_VOID:
+ case AST_TREE_TOKEN_TYPE_I8:
+ case AST_TREE_TOKEN_TYPE_U8:
+ case AST_TREE_TOKEN_TYPE_I16:
+ case AST_TREE_TOKEN_TYPE_U16:
+ case AST_TREE_TOKEN_TYPE_I32:
+ case AST_TREE_TOKEN_TYPE_U32:
+ case AST_TREE_TOKEN_TYPE_I64:
case AST_TREE_TOKEN_TYPE_U64:
- case AST_TREE_TOKEN_TYPE_BOOL:
- case AST_TREE_TOKEN_FUNCTION_CALL:
+ case AST_TREE_TOKEN_TYPE_F16:
+ case AST_TREE_TOKEN_TYPE_F32:
+ case AST_TREE_TOKEN_TYPE_F64:
+ case AST_TREE_TOKEN_TYPE_F128:
case AST_TREE_TOKEN_VARIABLE_DEFINE:
case AST_TREE_TOKEN_OPERATOR_ASSIGN:
- case AST_TREE_TOKEN_OPERATOR_PLUS:
- case AST_TREE_TOKEN_OPERATOR_MINUS:
- case AST_TREE_TOKEN_OPERATOR_SUM:
- case AST_TREE_TOKEN_OPERATOR_SUB:
- case AST_TREE_TOKEN_OPERATOR_MULTIPLY:
- case AST_TREE_TOKEN_OPERATOR_DIVIDE:
- case AST_TREE_TOKEN_OPERATOR_MODULO:
- case AST_TREE_TOKEN_OPERATOR_EQUAL:
- case AST_TREE_TOKEN_OPERATOR_NOT_EQUAL:
- case AST_TREE_TOKEN_OPERATOR_GREATER:
- case AST_TREE_TOKEN_OPERATOR_SMALLER:
- case AST_TREE_TOKEN_OPERATOR_GREATER_OR_EQUAL:
- case AST_TREE_TOKEN_OPERATOR_SMALLER_OR_EQUAL:
- case AST_TREE_TOKEN_KEYWORD_IF:
- case AST_TREE_TOKEN_TYPE_I64:
case AST_TREE_TOKEN_SCOPE:
case AST_TREE_TOKEN_NONE:
}
diff --git a/src/utils/string.c b/src/utils/string.c
index 5f9b7de..ee8a354 100644
--- a/src/utils/string.c
+++ b/src/utils/string.c
@@ -1,5 +1,6 @@
#include "string.h"
#include "memory.h"
+#include "utils/type.h"
#include <stdint.h>
#include <string.h>
@@ -15,8 +16,8 @@ size_t searchInStringArray(const char *array[], size_t array_size,
return array_size;
}
-uint64_t decimalToU64(char *str_begin, char *str_end, bool *success) {
- uint64_t result = 0;
+u64 decimalToU64(char *str_begin, char *str_end, bool *success) {
+ u64 result = 0;
while (str_begin < str_end) {
if (*str_begin < '0' || *str_begin > '9') {
@@ -32,7 +33,39 @@ uint64_t decimalToU64(char *str_begin, char *str_end, bool *success) {
return result;
}
-char *u64ToString(uint64_t value) {
+f128 numberToFloat(char *str_begin, char *str_end, bool *success) {
+ f64 left = 0;
+ f64 right = 0;
+ bool isPastPoint = false;
+
+ while (str_begin < str_end) {
+ char c;
+ if (isPastPoint) {
+ c = *--str_end;
+ } else {
+ c = *str_begin++;
+ }
+ if (c >= '0' && c <= '9') {
+ if (isPastPoint) {
+ left *= 10;
+ left += c - '0';
+ } else {
+ right /= 10;
+ right += c - '0';
+ }
+ } else if (c == '.' && !isPastPoint) {
+ isPastPoint = true;
+ } else {
+ *success = false;
+ return 0;
+ }
+ }
+
+ *success = true;
+ return left + right;
+}
+
+char *u64ToString(u64 value) {
char *str = a404m_malloc(21 * sizeof(*str));
size_t i = 0;
diff --git a/src/utils/string.h b/src/utils/string.h
index 8f92bc4..54130e5 100644
--- a/src/utils/string.h
+++ b/src/utils/string.h
@@ -1,10 +1,12 @@
#pragma once
+#include "utils/type.h"
#include <stddef.h>
#include <stdint.h>
size_t searchInStringArray(const char *array[], size_t array_size,
const char *str, size_t str_size);
-uint64_t decimalToU64(char *str_begin, char *str_end, bool *success);
-char* u64ToString(uint64_t value);
+u64 decimalToU64(char *str_begin, char *str_end, bool *success);
+f128 numberToFloat(char *str_begin, char *str_end, bool *success);
+char* u64ToString(u64 value);
diff --git a/src/utils/type.c b/src/utils/type.c
new file mode 100644
index 0000000..dea08ef
--- /dev/null
+++ b/src/utils/type.c
@@ -0,0 +1,21 @@
+#include "type.h"
+
+#include <assert.h>
+
+void checkTypes() {
+ assert(sizeof(i8) == (8 / 8));
+ assert(sizeof(i16) == (16 / 8));
+ assert(sizeof(i32) == (32 / 8));
+ assert(sizeof(i64) == (64 / 8));
+
+ assert(sizeof(u8) == (8 / 8));
+ assert(sizeof(u16) == (16 / 8));
+ assert(sizeof(u32) == (32 / 8));
+ assert(sizeof(u64) == (64 / 8));
+
+ assert(sizeof(f16) == (16 / 8));
+ assert(sizeof(f32) == (32 / 8));
+ assert(sizeof(f64) == (64 / 8));
+ assert(sizeof(f128) == (128 / 8));
+}
+
diff --git a/src/utils/type.h b/src/utils/type.h
new file mode 100644
index 0000000..aad46df
--- /dev/null
+++ b/src/utils/type.h
@@ -0,0 +1,20 @@
+#pragma once
+
+#include <stdint.h>
+
+typedef int8_t i8;
+typedef int16_t i16;
+typedef int32_t i32;
+typedef int64_t i64;
+
+typedef uint8_t u8;
+typedef uint16_t u16;
+typedef uint32_t u32;
+typedef uint64_t u64;
+
+typedef _Float16 f16;
+typedef float f32;
+typedef double f64;
+typedef long double f128;
+
+void checkTypes();
diff --git a/test/main.felan b/test/main.felan
index fb8e2e0..4b635bb 100644
--- a/test/main.felan
+++ b/test/main.felan
@@ -1,14 +1,10 @@
main :: () -> void {
- a :i8 = 121312;
- b :u8 = 1;
- c :i16 = 1;
- d :u16 = 1;
- e :i32 = 1;
- f :u32 = 1;
- g :i64 = 1;
- h :u64 = 1;
- if a == 2
- print_u64 h;
+ a :f32 = 23;
+ b :f64 = 54.5;
+ c :f128 = 1.0;
+ d :f16 = 5.5;
+ if a == 23
+ print_u64 1;
else
- print_u64 h+2;
+ print_u64 2;
};