Fixed crash bug on missing module, and on file name == keyword. Added summary to tester and corrected filename.

This commit is contained in:
Christoffer Lerno
2020-07-25 12:50:02 +02:00
committed by Christoffer Lerno
parent bd68380f06
commit e3566ba838
15 changed files with 71 additions and 38 deletions

View File

@@ -39,7 +39,7 @@ bool context_set_module_from_filename(Context *context)
int len = filename_to_module(context->file->full_path, buffer);
if (!len)
{
sema_error(context, "The filename '%s' could not be converted to a valid module name, try using an explicit module name.");
sema_error(context, "The filename '%s' could not be converted to a valid module name, try using an explicit module name.", context->file->full_path);
return false;
}
@@ -48,7 +48,7 @@ bool context_set_module_from_filename(Context *context)
if (type != TOKEN_IDENT)
{
sema_error(context, "Generating a filename from the file '%s' resulted in a name that is a reserved keyword, "
"try using an explicit module name.");
"try using an explicit module name.", context->file->full_path);
return false;
}
Path *path = CALLOCS(Path);
@@ -165,6 +165,7 @@ bool context_add_import(Context *context, Path *path, Token token, Token alias)
}
Decl *import = decl_calloc();
import->span = path->span;
import->decl_kind = DECL_IMPORT;
import->visibility = VISIBLE_LOCAL;
import->import.path = path;

View File

@@ -189,6 +189,7 @@ void sema_error_at_prev_end(Token token, const char *message, ...)
void sema_error(Context *context, const char *message, ...)
{
diagnostics.errors++;
File *file = lexer_current_file(&context->lexer);
va_list list;
va_start(list, message);
@@ -196,6 +197,8 @@ void sema_error(Context *context, const char *message, ...)
evprintf(message, list);
eprintf("\n");
va_end(list);
}

View File

@@ -1753,19 +1753,18 @@ static inline bool parse_optional_module_params(Context *context, TokenId **toke
* : MODULE path ';'
* | MODULE path '(' module_params ')' ';'
*/
static inline void parse_module(Context *context)
static inline bool parse_module(Context *context)
{
if (!try_consume(context, TOKEN_MODULE))
{
context_set_module_from_filename(context);
return;
return context_set_module_from_filename(context);
}
if (!TOKEN_IS(TOKEN_IDENT))
{
SEMA_TOKEN_ERROR(context->tok, "Module statement should be followed by the name of the module to import.");
return;
return false;
}
Path *path = parse_module_path(context);
@@ -1779,7 +1778,7 @@ static inline void parse_module(Context *context)
path->span = INVALID_RANGE;
context_set_module(context, path, NULL);
recover_top_level(context);
return;
return false;
}
// Is this a generic module?
@@ -1788,10 +1787,11 @@ static inline void parse_module(Context *context)
{
context_set_module(context, path, generic_parameters);
recover_top_level(context);
return;
return true;
}
context_set_module(context, path, generic_parameters);
TRY_CONSUME_EOS_OR();
TRY_CONSUME_EOS_OR(false);
return true;
}
/**
@@ -1906,7 +1906,7 @@ static inline void parse_current(Context *context)
{
// Prime everything
advance(context); advance(context);
parse_module(context);
if (!parse_module(context)) return;
parse_imports(context);
while (!TOKEN_IS(TOKEN_EOF))
{

View File

@@ -2,21 +2,26 @@
import os, sys, shutil, subprocess
TEST_DIR = '/tmp/c3test/'
class Config:
run_skipped = False
cwd = "."
numtests = 0
numsuccess = 0
numskipped = 0
class File:
def __init__(self, filepath):
with open(filepath) as reader:
self.content = reader.read().splitlines()
self.filename = filepath
self.filepath = filepath
self.filename = os.path.basename(filepath)
class Issues:
def __init__(self, conf, file, single):
self.conf = conf
self.file = file
self.single = single
self.line = 0
@@ -30,10 +35,10 @@ class Issues:
self.errors = {}
self.warnings = {}
if single:
self.current_file = conf.cwd + "/" + file.filename
self.current_file = conf.cwd + "/" + file.filepath
def exit_error(self, message):
print('Error in file ' + self.file.filename + ': ' + message)
print('Error in file ' + self.file.filepath + ': ' + message)
exit(-1)
def set_failed(self):
@@ -41,7 +46,6 @@ class Issues:
self.has_errors = True
def check_line(self, type, file, line, message):
if file == 'test.c3': file = self.file.filename
map = {}
if type == 'Error':
map = self.errors
@@ -92,13 +96,15 @@ class Issues:
if "// #" in line:
self.parse_trailing_directive(line)
self.line += 1
with open(TEST_DIR + 'test.c3', mode='w') as f:
target_file = TEST_DIR + self.file.filename
with open(target_file, mode='w') as f:
f.write("\n".join(self.file.content))
f.write("\n")
print("- " + self.file.filename + ":", end="")
self.compile("--test compile " + TEST_DIR + 'test.c3')
print("- " + self.file.filepath + ":", end="")
self.compile("--test compile " + target_file)
if not self.has_errors:
self.conf.numsuccess += 1
print(" Passed.")
def parse_header_directive(self, line):
@@ -143,7 +149,10 @@ class Issues:
def parse(self):
if len(self.file.content) == 0: self.exit_error("File was empty")
is_skip = self.file.content[0].startswith("// #skip")
if is_skip != self.skip: return
if is_skip != self.skip:
print("- " + self.file.filepath + ": *SKIPPED*")
self.conf.numskipped += 1
return
if is_skip: self.line += 1
if self.single:
@@ -201,5 +210,6 @@ def main():
handle_dir(filepath, conf)
else:
usage()
print("Found %d tests: %d / %d passed (%d skipped)." % (conf.numtests, conf.numsuccess, conf.numtests - conf.numskipped, conf.numskipped))
main()

View File

@@ -0,0 +1,3 @@
func void foo) // #error: Expected '('
{
}

View File

@@ -0,0 +1,3 @@
module test // #error: Expected ';'
int a;

View File

@@ -0,0 +1,4 @@
module test;
import foo; // #error: No module named 'foo' could be found.
import bar; // #error: No module named 'bar' could be found.

View File

@@ -0,0 +1,7 @@
func void foo(int a) {}
public func int main()
{
foo(10, foo(); // #error: Expected the ending ')'
return 0;
}

View File

@@ -0,0 +1,2 @@
typedef func void (int a = 10) as Foo; // #error: Function types may not have default arguments.

View File

@@ -1,4 +1,5 @@
/*
// #skip
module for_test;
public func int main()
{
@@ -28,4 +29,3 @@ public func int test3()
}
return 0;
}
*/

View File

@@ -0,0 +1,5 @@
public func int main()
{
if (int a) {} // #error: Expected a declaration with initializer
return 0;
}

View File

@@ -1,21 +1,4 @@
enum EnumTestOverflow
{
VALUE = 0x80000000, // #error: does not fit in type 'int'
}
enum EnumTestErrorType : float // #error: must be an integer type not 'float'
{
VALUE_BOOM
}
enum EnumWithErrorType2 : int* // #error: must be an integer type not 'int*'
{
TEST
}
enum EnumTestErrorType3 : int
{
A = FOO // #error: Identifier 'FOO' could not be found

View File

@@ -0,0 +1,9 @@
enum EnumTestErrorType : float // #error: must be an integer type not 'float'
{
VALUE_BOOM
}
enum EnumWithErrorType2 : int* // #error: must be an integer type not 'int*'
{
TEST
}

View File

@@ -0,0 +1,4 @@
enum EnumTestOverflow
{
VALUE = 0x80000000, // #error: does not fit in type 'int'
}

View File

@@ -15,7 +15,6 @@ enum EnumWithErrorData2 : int (int, int bar) // #error: function parameter must
}
enum EnumTestErrorType3 : int
{
A,