Start reducing number of segfaults possible in M2-Planet

This commit is contained in:
Jeremiah Orians 2020-01-22 18:03:28 -05:00
parent 923784c797
commit 4b2a048f14
No known key found for this signature in database
GPG Key ID: 5410E91C14959E87
12 changed files with 133 additions and 83 deletions

View File

@ -38,11 +38,13 @@ int current_count;
int Address_of;
/* Imported functions */
char* number_to_hex(int a, int bytes);
char* numerate_number(int a);
char* parse_string(char* string);
int escape_lookup(char* c);
char* numerate_number(int a);
int numerate_string(char *a);
char* number_to_hex(int a, int bytes);
void require(int bool, char* error);
struct token_list* emit(char *s, struct token_list* head)
{
@ -89,6 +91,7 @@ struct token_list* sym_lookup(char *s, struct token_list* symbol_list)
void line_error()
{
require(NULL != global_token, "EOF reached inside of line_error\n");
file_print(global_token->filename, stderr);
file_print(":", stderr);
file_print(numerate_number(global_token->linenumber), stderr);
@ -97,6 +100,7 @@ void line_error()
void require_match(char* message, char* required)
{
require(NULL != global_token, "EOF reached inside of require match\n");
if(!match(global_token->s, required))
{
line_error();
@ -104,6 +108,7 @@ void require_match(char* message, char* required)
exit(EXIT_FAILURE);
}
global_token = global_token->next;
require(NULL != global_token, "EOF after require match occurred\n");
}
void expression();
@ -140,6 +145,7 @@ void function_call(char* s, int bool)
if(global_token->s[0] != ')')
{
expression();
require(NULL != global_token, "incomplete function call, recieved EOF instead of )\n");
if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("PUSHR R0 R15\t#_process_expression1\n");
else if(X86 == Architecture) emit_out("PUSH_eax\t#_process_expression1\n");
else if(AMD64 == Architecture) emit_out("PUSH_RAX\t#_process_expression1\n");
@ -149,6 +155,7 @@ void function_call(char* s, int bool)
while(global_token->s[0] == ',')
{
global_token = global_token->next;
require(NULL != global_token, "incomplete function call, recieved EOF instead of argument\n");
expression();
if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("PUSHR R0 R15\t#_process_expression2\n");
else if(X86 == Architecture) emit_out("PUSH_eax\t#_process_expression2\n");
@ -280,6 +287,7 @@ void constant_load(struct token_list* a)
void variable_load(struct token_list* a)
{
require(NULL != global_token, "incomplete variable load recieved\n");
if(match("FUNCTION", a->type->name) && match("(", global_token->s))
{
function_call(numerate_number(a->depth), TRUE);
@ -307,6 +315,7 @@ void variable_load(struct token_list* a)
void function_load(struct token_list* a)
{
require(NULL != global_token, "incomplete function load\n");
if(match("(", global_token->s))
{
function_call(a->s, FALSE);
@ -332,6 +341,8 @@ void global_load(struct token_list* a)
else if(ARMV7L == Architecture) emit_out("!0 R0 LOAD32 R15 MEMORY\n~0 JUMP_ALWAYS\n&GLOBAL_");
emit_out(a->s);
emit_out("\n");
require(NULL != global_token, "unterminated global load\n");
if(!match("=", global_token->s))
{
if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("LOAD R0 R0 0\n");
@ -353,6 +364,7 @@ void global_load(struct token_list* a)
void primary_expr_failure()
{
require(NULL != global_token, "hit EOF when expecting primary expression\n");
line_error();
file_print("Received ", stderr);
file_print(global_token->s, stderr);
@ -505,6 +517,7 @@ void common_recursion(FUNCTION f)
struct type* last_type = current_target;
global_token = global_token->next;
require(NULL != global_token, "Recieved EOF in common_recursion\n");
f();
current_target = promote_type(current_target, last_type);
@ -516,6 +529,7 @@ void common_recursion(FUNCTION f)
void general_recursion(FUNCTION f, char* s, char* name, FUNCTION iterate)
{
require(NULL != global_token, "Recieved EOF in general_recursion\n");
if(match(name, global_token->s))
{
common_recursion(f);
@ -526,6 +540,7 @@ void general_recursion(FUNCTION f, char* s, char* name, FUNCTION iterate)
void arithmetic_recursion(FUNCTION f, char* s1, char* s2, char* name, FUNCTION iterate)
{
require(NULL != global_token, "Recieved EOF in arithmetic_recursion\n");
if(match(name, global_token->s))
{
common_recursion(f);
@ -575,10 +590,12 @@ void postfix_expr_arrow()
{
emit_out("# looking up offset\n");
global_token = global_token->next;
require(NULL != global_token, "naked -> not allowed\n");
struct type* i = lookup_member(current_target, global_token->s);
current_target = i->type;
global_token = global_token->next;
require(NULL != global_token, "Unterminated -> expression not allowed\n");
if(0 != i->offset)
{
@ -623,6 +640,8 @@ void postfix_expr_array()
struct type* array = current_target;
common_recursion(expression);
current_target = array;
require(NULL != current_target, "Arrays only apply to variables\n");
char* assign;
if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) assign = "LOAD R0 R0 0\n";
else if(X86 == Architecture) assign = "LOAD_INTEGER\n";
@ -675,6 +694,7 @@ struct type* type_name();
void unary_expr_sizeof()
{
global_token = global_token->next;
require(NULL != global_token, "Recieved EOF when starting sizeof\n");
require_match("ERROR in unary_expr\nMissing (\n", "(");
struct type* a = type_name();
require_match("ERROR in unary_expr\nMissing )\n", ")");
@ -690,6 +710,7 @@ void unary_expr_sizeof()
void postfix_expr_stub()
{
require(NULL != global_token, "Unexpected EOF, improperly terminated primary expression\n");
if(match("[", global_token->s))
{
postfix_expr_array();
@ -887,10 +908,12 @@ void bitwise_expr()
void primary_expr()
{
require(NULL != global_token, "Recieved EOF where primary expression expected\n");
if(match("&", global_token->s))
{
Address_of = TRUE;
global_token = global_token->next;
require(NULL != global_token, "Recieved EOF after & where primary expression expected\n");
}
else
{
@ -1016,10 +1039,12 @@ void collect_local()
emit_out("\n");
global_token = global_token->next;
require(NULL != global_token, "incomplete local missing name\n");
if(match("=", global_token->s))
{
global_token = global_token->next;
require(NULL != global_token, "incomplete local assignment\n");
expression();
}
@ -1073,6 +1098,7 @@ void process_if()
if(match("else", global_token->s))
{
global_token = global_token->next;
require(NULL != global_token, "Recieved EOF where an else statement expected\n");
statement();
}
emit_out(":_END_IF_");
@ -1170,6 +1196,7 @@ void process_asm()
emit_out((global_token->s + 1));
emit_out("\n");
global_token = global_token->next;
require(NULL != global_token, "Recieved EOF inside asm statement\n");
}
require_match("ERROR in process_asm\nMISSING )\n", ")");
require_match("ERROR in process_asm\nMISSING ;\n", ";");
@ -1195,6 +1222,7 @@ void process_do()
uniqueID_out(function->s, number_string);
global_token = global_token->next;
require(NULL != global_token, "Recieved EOF where do statement is expected\n");
statement();
require_match("ERROR in process_do\nMISSING while\n", "while");
@ -1274,6 +1302,7 @@ void process_while()
void return_result()
{
global_token = global_token->next;
require(NULL != global_token, "Incomplete return statement recieved\n");
if(global_token->s[0] != ';') expression();
require_match("ERROR in return_result\nMISSING ;\n", ";");
@ -1330,11 +1359,13 @@ void process_break()
void recursive_statement()
{
global_token = global_token->next;
require(NULL != global_token, "Recieved EOF in recursive statement\n");
struct token_list* frame = function->locals;
while(!match("}", global_token->s))
{
statement();
require(NULL != global_token, "Recieved EOF in recursive statement prior to }\n");
}
global_token = global_token->next;
@ -1416,6 +1447,7 @@ void statement()
else if(match("goto", global_token->s))
{
global_token = global_token->next;
require(NULL != global_token, "naked goto is not supported\n");
if((KNIGHT_POSIX == Architecture) || (KNIGHT_NATIVE == Architecture)) emit_out("JUMP @");
else if(X86 == Architecture) emit_out("JUMP %");
else if(AMD64 == Architecture) emit_out("JUMP %");
@ -1451,6 +1483,7 @@ void statement()
void collect_arguments()
{
global_token = global_token->next;
require(NULL != global_token, "Recieved EOF when attempting to collect arguments\n");
while(!match(")", global_token->s))
{
@ -1480,11 +1513,18 @@ void collect_arguments()
}
global_token = global_token->next;
require(NULL != global_token, "Incomplete argument list\n");
function->arguments = a;
}
/* ignore trailing comma (needed for foo(bar(), 1); expressions*/
if(global_token->s[0] == ',') global_token = global_token->next;
if(global_token->s[0] == ',')
{
global_token = global_token->next;
require(NULL != global_token, "naked comma in collect arguments\n");
}
require(NULL != global_token, "Argument list never completed\n");
}
global_token = global_token->next;
}
@ -1503,6 +1543,7 @@ void declare_function()
}
else collect_arguments();
require(NULL != global_token, "Function definitions either need to be prototypes or full\n");
/* If just a prototype don't waste time */
if(global_token->s[0] == ';') global_token = global_token->next;
else
@ -1552,8 +1593,10 @@ new_type:
if(match("CONSTANT", global_token->s))
{
global_token = global_token->next;
require(NULL != global_token, "CONSTANT lacks a name\n");
global_constant_list = sym_declare(global_token->s, NULL, global_constant_list);
require(NULL != global_token->next, "CONSTANT lacks a value\n");
if(match("sizeof", global_token->next->s))
{
global_token = global_token->next->next;
@ -1579,6 +1622,7 @@ new_type:
/* Add to global symbol table */
global_symbol_list = sym_declare(global_token->s, type_size, global_symbol_list);
global_token = global_token->next;
require(NULL != global_token, "Unterminated global\n");
if(match(";", global_token->s))
{
/* Ensure 4 bytes are allocated for the global */
@ -1596,6 +1640,7 @@ new_type:
globals_list = emit(global_token->prev->s, globals_list);
globals_list = emit("\n", globals_list);
global_token = global_token->next;
require(NULL != global_token, "Global locals value in assignment\n");
if(in_set(global_token->s[0], "0123456789"))
{ /* Assume Int */
globals_list = emit("%", globals_list);

View File

@ -16,23 +16,16 @@
*/
#include "cc.h"
/* imported functions */
int in_set(int c, char* s);
void require(int bool, char* error);
/* Globals */
FILE* input;
struct token_list* token;
int line;
char* file;
int in_set(int c, char* s);
/* Deal with common errors */
void require(int bool, char* error)
{
if(!bool)
{
file_print(error, stderr);
exit(EXIT_FAILURE);
}
}
int clearWhiteSpace(int c)
{

View File

@ -17,8 +17,11 @@
#include "cc.h"
#include <stdint.h>
void line_error();
/* Imported functions */
int numerate_string(char *a);
void line_error();
void require(int bool, char* error);
/* Initialize default types */
void initialize_types()
@ -156,6 +159,7 @@ struct type* lookup_type(char* s, struct type* start)
struct type* lookup_member(struct type* parent, char* name)
{
struct type* i;
require(NULL != parent, "Not a valid struct type\n");
for(i = parent->members; NULL != i; i = i->members)
{
if(match(i->name, name)) return i;
@ -182,14 +186,17 @@ struct type* build_member(struct type* last, int offset)
i->offset = offset;
struct type* member_type = type_name();
require(NULL != member_type, "struct member type can not be invalid\n");
i->type = member_type;
i->name = global_token->s;
global_token = global_token->next;
require(NULL != global_token, "struct member can not be EOF terminated\n");
/* Check to see if array */
if(match( "[", global_token->s))
{
global_token = global_token->next;
require(NULL != global_token, "struct member arrays can not be EOF sized\n");
i->size = member_type->type->size * numerate_string(global_token->s);
if(0 == i->size)
{
@ -221,6 +228,7 @@ struct type* build_union(struct type* last, int offset)
size = member_size;
}
require_match("ERROR in build_union\nMissing ;\n", ";");
require(NULL != global_token, "Unterminated union\n");
}
member_size = size;
global_token = global_token->next;
@ -257,6 +265,7 @@ void create_struct()
}
offset = offset + member_size;
require_match("ERROR in create_struct\n Missing ;\n", ";");
require(NULL != global_token, "Unterminated struct\n");
}
global_token = global_token->next;
@ -272,9 +281,11 @@ struct type* type_name()
{
struct type* ret;
require(NULL != global_token, "Recieved EOF instead of type name\n");
if(match("struct", global_token->s))
{
global_token = global_token->next;
require(NULL != global_token, "structs can not have a EOF type name\n");
ret = lookup_type(global_token->s, global_types);
if(NULL == ret)
{
@ -296,16 +307,19 @@ struct type* type_name()
}
global_token = global_token->next;
require(NULL != global_token, "unfinished type definition\n");
if(match("const", global_token->s))
{
global_token = global_token->next;
require(NULL != global_token, "unfinished type definition in const\n");
}
while(global_token->s[0] == '*')
{
ret = ret->indirect;
global_token = global_token->next;
require(NULL != global_token, "unfinished type definition in indirection\n");
}
return ret;

31
functions/require.c Normal file
View File

@ -0,0 +1,31 @@
/* Copyright (C) 2016 Jeremiah Orians
* Copyright (C) 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
* This file is part of M2-Planet.
*
* M2-Planet 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.
*
* M2-Planet 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 M2-Planet. If not, see <http://www.gnu.org/licenses/>.
*/
#include<stdio.h>
#include<stdlib.h>
void file_print(char* s, FILE* f);
void require(int bool, char* error)
{
if(!bool)
{
file_print(error, stderr);
exit(EXIT_FAILURE);
}
}

View File

@ -18,10 +18,29 @@
VPATH = bin:test:test/results
PACKAGE = m2-planet
# C compiler settings
CC?=gcc
CFLAGS:=$(CFLAGS) -D_GNU_SOURCE -O0 -std=c99 -ggdb
all: M2-Planet
M2-Planet: bin results cc.h cc_reader.c cc_strings.c cc_types.c cc_core.c cc.c
./test/test100/hello.sh
$(CC) $(CFLAGS) \
functions/match.c \
functions/in_set.c \
functions/numerate_number.c \
functions/file_print.c \
functions/number_pack.c \
functions/string.c \
functions/require.c \
cc_reader.c \
cc_strings.c \
cc_types.c \
cc_core.c \
cc.c \
cc.h \
gcc_req.h \
-o bin/M2-Planet
# Clean up after ourselves
.PHONY: clean

View File

@ -53,10 +53,10 @@ a0ae067746e7a2b01d33950da1cf640e12c3a70a045ab331ea2025af59dec9af test/results/t
1154f39f25dcd6d914e9a542306f95280926baf985d011b2152c7ea0b87ab42d test/results/test10-knight-native-binary
c1b5a2a3cd46c5e95e5540e871c2a916e028684ca80f51c001ef489342e27625 test/results/test10-knight-posix-binary
b3e13d54aab689137628fb9c4487bfd8288f9bd18bef8fe756577c8d2dce1f1f test/results/test10-x86-binary
c0becbe4e1edb7218bf2f6849493f768da8078a87af18ff093eaf9f6c1fcb9e7 test/results/test100-amd64-binary
d95bd6ad6a59ef9f508e462ebb4b716f2799ed30a5882c549156cb0f3ca00a42 test/results/test100-armv7l-binary
d044e557477b6a2db1c983d353bc7aa2080600894839947f5191ee524f231300 test/results/test100-knight-posix-binary
8e33e2bf5cdb0c127cca0c4bdbc627d7f2cbdb5130aadedbfc01a379520174a0 test/results/test100-x86-binary
1b6e8c0ab5a944f1d83065db5d18a265c6e14109c532b89d3cc316b4074f9e73 test/results/test100-amd64-binary
540ca777bf1a48c51ae9ca9e172ded87b28362adee9ca220c176122e872f6c45 test/results/test100-armv7l-binary
6f8d22172abf64e5cfc8621c81236aab58de96fdc79332475df0e1c5b87821a3 test/results/test100-knight-posix-binary
7637a9078de8914e2821df07371083b319a095d51e237881e526290ab472df67 test/results/test100-x86-binary
34e6d535e30ef8826a4ad1a4d08b76cfa370c54595599ad3be784b64c9cd8ec5 test/results/test11-amd64-binary
893695e6f300a0fe055fad935a56abd549bba70d1d39c535a680f41bbb73f117 test/results/test11-armv7l-binary
955b564d2c89abf2cfc6c80d766cd11479d146b828dec69e654b0958a62d5e6e test/results/test11-knight-native-binary

View File

@ -28,6 +28,7 @@ set -ex
-f functions/file_print.c \
-f functions/number_pack.c \
-f functions/string.c \
-f functions/require.c \
-f cc.h \
-f cc_reader.c \
-f cc_strings.c \
@ -73,6 +74,7 @@ then
-f functions/file_print.c \
-f functions/number_pack.c \
-f functions/string.c \
-f functions/require.c \
-f cc.h \
-f cc_reader.c \
-f cc_strings.c \

View File

@ -28,6 +28,7 @@ set -ex
-f functions/file_print.c \
-f functions/number_pack.c \
-f functions/string.c \
-f functions/require.c \
-f cc.h \
-f cc_reader.c \
-f cc_strings.c \
@ -73,6 +74,7 @@ then
-f functions/file_print.c \
-f functions/number_pack.c \
-f functions/string.c \
-f functions/require.c \
-f cc.h \
-f cc_reader.c \
-f cc_strings.c \

View File

@ -28,6 +28,7 @@ set -ex
-f functions/file_print.c \
-f functions/number_pack.c \
-f functions/string.c \
-f functions/require.c \
-f cc.h \
-f cc_reader.c \
-f cc_strings.c \
@ -68,6 +69,7 @@ then
-f functions/file_print.c \
-f functions/number_pack.c \
-f functions/string.c \
-f functions/require.c \
-f cc.h \
-f cc_reader.c \
-f cc_strings.c \

View File

@ -28,6 +28,7 @@ set -ex
-f functions/file_print.c \
-f functions/number_pack.c \
-f functions/string.c \
-f functions/require.c \
-f cc.h \
-f cc_reader.c \
-f cc_strings.c \
@ -73,6 +74,7 @@ then
-f functions/file_print.c \
-f functions/number_pack.c \
-f functions/string.c \
-f functions/require.c \
-f cc.h \
-f cc_reader.c \
-f cc_strings.c \

View File

@ -1,60 +0,0 @@
#! /bin/sh
## Copyright (C) 2017 Jeremiah Orians
## This file is part of M2-Planet.
##
## M2-Planet 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.
##
## M2-Planet 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 M2-Planet. If not, see <http://www.gnu.org/licenses/>.
set -ex
# Build using seed if possible
if [ -f bin/M2-Planet-seed ]
then
[ ! -f test/results ] && mkdir -p test/results
cp bin/M2-Planet-seed bin/M2-Planet
if [ "$(get_machine ${GET_MACHINE_FLAGS})" = "amd64" ]
then
./test/test100/hello-amd64.sh
mv test/results/test100-amd64-binary bin/M2-Planet
elif [ "$(get_machine ${GET_MACHINE_FLAGS})" = "x86" ]
then
./test/test100/hello-x86.sh
mv test/results/test100-x86-binary bin/M2-Planet
elif [ "$(get_machine ${GET_MACHINE_FLAGS})" = "armv7l" ]
then
./test/test100/hello-armv7l.sh
mv test/results/test100-armv7l-binary bin/M2-Planet
fi
else
[ -z "${CC+x}" ] && export CC=gcc
[ -z "${CFLAGS+x}" ] && export CFLAGS=" -D_GNU_SOURCE -O0 -std=c99 -ggdb"
${CC} ${CFLAGS} \
functions/match.c \
functions/in_set.c \
functions/numerate_number.c \
functions/file_print.c \
functions/number_pack.c \
functions/string.c \
cc_reader.c \
cc_strings.c \
cc_types.c \
cc_core.c \
cc.c \
cc.h \
gcc_req.h \
-o bin/M2-Planet || exit 5
fi
exit 0

View File

@ -1 +1 @@
cdfe50b2c9eac325f228fce9146358df4ef672f030cf936506a445555716cf89 test/test100/proof
77224b14932a67cddb5e21c3ba1f7a1604ce48b2a63792791eb48fbb76110053 test/test100/proof