Added support for passing of function pointers via FUNCTION
This commit is contained in:
parent
a035d955e9
commit
fdbb577784
124
cc_core.c
124
cc_core.c
|
@ -97,6 +97,51 @@ int stack_index(struct token_list* a, struct token_list* function)
|
||||||
exit(EXIT_FAILURE);
|
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)
|
struct token_list* sym_get_value(char *s, struct token_list* out, struct token_list* function)
|
||||||
{
|
{
|
||||||
global_token = global_token->next;
|
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;
|
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);
|
a= sym_lookup(s, function->locals);
|
||||||
if(NULL != a)
|
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);
|
if(!match("=", global_token->s)) out = emit("LOAD_INTEGER\x0A", out);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
a = sym_lookup(s, function->arguments);
|
|
||||||
|
|
||||||
|
a = sym_lookup(s, function->arguments);
|
||||||
if(NULL != a)
|
if(NULL != a)
|
||||||
{
|
{
|
||||||
current_target = a->type;
|
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);
|
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);
|
if(!match("=", global_token->s) && !match("argv", s)) out = emit("LOAD_INTEGER\x0A", out);
|
||||||
return 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);
|
a = sym_lookup(s, global_symbol_list);
|
||||||
if(NULL != a)
|
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);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct token_list* expression(struct token_list* out, struct token_list* function);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* primary-expr:
|
* primary-expr:
|
||||||
* identifier
|
* identifier
|
||||||
|
@ -203,42 +264,6 @@ struct token_list* primary_expr(struct token_list* out, struct token_list* funct
|
||||||
return out;
|
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 type* last_type;
|
||||||
|
|
||||||
struct token_list* pre_recursion(struct token_list* out, struct token_list* func)
|
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", "]");
|
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))
|
else if(match("->", global_token->s))
|
||||||
{
|
{
|
||||||
out = emit("# looking up offset\x0A", out);
|
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;
|
global_token = global_token->next;
|
||||||
|
|
||||||
require_match("ERROR in process_for\nMISSING (\x0A", "(");
|
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);
|
out = emit(prepend_string(":FOR_", number_string), out);
|
||||||
|
|
||||||
|
|
|
@ -61,7 +61,16 @@ void initialize_types()
|
||||||
/* FILE* has the same properties as FILE */
|
/* FILE* has the same properties as FILE */
|
||||||
d->indirect = d;
|
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 */
|
/* Finalize type list */
|
||||||
|
d->next = e;
|
||||||
c->next = d;
|
c->next = d;
|
||||||
a->next = c;
|
a->next = c;
|
||||||
global_types->next = a;
|
global_types->next = a;
|
||||||
|
|
5
makefile
5
makefile
|
@ -51,6 +51,7 @@ clean:
|
||||||
./test/test17/cleanup.sh
|
./test/test17/cleanup.sh
|
||||||
./test/test18/cleanup.sh
|
./test/test18/cleanup.sh
|
||||||
./test/test19/cleanup.sh
|
./test/test19/cleanup.sh
|
||||||
|
./test/test20/cleanup.sh
|
||||||
./test/test99/cleanup.sh
|
./test/test99/cleanup.sh
|
||||||
./test/test100/cleanup.sh
|
./test/test100/cleanup.sh
|
||||||
|
|
||||||
|
@ -82,6 +83,7 @@ test: test00-binary \
|
||||||
test17-binary \
|
test17-binary \
|
||||||
test18-binary \
|
test18-binary \
|
||||||
test19-binary \
|
test19-binary \
|
||||||
|
test20-binary \
|
||||||
test99-binary \
|
test99-binary \
|
||||||
test100-binary | results
|
test100-binary | results
|
||||||
sha256sum -c test/test.answers
|
sha256sum -c test/test.answers
|
||||||
|
@ -146,6 +148,9 @@ test18-binary: M2-Planet | results
|
||||||
test19-binary: M2-Planet | results
|
test19-binary: M2-Planet | results
|
||||||
test/test19/hello.sh
|
test/test19/hello.sh
|
||||||
|
|
||||||
|
test20-binary: M2-Planet | results
|
||||||
|
test/test20/hello.sh
|
||||||
|
|
||||||
test99-binary: M2-Planet | results
|
test99-binary: M2-Planet | results
|
||||||
test/test99/hello.sh
|
test/test99/hello.sh
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ d27eb315d694324650b11a421d6990eee60ac5921a5625bbccb43d806f09e156 test/results/t
|
||||||
8cc38294fb1261843cfc3956fad5a451c95bbc2ed687435d4e2d59df2c4a8567 test/results/test08-binary
|
8cc38294fb1261843cfc3956fad5a451c95bbc2ed687435d4e2d59df2c4a8567 test/results/test08-binary
|
||||||
cc8f252877a85c0d7832094ff574d7173ac33940917bc1591358b8970651a81c test/results/test09-binary
|
cc8f252877a85c0d7832094ff574d7173ac33940917bc1591358b8970651a81c test/results/test09-binary
|
||||||
3857aee4183de41bd00b014d616a5d73f4bfc57aa60a6073bb4113d6ff2fb8d5 test/results/test10-binary
|
3857aee4183de41bd00b014d616a5d73f4bfc57aa60a6073bb4113d6ff2fb8d5 test/results/test10-binary
|
||||||
a5764dc3aa8b9021beb2388d42357653315a21b0111a5c15f9e82301d88b5a79 test/results/test100-binary
|
9d70fbcb87a3002f8d6f8831d421926b482544f5363fd291387b57e34fb57f3e test/results/test100-binary
|
||||||
dce2f0b35323cf6a2b01f74a9335100f2d8626028af545832dbdb503573db0e5 test/results/test11-binary
|
dce2f0b35323cf6a2b01f74a9335100f2d8626028af545832dbdb503573db0e5 test/results/test11-binary
|
||||||
88602970fa07b5da7a42b4f2b2486fe03accc6796e05453c4ab934e986790bef test/results/test12-binary
|
88602970fa07b5da7a42b4f2b2486fe03accc6796e05453c4ab934e986790bef test/results/test12-binary
|
||||||
c85a57b5b1d65288efd47a3b12c6fca1efade9e7ec91e65efda5531d2c40d293 test/results/test13-binary
|
c85a57b5b1d65288efd47a3b12c6fca1efade9e7ec91e65efda5531d2c40d293 test/results/test13-binary
|
||||||
|
@ -19,4 +19,5 @@ b1de0d8c35068420d8f15d2fea74496e4f86c905f7c1b8601d569cd5c61d2796 test/results/t
|
||||||
15f1fc51d559b74d7515d3e978a835f7edc765f0763fdbae328f4b03a6b2b92b test/results/test17-binary
|
15f1fc51d559b74d7515d3e978a835f7edc765f0763fdbae328f4b03a6b2b92b test/results/test17-binary
|
||||||
f2245dea4a08a26f1f63383acedd5a67e918b8c9d8e484f037aee7b71c7f8a50 test/results/test18-binary
|
f2245dea4a08a26f1f63383acedd5a67e918b8c9d8e484f037aee7b71c7f8a50 test/results/test18-binary
|
||||||
6f1331ad820cdf9d45506eaac3053b80f4357fe955c30a113d1ec2bf829d79a2 test/results/test19-binary
|
6f1331ad820cdf9d45506eaac3053b80f4357fe955c30a113d1ec2bf829d79a2 test/results/test19-binary
|
||||||
|
6fa44153ee3f27f0df49b282c0bb3017dbfaea906073c8c02b8bf5ad4d4a7860 test/results/test20-binary
|
||||||
ba3d9623c6512bc327cf934d994e5327e5fad3f7500896e2d8458467fae9b9e9 test/results/test99-binary
|
ba3d9623c6512bc327cf934d994e5327e5fad3f7500896e2d8458467fae9b9e9 test/results/test99-binary
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
aacd70427396379f16862809eacd1a881b74e0ceafd6b99304f74e2893e48b98 test/test100/proof
|
ebee1401bceb90f543c7656d98264271ce477f527470f5050d5cdb8c8871cb86 test/test100/proof
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
# Ignore the files created by script
|
||||||
|
*.M1
|
||||||
|
*.hex2
|
||||||
|
|
||||||
|
# A place to put a good run for comparison
|
||||||
|
actual.M1
|
|
@ -0,0 +1,4 @@
|
||||||
|
#! /bin/sh
|
||||||
|
rm -f test/test20/struct.M1
|
||||||
|
rm -f test/test20/struct.hex2
|
||||||
|
exit 0
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef int (FUNCTION)(int);
|
|
@ -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
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include<stdlib.h>
|
||||||
|
#include<stdio.h>
|
||||||
|
#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);
|
||||||
|
}
|
Loading…
Reference in New Issue