diff --git a/cc_core.c b/cc_core.c
index 6a2afab..c9b5875 100644
--- a/cc_core.c
+++ b/cc_core.c
@@ -97,6 +97,51 @@ int stack_index(struct token_list* a, struct token_list* function)
exit(EXIT_FAILURE);
}
+struct token_list* expression(struct token_list* out, struct token_list* function);
+struct token_list* function_call(struct token_list* out, struct token_list* function, char* s, int bool)
+{
+ require_match("ERROR in process_expression_list\nNo ( was found\x0A", "(");
+ int passed = 0;
+
+ if(global_token->s[0] != ')')
+ {
+ out = expression(out, function);
+ out = emit("PUSH_eax\t#_process_expression1\x0A", out);
+ function->temps = function->temps + 1;
+ passed = 1;
+
+ while(global_token->s[0] == ',')
+ {
+ global_token = global_token->next;
+ out = expression(out, function);
+ out = emit("PUSH_eax\t#_process_expression2\x0A", out);
+ function->temps = function->temps + 1;
+ passed = passed + 1;
+ }
+ }
+
+ require_match("ERROR in process_expression_list\nNo ) was found\n", ")");
+
+ if(bool)
+ {
+ struct token_list* a = sym_lookup(s, function->arguments);
+ out = emit(prepend_string("LOAD_EFFECTIVE_ADDRESS %", numerate_number(stack_index(a, function))), out);
+ out = emit("LOAD_INTEGER\n", out);
+ out = emit("CALL_eax\n", out);
+ }
+ else
+ {
+ out = emit(prepend_string("CALL_IMMEDIATE %FUNCTION_", postpend_char(s, LF)), out);
+ }
+
+ for(; passed > 0; passed = passed - 1)
+ {
+ out = emit("POP_ebx\t# _process_expression_locals\x0A", out);
+ function->temps = function->temps - 1;
+ }
+ return out;
+}
+
struct token_list* sym_get_value(char *s, struct token_list* out, struct token_list* function)
{
global_token = global_token->next;
@@ -106,12 +151,6 @@ struct token_list* sym_get_value(char *s, struct token_list* out, struct token_l
out = emit(prepend_string("LOAD_IMMEDIATE_eax %", postpend_char(a->arguments->s, LF)), out); return out;
}
- a= sym_lookup(s, global_function_list);
- if(NULL != a)
- {
- return out;
- }
-
a= sym_lookup(s, function->locals);
if(NULL != a)
{
@@ -120,16 +159,40 @@ struct token_list* sym_get_value(char *s, struct token_list* out, struct token_l
if(!match("=", global_token->s)) out = emit("LOAD_INTEGER\x0A", out);
return out;
}
- a = sym_lookup(s, function->arguments);
+ a = sym_lookup(s, function->arguments);
if(NULL != a)
{
current_target = a->type;
+ if(match("FUNCTION", a->type->name))
+ {
+ if(!match("(", global_token->s))
+ {
+ out = emit(prepend_string("#Loading address of function\nLOAD_EFFECTIVE_ADDRESS %", numerate_number(stack_index(a, function))), out);
+ out = emit("LOAD_INTEGER\n", out);
+ return out;
+ }
+ return function_call(out, function, s, TRUE);
+ }
out = emit(prepend_string("LOAD_EFFECTIVE_ADDRESS %", numerate_number(stack_index(a, function))), out);
if(!match("=", global_token->s) && !match("argv", s)) out = emit("LOAD_INTEGER\x0A", out);
return out;
}
+ a= sym_lookup(s, global_function_list);
+ if(NULL != a)
+ {
+ if(!match("(", global_token->s))
+ {
+ out = emit(prepend_string("LOAD_IMMEDIATE_eax &FUNCTION_", postpend_char(s, LF)), out);
+ return out;
+ }
+ else
+ {
+ return function_call(out, function, s, FALSE);
+ }
+ }
+
a = sym_lookup(s, global_symbol_list);
if(NULL != a)
{
@@ -144,8 +207,6 @@ struct token_list* sym_get_value(char *s, struct token_list* out, struct token_l
exit(EXIT_FAILURE);
}
-struct token_list* expression(struct token_list* out, struct token_list* function);
-
/*
* primary-expr:
* identifier
@@ -203,42 +264,6 @@ struct token_list* primary_expr(struct token_list* out, struct token_list* funct
return out;
}
-/* Deal with Expression lists */
-struct token_list* process_expression_list(struct token_list* out, struct token_list* function)
-{
- char* func = global_token->prev->s;
- global_token = global_token->next;
- int temp = function->temps;
-
- if(global_token->s[0] != ')')
- {
- out = expression(out, function);
- out = emit("PUSH_eax\t#_process_expression1\x0A", out);
- function->temps = function->temps + 1;
-
- while(global_token->s[0] == ',')
- {
- global_token = global_token->next;
- out = expression(out, function);
- out = emit("PUSH_eax\t#_process_expression2\x0A", out);
- function->temps = function->temps + 1;
- }
- require_match("ERROR in process_expression_list\nNo ) was found\x0A", ")");
- }
- else global_token = global_token->next;
-
- out = emit(prepend_string("CALL_IMMEDIATE %FUNCTION_", postpend_char(func, LF)), out);
-
- int i;
- for(i = function->temps - temp; 0 != i; i = i - 1)
- {
- out = emit("POP_ebx\t# _process_expression_locals\x0A", out);
- }
-
- function->temps = temp;
- return out;
-}
-
struct type* last_type;
struct token_list* pre_recursion(struct token_list* out, struct token_list* func)
@@ -352,10 +377,6 @@ struct token_list* postfix_expr(struct token_list* out, struct token_list* funct
}
require_match("ERROR in postfix_expr\nMissing ]\x0A", "]");
}
- else if(global_token->s[0] == '(')
- {
- out = process_expression_list(out, function);
- }
else if(match("->", global_token->s))
{
out = emit("# looking up offset\x0A", out);
@@ -744,7 +765,10 @@ struct token_list* process_for(struct token_list* out, struct token_list* functi
global_token = global_token->next;
require_match("ERROR in process_for\nMISSING (\x0A", "(");
- out = expression(out, function);
+ if(!match(";",global_token->s))
+ {
+ out = expression(out, function);
+ }
out = emit(prepend_string(":FOR_", number_string), out);
diff --git a/cc_types.c b/cc_types.c
index adf3a21..e3a08f7 100644
--- a/cc_types.c
+++ b/cc_types.c
@@ -61,7 +61,16 @@ void initialize_types()
/* FILE* has the same properties as FILE */
d->indirect = d;
+ /* Define FUNCTION */
+ struct type* e = calloc(1, sizeof(struct type));
+ e->name = "FUNCTION";
+ e->size = 4;
+ e->type = e;
+ /* FUNCTION* has the same properties as FUNCTION */
+ e->indirect = e;
+
/* Finalize type list */
+ d->next = e;
c->next = d;
a->next = c;
global_types->next = a;
diff --git a/makefile b/makefile
index be1010f..4a88e29 100644
--- a/makefile
+++ b/makefile
@@ -51,6 +51,7 @@ clean:
./test/test17/cleanup.sh
./test/test18/cleanup.sh
./test/test19/cleanup.sh
+ ./test/test20/cleanup.sh
./test/test99/cleanup.sh
./test/test100/cleanup.sh
@@ -82,6 +83,7 @@ test: test00-binary \
test17-binary \
test18-binary \
test19-binary \
+ test20-binary \
test99-binary \
test100-binary | results
sha256sum -c test/test.answers
@@ -146,6 +148,9 @@ test18-binary: M2-Planet | results
test19-binary: M2-Planet | results
test/test19/hello.sh
+test20-binary: M2-Planet | results
+ test/test20/hello.sh
+
test99-binary: M2-Planet | results
test/test99/hello.sh
diff --git a/test/test.answers b/test/test.answers
index fe91b93..e36d066 100644
--- a/test/test.answers
+++ b/test/test.answers
@@ -9,7 +9,7 @@ d27eb315d694324650b11a421d6990eee60ac5921a5625bbccb43d806f09e156 test/results/t
8cc38294fb1261843cfc3956fad5a451c95bbc2ed687435d4e2d59df2c4a8567 test/results/test08-binary
cc8f252877a85c0d7832094ff574d7173ac33940917bc1591358b8970651a81c test/results/test09-binary
3857aee4183de41bd00b014d616a5d73f4bfc57aa60a6073bb4113d6ff2fb8d5 test/results/test10-binary
-a5764dc3aa8b9021beb2388d42357653315a21b0111a5c15f9e82301d88b5a79 test/results/test100-binary
+9d70fbcb87a3002f8d6f8831d421926b482544f5363fd291387b57e34fb57f3e test/results/test100-binary
dce2f0b35323cf6a2b01f74a9335100f2d8626028af545832dbdb503573db0e5 test/results/test11-binary
88602970fa07b5da7a42b4f2b2486fe03accc6796e05453c4ab934e986790bef test/results/test12-binary
c85a57b5b1d65288efd47a3b12c6fca1efade9e7ec91e65efda5531d2c40d293 test/results/test13-binary
@@ -19,4 +19,5 @@ b1de0d8c35068420d8f15d2fea74496e4f86c905f7c1b8601d569cd5c61d2796 test/results/t
15f1fc51d559b74d7515d3e978a835f7edc765f0763fdbae328f4b03a6b2b92b test/results/test17-binary
f2245dea4a08a26f1f63383acedd5a67e918b8c9d8e484f037aee7b71c7f8a50 test/results/test18-binary
6f1331ad820cdf9d45506eaac3053b80f4357fe955c30a113d1ec2bf829d79a2 test/results/test19-binary
+6fa44153ee3f27f0df49b282c0bb3017dbfaea906073c8c02b8bf5ad4d4a7860 test/results/test20-binary
ba3d9623c6512bc327cf934d994e5327e5fad3f7500896e2d8458467fae9b9e9 test/results/test99-binary
diff --git a/test/test100/proof.answer b/test/test100/proof.answer
index d303d49..c104982 100644
--- a/test/test100/proof.answer
+++ b/test/test100/proof.answer
@@ -1 +1 @@
-aacd70427396379f16862809eacd1a881b74e0ceafd6b99304f74e2893e48b98 test/test100/proof
+ebee1401bceb90f543c7656d98264271ce477f527470f5050d5cdb8c8871cb86 test/test100/proof
diff --git a/test/test20/.gitignore b/test/test20/.gitignore
new file mode 100644
index 0000000..e483926
--- /dev/null
+++ b/test/test20/.gitignore
@@ -0,0 +1,6 @@
+# Ignore the files created by script
+*.M1
+*.hex2
+
+# A place to put a good run for comparison
+actual.M1
diff --git a/test/test20/cleanup.sh b/test/test20/cleanup.sh
new file mode 100755
index 0000000..3aa2aba
--- /dev/null
+++ b/test/test20/cleanup.sh
@@ -0,0 +1,4 @@
+#! /bin/sh
+rm -f test/test20/struct.M1
+rm -f test/test20/struct.hex2
+exit 0
diff --git a/test/test20/gcc_req.h b/test/test20/gcc_req.h
new file mode 100644
index 0000000..4d6c907
--- /dev/null
+++ b/test/test20/gcc_req.h
@@ -0,0 +1,18 @@
+/* Copyright (C) 2016 Jeremiah Orians
+ * This file is part of stage0.
+ *
+ * stage0 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * stage0 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with stage0. If not, see .
+ */
+
+typedef int (FUNCTION)(int);
diff --git a/test/test20/hello.sh b/test/test20/hello.sh
new file mode 100755
index 0000000..288eac3
--- /dev/null
+++ b/test/test20/hello.sh
@@ -0,0 +1,29 @@
+#! /bin/sh
+set -x
+# Build the test
+bin/M2-Planet -f test/functions/putchar.c \
+ -f test/functions/exit.c \
+ -f test/functions/malloc.c \
+ -f test/test20/struct.c \
+ -o test/test20/struct.M1 || exit 1
+
+# Macro assemble with libc written in M1-Macro
+M1 -f test/common_x86/x86_defs.M1 \
+ -f test/functions/libc-core.M1 \
+ -f test/test20/struct.M1 \
+ --LittleEndian \
+ --Architecture 1 \
+ -o test/test20/struct.hex2 || exit 2
+
+# Resolve all linkages
+hex2 -f test/common_x86/ELF-i386.hex2 -f test/test20/struct.hex2 --LittleEndian --Architecture 1 --BaseAddress 0x8048000 -o test/results/test20-binary --exec_enable || exit 3
+
+# Ensure binary works if host machine supports test
+if [ "$(get_machine)" = "x86_64" ]
+then
+ # Verify that the compiled program returns the correct result
+ out=$(./test/results/test20-binary 2>&1 )
+ [ 20 = $? ] || exit 4
+ [ "$out" = "35419896642975313541989657891634" ] || exit 5
+fi
+exit 0
diff --git a/test/test20/struct.c b/test/test20/struct.c
new file mode 100644
index 0000000..bc46108
--- /dev/null
+++ b/test/test20/struct.c
@@ -0,0 +1,59 @@
+/* Copyright (C) 2016 Jeremiah Orians
+ * This file is part of stage0.
+ *
+ * stage0 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * stage0 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with stage0. If not, see .
+ */
+
+#include
+#include
+#include "gcc_req.h"
+
+struct foo
+{
+ struct foo* next;
+ struct foo* prev;
+ FUNCTION* run;
+ int a;
+ int b;
+};
+
+void print_hex(int a, int count, FUNCTION foo2)
+{
+ if(count <= 0) return;
+ print_hex(a >> 4, count - 1, foo2);
+ foo2((a & 15) + 48);
+}
+
+int main()
+{
+ struct foo* a = malloc(sizeof(struct foo));
+ struct foo* b = malloc(sizeof(struct foo));
+
+ a->run = putchar;
+ a->a = 0x35419896;
+ a->b = 0x57891634;
+ b->a = 0x13579246;
+ b->b = 0x64297531;
+ a->next = b;
+ a->prev = b;
+ b->next = a;
+ b->prev = a;
+
+ print_hex(a->next->next->a, 8, a->run);
+ print_hex(b->prev->prev->b, 8, putchar);
+ print_hex(b->next->a, 8, putchar);
+ print_hex(b->prev->b, 8, putchar);
+ putchar(10);
+ return sizeof(struct foo);
+}