summaryrefslogtreecommitdiff
path: root/src/runner
diff options
context:
space:
mode:
authorA404M <ahmadmahmoudiprogrammer@gmail.com>2025-04-09 22:54:40 +0330
committerA404M <ahmadmahmoudiprogrammer@gmail.com>2025-04-09 22:54:40 +0330
commit5e95fdfa4b7e6960d83480b8e4062e7484037af7 (patch)
tree742e139dc1149daf4c5565b07c8e58a665355b4a /src/runner
parent9b355a18b14f2ece7707e6c5334124dcc0961e2d (diff)
add builtins (cast)
Diffstat (limited to 'src/runner')
-rw-r--r--src/runner/runner.c276
-rw-r--r--src/runner/runner.h3
2 files changed, 277 insertions, 2 deletions
diff --git a/src/runner/runner.c b/src/runner/runner.c
index 8746e7c..818f21a 100644
--- a/src/runner/runner.c
+++ b/src/runner/runner.c
@@ -94,6 +94,269 @@ AstTree *runAstTreeFunction(AstTree *tree, AstTreeFunctionCallParam *arguments,
return &AST_TREE_VOID_VALUE;
}
+AstTree *runAstTreeBuiltin(AstTree *tree, AstTreeFunctionCallParam *arguments,
+ size_t arguments_size) {
+ AstTreeBuiltin *metadata = tree->metadata;
+
+ AstTrees args = {
+ .data = a404m_malloc(arguments_size * sizeof(*args.data)),
+ .size = arguments_size,
+ };
+
+ bool shouldRet = false;
+
+ for (size_t i = 0; i < arguments_size; ++i) {
+ AstTreeFunctionCallParam param = arguments[i];
+ args.data[i] = runExpression(param.value, &shouldRet, false);
+ }
+
+ if (shouldRet) {
+ UNREACHABLE;
+ }
+
+ AstTree *ret;
+
+ switch (metadata->token) {
+ case AST_TREE_BUILTIN_TOKEN_CAST: {
+ AstTree *from = args.data[0];
+ AstTree *to = args.data[1];
+
+ if (from->token == AST_TREE_TOKEN_VALUE_INT) {
+ AstTreeInt value = *(AstTreeInt *)from->metadata;
+ if (typeIsEqual(to, &AST_TREE_U8_TYPE)) {
+ AstTreeInt *newValue = a404m_malloc(sizeof(*newValue));
+ *newValue = (u8)value;
+ ret = newAstTree(AST_TREE_TOKEN_VALUE_INT, newValue, &AST_TREE_U8_TYPE,
+ NULL, NULL);
+ } else if (typeIsEqual(to, &AST_TREE_U16_TYPE)) {
+ AstTreeInt *newValue = a404m_malloc(sizeof(*newValue));
+ *newValue = (u16)value;
+ ret = newAstTree(AST_TREE_TOKEN_VALUE_INT, newValue, &AST_TREE_U16_TYPE,
+ NULL, NULL);
+ } else if (typeIsEqual(to, &AST_TREE_U32_TYPE)) {
+ AstTreeInt *newValue = a404m_malloc(sizeof(*newValue));
+ *newValue = (u32)value;
+ ret = newAstTree(AST_TREE_TOKEN_VALUE_INT, newValue, &AST_TREE_U32_TYPE,
+ NULL, NULL);
+ } else if (typeIsEqual(to, &AST_TREE_U64_TYPE)) {
+ AstTreeInt *newValue = a404m_malloc(sizeof(*newValue));
+ *newValue = (u64)value;
+ ret = newAstTree(AST_TREE_TOKEN_VALUE_INT, newValue, &AST_TREE_U64_TYPE,
+ NULL, NULL);
+ } else if (typeIsEqual(to, &AST_TREE_I8_TYPE)) {
+ AstTreeInt *newValue = a404m_malloc(sizeof(*newValue));
+ *newValue = (i8)value;
+ ret = newAstTree(AST_TREE_TOKEN_VALUE_INT, newValue, &AST_TREE_I8_TYPE,
+ NULL, NULL);
+ } else if (typeIsEqual(to, &AST_TREE_I16_TYPE)) {
+ AstTreeInt *newValue = a404m_malloc(sizeof(*newValue));
+ *newValue = (i16)value;
+ ret = newAstTree(AST_TREE_TOKEN_VALUE_INT, newValue, &AST_TREE_I16_TYPE,
+ NULL, NULL);
+ } else if (typeIsEqual(to, &AST_TREE_I32_TYPE)) {
+ AstTreeInt *newValue = a404m_malloc(sizeof(*newValue));
+ *newValue = (i32)value;
+ ret = newAstTree(AST_TREE_TOKEN_VALUE_INT, newValue, &AST_TREE_I32_TYPE,
+ NULL, NULL);
+ } else if (typeIsEqual(to, &AST_TREE_I64_TYPE)) {
+ AstTreeInt *newValue = a404m_malloc(sizeof(*newValue));
+ *newValue = (i64)value;
+ ret = newAstTree(AST_TREE_TOKEN_VALUE_INT, newValue, &AST_TREE_I64_TYPE,
+ NULL, NULL);
+ } else if (typeIsEqual(to, &AST_TREE_F16_TYPE)) {
+ AstTreeFloat *newValue = a404m_malloc(sizeof(*newValue));
+ *newValue = (f16)value;
+ ret = newAstTree(AST_TREE_TOKEN_VALUE_FLOAT, newValue,
+ &AST_TREE_F16_TYPE, NULL, NULL);
+ } else if (typeIsEqual(to, &AST_TREE_F32_TYPE)) {
+ AstTreeFloat *newValue = a404m_malloc(sizeof(*newValue));
+ *newValue = (f32)value;
+ ret = newAstTree(AST_TREE_TOKEN_VALUE_FLOAT, newValue,
+ &AST_TREE_F32_TYPE, NULL, NULL);
+ } else if (typeIsEqual(to, &AST_TREE_F64_TYPE)) {
+ AstTreeFloat *newValue = a404m_malloc(sizeof(*newValue));
+ *newValue = (f64)value;
+ ret = newAstTree(AST_TREE_TOKEN_VALUE_FLOAT, newValue,
+ &AST_TREE_F64_TYPE, NULL, NULL);
+ } else if (typeIsEqual(to, &AST_TREE_F128_TYPE)) {
+ AstTreeFloat *newValue = a404m_malloc(sizeof(*newValue));
+ *newValue = (f128)value;
+ ret = newAstTree(AST_TREE_TOKEN_VALUE_FLOAT, newValue,
+ &AST_TREE_F128_TYPE, NULL, NULL);
+ } else if (typeIsEqual(to, &AST_TREE_BOOL_TYPE)) {
+ AstTreeBool *newValue = a404m_malloc(sizeof(*newValue));
+ *newValue = (bool)value;
+ ret = newAstTree(AST_TREE_TOKEN_VALUE_BOOL, newValue,
+ &AST_TREE_BOOL_TYPE, NULL, NULL);
+ } else {
+ printError(to->str_begin, to->str_end, "Bad type %s",
+ AST_TREE_TOKEN_STRINGS[to->token]);
+ UNREACHABLE;
+ }
+ } else if (from->token == AST_TREE_TOKEN_VALUE_FLOAT) {
+ AstTreeFloat value = *(AstTreeFloat *)from->metadata;
+ if (typeIsEqual(to, &AST_TREE_U8_TYPE)) {
+ AstTreeInt *newValue = a404m_malloc(sizeof(*newValue));
+ *newValue = (u8)value;
+ ret = newAstTree(AST_TREE_TOKEN_VALUE_INT, newValue, &AST_TREE_U8_TYPE,
+ NULL, NULL);
+ } else if (typeIsEqual(to, &AST_TREE_U16_TYPE)) {
+ AstTreeInt *newValue = a404m_malloc(sizeof(*newValue));
+ *newValue = (u16)value;
+ ret = newAstTree(AST_TREE_TOKEN_VALUE_INT, newValue, &AST_TREE_U16_TYPE,
+ NULL, NULL);
+ } else if (typeIsEqual(to, &AST_TREE_U32_TYPE)) {
+ AstTreeInt *newValue = a404m_malloc(sizeof(*newValue));
+ *newValue = (u32)value;
+ ret = newAstTree(AST_TREE_TOKEN_VALUE_INT, newValue, &AST_TREE_U32_TYPE,
+ NULL, NULL);
+ } else if (typeIsEqual(to, &AST_TREE_U64_TYPE)) {
+ AstTreeInt *newValue = a404m_malloc(sizeof(*newValue));
+ *newValue = (u64)value;
+ ret = newAstTree(AST_TREE_TOKEN_VALUE_INT, newValue, &AST_TREE_U64_TYPE,
+ NULL, NULL);
+ } else if (typeIsEqual(to, &AST_TREE_I8_TYPE)) {
+ AstTreeInt *newValue = a404m_malloc(sizeof(*newValue));
+ *newValue = (i8)value;
+ ret = newAstTree(AST_TREE_TOKEN_VALUE_INT, newValue, &AST_TREE_I8_TYPE,
+ NULL, NULL);
+ } else if (typeIsEqual(to, &AST_TREE_I16_TYPE)) {
+ AstTreeInt *newValue = a404m_malloc(sizeof(*newValue));
+ *newValue = (i16)value;
+ ret = newAstTree(AST_TREE_TOKEN_VALUE_INT, newValue, &AST_TREE_I16_TYPE,
+ NULL, NULL);
+ } else if (typeIsEqual(to, &AST_TREE_I32_TYPE)) {
+ AstTreeInt *newValue = a404m_malloc(sizeof(*newValue));
+ *newValue = (i32)value;
+ ret = newAstTree(AST_TREE_TOKEN_VALUE_INT, newValue, &AST_TREE_I32_TYPE,
+ NULL, NULL);
+ } else if (typeIsEqual(to, &AST_TREE_I64_TYPE)) {
+ AstTreeInt *newValue = a404m_malloc(sizeof(*newValue));
+ *newValue = (i64)value;
+ ret = newAstTree(AST_TREE_TOKEN_VALUE_INT, newValue, &AST_TREE_I64_TYPE,
+ NULL, NULL);
+ } else if (typeIsEqual(to, &AST_TREE_F16_TYPE)) {
+ AstTreeFloat *newValue = a404m_malloc(sizeof(*newValue));
+ *newValue = (f16)value;
+ ret = newAstTree(AST_TREE_TOKEN_VALUE_FLOAT, newValue,
+ &AST_TREE_F16_TYPE, NULL, NULL);
+ } else if (typeIsEqual(to, &AST_TREE_F32_TYPE)) {
+ AstTreeFloat *newValue = a404m_malloc(sizeof(*newValue));
+ *newValue = (f32)value;
+ ret = newAstTree(AST_TREE_TOKEN_VALUE_FLOAT, newValue,
+ &AST_TREE_F32_TYPE, NULL, NULL);
+ } else if (typeIsEqual(to, &AST_TREE_F64_TYPE)) {
+ AstTreeFloat *newValue = a404m_malloc(sizeof(*newValue));
+ *newValue = (f64)value;
+ ret = newAstTree(AST_TREE_TOKEN_VALUE_FLOAT, newValue,
+ &AST_TREE_F64_TYPE, NULL, NULL);
+ } else if (typeIsEqual(to, &AST_TREE_F128_TYPE)) {
+ AstTreeFloat *newValue = a404m_malloc(sizeof(*newValue));
+ *newValue = (f128)value;
+ ret = newAstTree(AST_TREE_TOKEN_VALUE_FLOAT, newValue,
+ &AST_TREE_F128_TYPE, NULL, NULL);
+ } else if (typeIsEqual(to, &AST_TREE_BOOL_TYPE)) {
+ AstTreeBool *newValue = a404m_malloc(sizeof(*newValue));
+ *newValue = (bool)value;
+ ret = newAstTree(AST_TREE_TOKEN_VALUE_BOOL, newValue,
+ &AST_TREE_BOOL_TYPE, NULL, NULL);
+ } else {
+ printError(to->str_begin, to->str_end, "Bad type %s",
+ AST_TREE_TOKEN_STRINGS[to->token]);
+ UNREACHABLE;
+ }
+ } else if (from->token == AST_TREE_TOKEN_VALUE_BOOL) {
+ AstTreeBool value = *(AstTreeBool *)from->metadata;
+ if (typeIsEqual(to, &AST_TREE_U8_TYPE)) {
+ AstTreeInt *newValue = a404m_malloc(sizeof(*newValue));
+ *newValue = (u8)value;
+ ret = newAstTree(AST_TREE_TOKEN_VALUE_INT, newValue, &AST_TREE_U8_TYPE,
+ NULL, NULL);
+ } else if (typeIsEqual(to, &AST_TREE_U16_TYPE)) {
+ AstTreeInt *newValue = a404m_malloc(sizeof(*newValue));
+ *newValue = (u16)value;
+ ret = newAstTree(AST_TREE_TOKEN_VALUE_INT, newValue, &AST_TREE_U16_TYPE,
+ NULL, NULL);
+ } else if (typeIsEqual(to, &AST_TREE_U32_TYPE)) {
+ AstTreeInt *newValue = a404m_malloc(sizeof(*newValue));
+ *newValue = (u32)value;
+ ret = newAstTree(AST_TREE_TOKEN_VALUE_INT, newValue, &AST_TREE_U32_TYPE,
+ NULL, NULL);
+ } else if (typeIsEqual(to, &AST_TREE_U64_TYPE)) {
+ AstTreeInt *newValue = a404m_malloc(sizeof(*newValue));
+ *newValue = (u64)value;
+ ret = newAstTree(AST_TREE_TOKEN_VALUE_INT, newValue, &AST_TREE_U64_TYPE,
+ NULL, NULL);
+ } else if (typeIsEqual(to, &AST_TREE_I8_TYPE)) {
+ AstTreeInt *newValue = a404m_malloc(sizeof(*newValue));
+ *newValue = (i8)value;
+ ret = newAstTree(AST_TREE_TOKEN_VALUE_INT, newValue, &AST_TREE_I8_TYPE,
+ NULL, NULL);
+ } else if (typeIsEqual(to, &AST_TREE_I16_TYPE)) {
+ AstTreeInt *newValue = a404m_malloc(sizeof(*newValue));
+ *newValue = (i16)value;
+ ret = newAstTree(AST_TREE_TOKEN_VALUE_INT, newValue, &AST_TREE_I16_TYPE,
+ NULL, NULL);
+ } else if (typeIsEqual(to, &AST_TREE_I32_TYPE)) {
+ AstTreeInt *newValue = a404m_malloc(sizeof(*newValue));
+ *newValue = (i32)value;
+ ret = newAstTree(AST_TREE_TOKEN_VALUE_INT, newValue, &AST_TREE_I32_TYPE,
+ NULL, NULL);
+ } else if (typeIsEqual(to, &AST_TREE_I64_TYPE)) {
+ AstTreeInt *newValue = a404m_malloc(sizeof(*newValue));
+ *newValue = (i64)value;
+ ret = newAstTree(AST_TREE_TOKEN_VALUE_INT, newValue, &AST_TREE_I64_TYPE,
+ NULL, NULL);
+ } else if (typeIsEqual(to, &AST_TREE_F16_TYPE)) {
+ AstTreeFloat *newValue = a404m_malloc(sizeof(*newValue));
+ *newValue = (f16)value;
+ ret = newAstTree(AST_TREE_TOKEN_VALUE_FLOAT, newValue,
+ &AST_TREE_F16_TYPE, NULL, NULL);
+ } else if (typeIsEqual(to, &AST_TREE_F32_TYPE)) {
+ AstTreeFloat *newValue = a404m_malloc(sizeof(*newValue));
+ *newValue = (f32)value;
+ ret = newAstTree(AST_TREE_TOKEN_VALUE_FLOAT, newValue,
+ &AST_TREE_F32_TYPE, NULL, NULL);
+ } else if (typeIsEqual(to, &AST_TREE_F64_TYPE)) {
+ AstTreeFloat *newValue = a404m_malloc(sizeof(*newValue));
+ *newValue = (f64)value;
+ ret = newAstTree(AST_TREE_TOKEN_VALUE_FLOAT, newValue,
+ &AST_TREE_F64_TYPE, NULL, NULL);
+ } else if (typeIsEqual(to, &AST_TREE_F128_TYPE)) {
+ AstTreeFloat *newValue = a404m_malloc(sizeof(*newValue));
+ *newValue = (f128)value;
+ ret = newAstTree(AST_TREE_TOKEN_VALUE_FLOAT, newValue,
+ &AST_TREE_F128_TYPE, NULL, NULL);
+ } else if (typeIsEqual(to, &AST_TREE_BOOL_TYPE)) {
+ AstTreeBool *newValue = a404m_malloc(sizeof(*newValue));
+ *newValue = (bool)value;
+ ret = newAstTree(AST_TREE_TOKEN_VALUE_BOOL, newValue,
+ &AST_TREE_BOOL_TYPE, NULL, NULL);
+ } else {
+ printError(to->str_begin, to->str_end, "Bad type %s",
+ AST_TREE_TOKEN_STRINGS[to->token]);
+ UNREACHABLE;
+ }
+ } else {
+ printError(to->str_begin, to->str_end, "Bad token %s",
+ AST_TREE_TOKEN_STRINGS[from->token]);
+ UNREACHABLE;
+ }
+ goto RETURN;
+ }
+ case AST_TREE_BUILTIN_TOKEN__SIZE__:
+ }
+ UNREACHABLE;
+
+RETURN:
+ for (size_t i = 0; i < args.size; ++i) {
+ astTreeDelete(args.data[i]);
+ }
+ free(args.data);
+
+ return ret;
+}
+
AstTree *runExpression(AstTree *expr, bool *shouldRet, bool isLeft) {
switch (expr->token) {
case AST_TREE_TOKEN_KEYWORD_PUTC: {
@@ -106,8 +369,16 @@ AstTree *runExpression(AstTree *expr, bool *shouldRet, bool isLeft) {
case AST_TREE_TOKEN_FUNCTION_CALL: {
AstTreeFunctionCall *metadata = expr->metadata;
AstTree *function = runExpression(metadata->function, shouldRet, false);
- AstTree *result = runAstTreeFunction(function, metadata->parameters,
- metadata->parameters_size);
+ AstTree *result;
+ if (function->token == AST_TREE_TOKEN_FUNCTION) {
+ result = runAstTreeFunction(function, metadata->parameters,
+ metadata->parameters_size);
+ } else if (function->token == AST_TREE_TOKEN_BUILTIN) {
+ result = runAstTreeBuiltin(function, metadata->parameters,
+ metadata->parameters_size);
+ } else {
+ UNREACHABLE;
+ }
astTreeDelete(function);
return result;
}
@@ -843,6 +1114,7 @@ AstTree *runExpression(AstTree *expr, bool *shouldRet, bool isLeft) {
case AST_TREE_TOKEN_VALUE_FLOAT:
case AST_TREE_TOKEN_VALUE_OBJECT:
case AST_TREE_TOKEN_FUNCTION:
+ case AST_TREE_TOKEN_BUILTIN:
return copyAstTree(expr);
case AST_TREE_TOKEN_OPERATOR_ADDRESS: {
AstTreeSingleChild *metadata = expr->metadata;
diff --git a/src/runner/runner.h b/src/runner/runner.h
index 2ff2ec2..6ed9956 100644
--- a/src/runner/runner.h
+++ b/src/runner/runner.h
@@ -11,4 +11,7 @@ bool runAstTree(AstTreeRoot *root);
AstTree *runAstTreeFunction(AstTree *tree, AstTreeFunctionCallParam *arguments,
size_t arguments_size);
+AstTree *runAstTreeBuiltin(AstTree *tree, AstTreeFunctionCallParam *arguments,
+ size_t arguments_size);
+
AstTree *runExpression(AstTree *expr, bool *shouldRet,bool isLeft);