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);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
5
makefile
5
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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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