summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--code/main.felan18
-rw-r--r--src/compiler/ast-tree.c18
-rw-r--r--src/compiler/ast-tree.h2
-rw-r--r--src/compiler/lexer.c33
-rw-r--r--src/compiler/lexer.h2
-rw-r--r--src/compiler/parser.c37
-rw-r--r--src/compiler/parser.h8
7 files changed, 91 insertions, 27 deletions
diff --git a/code/main.felan b/code/main.felan
index e7348c7..5609e27 100644
--- a/code/main.felan
+++ b/code/main.felan
@@ -17,21 +17,7 @@ long_double :: f128;
usize :: u64;
-array :: (t:type) -> type {
- return struct {
- ptr : *t;
- length : usize;
- };
-};
-
-array_int :: array(u64);
-array_int1 :: array(u64);
-array_int2 :: array(i64);
-
main :: () -> void {
- print_u64 (if array_int == array_int1 1 else 0);
- print_u64 (if array_int == array_int2 1 else 0);
-};
-
-comptime {
+ a := 'a';
+ print_u64 (if a == 97 1 else 0);
};
diff --git a/src/compiler/ast-tree.c b/src/compiler/ast-tree.c
index 239f9b4..678c533 100644
--- a/src/compiler/ast-tree.c
+++ b/src/compiler/ast-tree.c
@@ -1237,6 +1237,7 @@ AstTreeRoot *makeAstTree(ParserNode *parsedRoot) {
case PARSER_TOKEN_VALUE_BOOL:
case PARSER_TOKEN_VALUE_INT:
case PARSER_TOKEN_VALUE_FLOAT:
+ case PARSER_TOKEN_VALUE_CHAR:
case PARSER_TOKEN_FUNCTION_DEFINITION:
case PARSER_TOKEN_FUNCTION_CALL:
case PARSER_TOKEN_IDENTIFIER:
@@ -1462,13 +1463,16 @@ AstTree *astTreeParse(ParserNode *parserNode, AstTreeHelper *helper) {
return astTreeParseIdentifier(parserNode, helper);
case PARSER_TOKEN_VALUE_INT:
return astTreeParseValue(parserNode, AST_TREE_TOKEN_VALUE_INT,
- sizeof(AstTreeInt));
+ sizeof(AstTreeInt), NULL);
case PARSER_TOKEN_VALUE_FLOAT:
return astTreeParseValue(parserNode, AST_TREE_TOKEN_VALUE_FLOAT,
- sizeof(AstTreeFloat));
+ sizeof(AstTreeFloat), NULL);
case PARSER_TOKEN_VALUE_BOOL:
return astTreeParseValue(parserNode, AST_TREE_TOKEN_VALUE_BOOL,
- sizeof(AstTreeBool));
+ sizeof(AstTreeBool), NULL);
+ case PARSER_TOKEN_VALUE_CHAR:
+ return astTreeParseValue(parserNode, AST_TREE_TOKEN_VALUE_INT,
+ sizeof(AstTreeInt), &AST_TREE_U8_TYPE);
case PARSER_TOKEN_KEYWORD_NULL:
return astTreeParseKeyword(parserNode, AST_TREE_TOKEN_VALUE_NULL);
case PARSER_TOKEN_KEYWORD_UNDEFINED:
@@ -1657,6 +1661,7 @@ AstTree *astTreeParseFunction(ParserNode *parserNode, AstTreeHelper *p_helper) {
case PARSER_TOKEN_VALUE_INT:
case PARSER_TOKEN_VALUE_FLOAT:
case PARSER_TOKEN_VALUE_BOOL:
+ case PARSER_TOKEN_VALUE_CHAR:
case PARSER_TOKEN_TYPE_TYPE:
case PARSER_TOKEN_TYPE_FUNCTION:
case PARSER_TOKEN_TYPE_VOID:
@@ -1893,11 +1898,11 @@ AstTree *astTreeParseIdentifier(ParserNode *parserNode, AstTreeHelper *helper) {
}
AstTree *astTreeParseValue(ParserNode *parserNode, AstTreeToken token,
- size_t metadata_size) {
+ size_t metadata_size, AstTree *type) {
void *metadata = a404m_malloc(metadata_size);
memcpy(metadata, parserNode->metadata, metadata_size);
- return newAstTree(token, metadata, NULL, parserNode->str_begin,
+ return newAstTree(token, metadata, type, parserNode->str_begin,
parserNode->str_end);
}
@@ -2203,6 +2208,7 @@ AstTree *astTreeParseCurlyBracket(ParserNode *parserNode,
case PARSER_TOKEN_VALUE_INT:
case PARSER_TOKEN_VALUE_FLOAT:
case PARSER_TOKEN_VALUE_BOOL:
+ case PARSER_TOKEN_VALUE_CHAR:
case PARSER_TOKEN_TYPE_TYPE:
case PARSER_TOKEN_TYPE_FUNCTION:
case PARSER_TOKEN_TYPE_VOID:
@@ -3344,7 +3350,7 @@ bool setTypesValueFloat(AstTree *tree, AstTreeSetTypesHelper helper) {
printWarning(tree->str_begin, tree->str_end, "Value is overflowing");
}
tree->type = &AST_TREE_F16_TYPE;
- #endif
+#endif
} else if (typeIsEqual(helper.lookingType, &AST_TREE_F32_TYPE)) {
tree->token = AST_TREE_TOKEN_VALUE_FLOAT;
AstTreeFloat value = *(AstTreeFloat *)tree->metadata;
diff --git a/src/compiler/ast-tree.h b/src/compiler/ast-tree.h
index 4617ce4..fb708af 100644
--- a/src/compiler/ast-tree.h
+++ b/src/compiler/ast-tree.h
@@ -260,7 +260,7 @@ AstTree *astTreeParseFunctionCall(ParserNode *parserNode,
AstTreeHelper *helper);
AstTree *astTreeParseIdentifier(ParserNode *parserNode, AstTreeHelper *helper);
AstTree *astTreeParseValue(ParserNode *parserNode, AstTreeToken token,
- size_t metadata_size);
+ size_t metadata_size,AstTree *type);
AstTree *astTreeParseKeyword(ParserNode *parserNode, AstTreeToken token);
AstTree *astTreeParsePrintU64(ParserNode *parserNode, AstTreeHelper *helper);
AstTree *astTreeParseReturn(ParserNode *parserNode, AstTreeHelper *helper);
diff --git a/src/compiler/lexer.c b/src/compiler/lexer.c
index 0f971d7..43ea4c1 100644
--- a/src/compiler/lexer.c
+++ b/src/compiler/lexer.c
@@ -41,6 +41,7 @@ const char *LEXER_TOKEN_STRINGS[] = {
"LEXER_TOKEN_KEYWORD_UNDEFINED",
"LEXER_TOKEN_NUMBER",
+ "LEXER_TOKEN_CHAR",
"LEXER_TOKEN_SYMBOL",
"LEXER_TOKEN_SYMBOL_EOL",
@@ -193,12 +194,15 @@ LexerNodeArray lexer(char *str) {
&node_token, LEXER_TOKEN_NONE);
++iter;
int in = 1;
+ char *openingIter = iter - 2;
+
for (; in != 0; ++iter) {
if (*iter == '*' && *(iter + 1) == '/') {
--in;
} else if (*iter == '/' && *(iter + 1) == '*') {
++in;
} else if (*iter == '\0') {
+ printError(openingIter, openingIter + 2, "No closing */ found");
goto RETURN_ERROR;
}
}
@@ -211,6 +215,23 @@ LexerNodeArray lexer(char *str) {
if (isSpace(c)) {
lexerPushClear(&result, &result_size, iter, &node_str_begin, &node_token,
LEXER_TOKEN_NONE);
+ } else if (isString(c)) {
+ lexerPushClear(&result, &result_size, iter, &node_str_begin, &node_token,
+ LEXER_TOKEN_CHAR);
+ const char opening = c;
+ char *openingIter = iter;
+ ++iter;
+ for (;; ++iter) {
+ if (*iter == '\0') {
+ printError(openingIter, openingIter + 1, "No closing `%c` found",
+ opening);
+ goto RETURN_ERROR;
+ } else if (*iter == '\\') {
+ ++iter;
+ } else if (*iter == '\'') {
+ break;
+ }
+ }
} else if (isIdentifier(c) ||
(node_token == LEXER_TOKEN_IDENTIFIER && isNumber(c))) {
if (node_token != LEXER_TOKEN_IDENTIFIER &&
@@ -300,6 +321,7 @@ void lexerPushClear(LexerNodeArray *array, size_t *array_size, char *iter,
case LEXER_TOKEN_KEYWORD_STRUCT:
case LEXER_TOKEN_KEYWORD_UNDEFINED:
case LEXER_TOKEN_NUMBER:
+ case LEXER_TOKEN_CHAR:
case LEXER_TOKEN_SYMBOL_EOL:
case LEXER_TOKEN_SYMBOL_OPEN_PARENTHESIS:
case LEXER_TOKEN_SYMBOL_CLOSE_PARENTHESIS:
@@ -397,6 +419,17 @@ bool isSpace(char c) {
case ' ':
case '\n':
case '\t':
+ case '\v':
+ return true;
+ default:
+ return false;
+ }
+}
+
+extern bool isString(char c) {
+ switch (c) {
+ case '\'':
+ case '\"':
return true;
default:
return false;
diff --git a/src/compiler/lexer.h b/src/compiler/lexer.h
index 8759e10..42f7aa8 100644
--- a/src/compiler/lexer.h
+++ b/src/compiler/lexer.h
@@ -36,6 +36,7 @@ typedef enum LexerToken {
LEXER_TOKEN_KEYWORD_UNDEFINED,
LEXER_TOKEN_NUMBER,
+ LEXER_TOKEN_CHAR,
LEXER_TOKEN_SYMBOL,
LEXER_TOKEN_SYMBOL_EOL,
@@ -114,3 +115,4 @@ extern bool isNumber(char c);
extern bool isSymbol(char c);
extern bool isCompleteSymbol(char *str, size_t str_size);
extern bool isSpace(char c);
+extern bool isString(char c);
diff --git a/src/compiler/parser.c b/src/compiler/parser.c
index 951d3b4..8df9b2d 100644
--- a/src/compiler/parser.c
+++ b/src/compiler/parser.c
@@ -17,6 +17,7 @@ const char *PARSER_TOKEN_STRINGS[] = {
"PARSER_TOKEN_VALUE_INT",
"PARSER_TOKEN_VALUE_FLOAT",
"PARSER_TOKEN_VALUE_BOOL",
+ "PARSER_TOKEN_VALUE_CHAR",
"PARSER_TOKEN_TYPE_TYPE",
"PARSER_TOKEN_TYPE_FUNCTION",
@@ -109,7 +110,8 @@ static const ParserOrder PARSER_ORDER[] = {
LEXER_TOKEN_KEYWORD_F128, LEXER_TOKEN_KEYWORD_U64,
LEXER_TOKEN_KEYWORD_BOOL, LEXER_TOKEN_KEYWORD_TRUE,
LEXER_TOKEN_KEYWORD_FALSE, LEXER_TOKEN_KEYWORD_NULL,
- LEXER_TOKEN_NUMBER, LEXER_TOKEN_KEYWORD_UNDEFINED, ),
+ LEXER_TOKEN_NUMBER, LEXER_TOKEN_CHAR,
+ LEXER_TOKEN_KEYWORD_UNDEFINED, ),
},
{
.ltr = false,
@@ -234,6 +236,11 @@ void parserNodePrint(const ParserNode *node, int indent) {
printf(",value=%b", *metadata);
}
goto RETURN_SUCCESS;
+ case PARSER_TOKEN_VALUE_CHAR: {
+ ParserNodeCharMetadata *metadata = node->metadata;
+ printf(",value=%c", (char)*metadata);
+ }
+ goto RETURN_SUCCESS;
case PARSER_TOKEN_CONSTANT:
case PARSER_TOKEN_VARIABLE: {
const ParserNodeVariableMetadata *metadata = node->metadata;
@@ -479,7 +486,6 @@ void parserNodeDelete(ParserNode *node) {
free(metadata);
}
goto RETURN_SUCCESS;
-
case PARSER_TOKEN_VALUE_INT: {
ParserNodeIntMetadata *metadata = node->metadata;
free(metadata);
@@ -490,6 +496,11 @@ void parserNodeDelete(ParserNode *node) {
free(metadata);
}
goto RETURN_SUCCESS;
+ case PARSER_TOKEN_VALUE_CHAR: {
+ ParserNodeCharMetadata *metadata = node->metadata;
+ free(metadata);
+ }
+ goto RETURN_SUCCESS;
case PARSER_TOKEN_CONSTANT:
case PARSER_TOKEN_VARIABLE: {
ParserNodeVariableMetadata *metadata = node->metadata;
@@ -749,6 +760,8 @@ ParserNode *parseNode(LexerNode *node, LexerNode *begin, LexerNode *end,
return parserComma(node, begin, parent);
case LEXER_TOKEN_NUMBER:
return parserNumber(node, parent);
+ case LEXER_TOKEN_CHAR:
+ return parserChar(node, parent);
case LEXER_TOKEN_SYMBOL_ASSIGN:
return parserBinaryOperator(node, begin, end, parent,
PARSER_TOKEN_OPERATOR_ASSIGN);
@@ -1011,6 +1024,22 @@ ParserNode *parserNumber(LexerNode *node, ParserNode *parent) {
return node->parserNode = parserNode;
}
+ParserNode *parserChar(LexerNode *node, ParserNode *parent) {
+ const size_t size = node->str_end - 1 - node->str_begin - 1;
+ ParserNodeCharMetadata *metadata = a404m_malloc(sizeof(*metadata));
+ if (size == 1) {
+ *metadata = *(node->str_begin + 1);
+ } else if (size > 1) {
+ NOT_IMPLEMENTED;
+ } else {
+ printError(node->str_begin, node->str_end,
+ "Bad character: Character can't be empty");
+ }
+ return node->parserNode =
+ newParserNode(PARSER_TOKEN_VALUE_CHAR, node->str_begin,
+ node->str_end, metadata, parent);
+}
+
ParserNode *parserBoolValue(LexerNode *node, ParserNode *parent) {
ParserNodeBoolMetadata *metadata = a404m_malloc(sizeof(*metadata));
*metadata = node->token == LEXER_TOKEN_KEYWORD_TRUE;
@@ -1218,6 +1247,7 @@ ParserNode *parserFunction(LexerNode *node, LexerNode *begin, LexerNode *end,
case PARSER_TOKEN_VALUE_INT:
case PARSER_TOKEN_VALUE_FLOAT:
case PARSER_TOKEN_VALUE_BOOL:
+ case PARSER_TOKEN_VALUE_CHAR:
case PARSER_TOKEN_TYPE_TYPE:
case PARSER_TOKEN_TYPE_FUNCTION:
case PARSER_TOKEN_TYPE_VOID:
@@ -1700,6 +1730,7 @@ bool isExpression(ParserNode *node) {
case PARSER_TOKEN_VALUE_INT:
case PARSER_TOKEN_VALUE_FLOAT:
case PARSER_TOKEN_VALUE_BOOL:
+ case PARSER_TOKEN_VALUE_CHAR:
case PARSER_TOKEN_KEYWORD_IF:
case PARSER_TOKEN_KEYWORD_WHILE:
case PARSER_TOKEN_KEYWORD_COMPTIME:
@@ -1777,6 +1808,7 @@ bool isType(ParserNode *node) {
case PARSER_TOKEN_VALUE_INT:
case PARSER_TOKEN_VALUE_FLOAT:
case PARSER_TOKEN_VALUE_BOOL:
+ case PARSER_TOKEN_VALUE_CHAR:
case PARSER_TOKEN_KEYWORD_PRINT_U64:
case PARSER_TOKEN_KEYWORD_RETURN:
case PARSER_TOKEN_OPERATOR_ASSIGN:
@@ -1813,6 +1845,7 @@ bool isValue(ParserNode *node) {
case PARSER_TOKEN_VALUE_INT:
case PARSER_TOKEN_VALUE_FLOAT:
case PARSER_TOKEN_VALUE_BOOL:
+ case PARSER_TOKEN_VALUE_CHAR:
case PARSER_TOKEN_IDENTIFIER:
case PARSER_TOKEN_OPERATOR_ACCESS:
case PARSER_TOKEN_OPERATOR_ASSIGN:
diff --git a/src/compiler/parser.h b/src/compiler/parser.h
index 8eaea77..cb7af45 100644
--- a/src/compiler/parser.h
+++ b/src/compiler/parser.h
@@ -13,6 +13,7 @@ typedef enum ParserToken {
PARSER_TOKEN_VALUE_INT,
PARSER_TOKEN_VALUE_FLOAT,
PARSER_TOKEN_VALUE_BOOL,
+ PARSER_TOKEN_VALUE_CHAR,
PARSER_TOKEN_TYPE_TYPE,
PARSER_TOKEN_TYPE_FUNCTION,
@@ -28,7 +29,7 @@ typedef enum ParserToken {
PARSER_TOKEN_TYPE_U64,
#ifdef FLOAT_16_SUPPORT
PARSER_TOKEN_TYPE_F16,
- #endif
+#endif
PARSER_TOKEN_TYPE_F32,
PARSER_TOKEN_TYPE_F64,
PARSER_TOKEN_TYPE_F128,
@@ -86,7 +87,7 @@ extern const char *PARSER_TOKEN_STRINGS[];
typedef struct ParserOrder {
bool ltr;
size_t size;
- LexerToken data[22];
+ LexerToken data[23];
} ParserOrder;
typedef struct ParserNode {
@@ -130,6 +131,8 @@ typedef u64 ParserNodeIntMetadata;
typedef f128 ParserNodeFloatMetadata;
+typedef ParserNodeIntMetadata ParserNodeCharMetadata;
+
typedef struct ParserNodeInfixMetadata {
ParserNode *left;
ParserNode *right;
@@ -177,6 +180,7 @@ ParserNode *parserNoMetadata(LexerNode *node, ParserNode *parent,
ParserNode *parserPrintU64(LexerNode *node, LexerNode *end, ParserNode *parent);
ParserNode *parserReturn(LexerNode *node, LexerNode *end, ParserNode *parent);
ParserNode *parserNumber(LexerNode *node, ParserNode *parent);
+ParserNode *parserChar(LexerNode *node, ParserNode *parent);
ParserNode *parserBoolValue(LexerNode *node, ParserNode *parent);
ParserNode *parserEol(LexerNode *node, LexerNode *begin, ParserNode *parent);
ParserNode *parserComma(LexerNode *node, LexerNode *begin, ParserNode *parent);