corrected project to work with test_compiler.sh
This commit is contained in:
parent
26d10cfef0
commit
b2c2a2f497
15 changed files with 232 additions and 28 deletions
55
Compiler/.idea/.idea.Compiler/.idea/workspace.xml
generated
55
Compiler/.idea/.idea.Compiler/.idea/workspace.xml
generated
|
|
@ -20,14 +20,33 @@
|
||||||
</component>
|
</component>
|
||||||
<component name="ChangeListManager">
|
<component name="ChangeListManager">
|
||||||
<list default="true" id="a54bb6de-191c-4bd1-91ab-3953adfc5dfb" name="Default Changelist" comment="">
|
<list default="true" id="a54bb6de-191c-4bd1-91ab-3953adfc5dfb" name="Default Changelist" comment="">
|
||||||
<change afterPath="$PROJECT_DIR$/Generator/Generator.cs" afterDir="false" />
|
<change afterPath="$PROJECT_DIR$/../stage_1/invalid/missing_paren.c" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/.idea/.idea.Compiler/.idea/contentModel.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/.idea.Compiler/.idea/contentModel.xml" afterDir="false" />
|
<change afterPath="$PROJECT_DIR$/../stage_1/invalid/missing_retval.c" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/../stage_1/invalid/no_brace.c" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/../stage_1/invalid/no_semicolon.c" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/../stage_1/invalid/no_space.c" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/../stage_1/invalid/wrong_case.c" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/../stage_1/valid/multi_digit.c" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/../stage_1/valid/newlines.c" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/../stage_1/valid/no_newlines.c" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/../stage_1/valid/return_0.c" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/../stage_1/valid/return_2.c" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/../stage_1/valid/spaces.c" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/../test_compiler.sh" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/.idea/.idea.Compiler/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/.idea.Compiler/.idea/workspace.xml" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/.idea/.idea.Compiler/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/.idea.Compiler/.idea/workspace.xml" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/Compiler.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Compiler.cs" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/Compiler.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Compiler.cs" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/Parser/Nodes/NodeType.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Parser/Nodes/NodeType.cs" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/../tests/week_1/invalid/missing_paren.c" beforeDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/Parser/Nodes/ReturnNode.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Parser/Nodes/ReturnNode.cs" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/../tests/week_1/invalid/missing_retval.c" beforeDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/Parser/Parser.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Parser/Parser.cs" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/../tests/week_1/invalid/no_brace.c" beforeDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/../test.s" beforeDir="false" />
|
<change beforePath="$PROJECT_DIR$/../tests/week_1/invalid/no_semicolon.c" beforeDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/../tests/week_1/invalid/no_space.c" beforeDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/../tests/week_1/invalid/wrong_case.c" beforeDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/../tests/week_1/valid/multi_digit.c" beforeDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/../tests/week_1/valid/newlines.c" beforeDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/../tests/week_1/valid/no_newlines.c" beforeDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/../tests/week_1/valid/return_0.c" beforeDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/../tests/week_1/valid/return_2.c" beforeDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/../tests/week_1/valid/spaces.c" beforeDir="false" />
|
||||||
</list>
|
</list>
|
||||||
<option name="SHOW_DIALOG" value="false" />
|
<option name="SHOW_DIALOG" value="false" />
|
||||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||||
|
|
@ -164,7 +183,7 @@
|
||||||
<workItem from="1597620399423" duration="389000" />
|
<workItem from="1597620399423" duration="389000" />
|
||||||
<workItem from="1597650936637" duration="537000" />
|
<workItem from="1597650936637" duration="537000" />
|
||||||
<workItem from="1597695400525" duration="4873000" />
|
<workItem from="1597695400525" duration="4873000" />
|
||||||
<workItem from="1597863017034" duration="7430000" />
|
<workItem from="1597863017034" duration="9501000" />
|
||||||
</task>
|
</task>
|
||||||
<servers />
|
<servers />
|
||||||
</component>
|
</component>
|
||||||
|
|
@ -202,22 +221,22 @@
|
||||||
<screen x="1920" y="0" width="1920" height="1080" />
|
<screen x="1920" y="0" width="1920" height="1080" />
|
||||||
</state>
|
</state>
|
||||||
<state x="2169" y="170" width="430" height="508" key="FileChooserDialogImpl/1920.0.1920.1080/0.0.1920.1080@1920.0.1920.1080" timestamp="1597507670532" />
|
<state x="2169" y="170" width="430" height="508" key="FileChooserDialogImpl/1920.0.1920.1080/0.0.1920.1080@1920.0.1920.1080" timestamp="1597507670532" />
|
||||||
<state width="1868" height="577" key="GridCell.Tab.0.bottom" timestamp="1597868778558">
|
<state width="908" height="577" key="GridCell.Tab.0.bottom" timestamp="1597872134303">
|
||||||
<screen x="1920" y="0" width="1920" height="1080" />
|
<screen x="1920" y="0" width="1920" height="1080" />
|
||||||
</state>
|
</state>
|
||||||
<state width="1868" height="577" key="GridCell.Tab.0.bottom/1920.0.1920.1080/0.0.1920.1080@1920.0.1920.1080" timestamp="1597868778558" />
|
<state width="908" height="577" key="GridCell.Tab.0.bottom/1920.0.1920.1080/0.0.1920.1080@1920.0.1920.1080" timestamp="1597872134303" />
|
||||||
<state width="1868" height="577" key="GridCell.Tab.0.center" timestamp="1597868778558">
|
<state width="908" height="577" key="GridCell.Tab.0.center" timestamp="1597872134303">
|
||||||
<screen x="1920" y="0" width="1920" height="1080" />
|
<screen x="1920" y="0" width="1920" height="1080" />
|
||||||
</state>
|
</state>
|
||||||
<state width="1868" height="577" key="GridCell.Tab.0.center/1920.0.1920.1080/0.0.1920.1080@1920.0.1920.1080" timestamp="1597868778558" />
|
<state width="908" height="577" key="GridCell.Tab.0.center/1920.0.1920.1080/0.0.1920.1080@1920.0.1920.1080" timestamp="1597872134303" />
|
||||||
<state width="1868" height="577" key="GridCell.Tab.0.left" timestamp="1597868778558">
|
<state width="908" height="577" key="GridCell.Tab.0.left" timestamp="1597872134302">
|
||||||
<screen x="1920" y="0" width="1920" height="1080" />
|
<screen x="1920" y="0" width="1920" height="1080" />
|
||||||
</state>
|
</state>
|
||||||
<state width="1868" height="577" key="GridCell.Tab.0.left/1920.0.1920.1080/0.0.1920.1080@1920.0.1920.1080" timestamp="1597868778558" />
|
<state width="908" height="577" key="GridCell.Tab.0.left/1920.0.1920.1080/0.0.1920.1080@1920.0.1920.1080" timestamp="1597872134302" />
|
||||||
<state width="1868" height="577" key="GridCell.Tab.0.right" timestamp="1597868778558">
|
<state width="908" height="577" key="GridCell.Tab.0.right" timestamp="1597872134303">
|
||||||
<screen x="1920" y="0" width="1920" height="1080" />
|
<screen x="1920" y="0" width="1920" height="1080" />
|
||||||
</state>
|
</state>
|
||||||
<state width="1868" height="577" key="GridCell.Tab.0.right/1920.0.1920.1080/0.0.1920.1080@1920.0.1920.1080" timestamp="1597868778558" />
|
<state width="908" height="577" key="GridCell.Tab.0.right/1920.0.1920.1080/0.0.1920.1080@1920.0.1920.1080" timestamp="1597872134303" />
|
||||||
<state width="1868" height="383" key="GridCell.Tab.1.bottom" timestamp="1597865244687">
|
<state width="1868" height="383" key="GridCell.Tab.1.bottom" timestamp="1597865244687">
|
||||||
<screen x="1920" y="0" width="1920" height="1080" />
|
<screen x="1920" y="0" width="1920" height="1080" />
|
||||||
</state>
|
</state>
|
||||||
|
|
@ -282,10 +301,10 @@
|
||||||
<screen x="1920" y="0" width="1920" height="1080" />
|
<screen x="1920" y="0" width="1920" height="1080" />
|
||||||
</state>
|
</state>
|
||||||
<state width="1868" height="383" key="GridCell.Tab.4.right/1920.0.1920.1080/0.0.1920.1080@1920.0.1920.1080" timestamp="1597865244688" />
|
<state width="1868" height="383" key="GridCell.Tab.4.right/1920.0.1920.1080/0.0.1920.1080@1920.0.1920.1080" timestamp="1597865244688" />
|
||||||
<state x="1989" y="220" width="806" height="524" key="Rider.ProjectTemplateDialog.Size" timestamp="1597507532464">
|
<state x="631" y="291" width="806" height="524" key="Rider.ProjectTemplateDialog.Size" timestamp="1597872082099">
|
||||||
<screen x="1920" y="0" width="1920" height="1080" />
|
<screen x="0" y="0" width="1920" height="1080" />
|
||||||
</state>
|
</state>
|
||||||
<state x="1989" y="220" width="806" height="524" key="Rider.ProjectTemplateDialog.Size/1920.0.1920.1080/0.0.1920.1080@1920.0.1920.1080" timestamp="1597507532464" />
|
<state x="631" y="291" width="806" height="524" key="Rider.ProjectTemplateDialog.Size/1920.0.1920.1080/0.0.1920.1080@1920.0.1920.1080" timestamp="1597872082099" />
|
||||||
<state x="2336" y="41" width="709" height="485" key="RiderGenerateDialog" timestamp="1597863779733">
|
<state x="2336" y="41" width="709" height="485" key="RiderGenerateDialog" timestamp="1597863779733">
|
||||||
<screen x="1920" y="0" width="1920" height="1080" />
|
<screen x="1920" y="0" width="1920" height="1080" />
|
||||||
</state>
|
</state>
|
||||||
|
|
|
||||||
|
|
@ -13,19 +13,35 @@ namespace Compiler
|
||||||
{
|
{
|
||||||
public static void Main(string[] args)
|
public static void Main(string[] args)
|
||||||
{
|
{
|
||||||
if (args.Length != 1)
|
if (args.Length < 1)
|
||||||
{
|
{
|
||||||
Console.WriteLine("Usage: Compiler <input path>");
|
Console.WriteLine("Usage: Compiler <input path> [optional: -v]");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
bool debug = false;
|
||||||
|
string inputFileName = args[0].Split("/").Last();
|
||||||
string outputPath = args[0].Substring(0, args[0].LastIndexOf("/"));
|
string outputPath = args[0].Substring(0, args[0].LastIndexOf("/"));
|
||||||
|
|
||||||
Compile(args[0], $"{outputPath}/assembly.s");
|
if (args.Length == 2)
|
||||||
|
{
|
||||||
|
if (args[2] == "-v")
|
||||||
|
{
|
||||||
|
debug = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Compile(args[0], $"{outputPath}/assembly.s", debug);
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
Console.WriteLine($"Compiled to {outputPath}/assembly.s");
|
Console.WriteLine($"Compiled to {outputPath}/assembly.s");
|
||||||
|
}
|
||||||
|
|
||||||
ProcessStartInfo startInfo = new ProcessStartInfo()
|
ProcessStartInfo startInfo = new ProcessStartInfo()
|
||||||
{FileName = "gcc", Arguments = $"{outputPath}/assembly.s -o {outputPath}/program"};
|
{
|
||||||
|
FileName = "gcc",
|
||||||
|
Arguments = $"{outputPath}/assembly.s -o {outputPath}/{inputFileName.Replace(".c", "")}"
|
||||||
|
};
|
||||||
Process proc = new Process() {StartInfo = startInfo,};
|
Process proc = new Process() {StartInfo = startInfo,};
|
||||||
proc.Start();
|
proc.Start();
|
||||||
|
|
||||||
|
|
@ -33,14 +49,19 @@ namespace Compiler
|
||||||
{
|
{
|
||||||
Thread.Sleep(1);
|
Thread.Sleep(1);
|
||||||
}
|
}
|
||||||
Console.WriteLine($"Assembled to {outputPath}/program");
|
|
||||||
File.Delete($"{outputPath}/assembly.s");
|
File.Delete($"{outputPath}/assembly.s");
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"Assembled to {outputPath}/program");
|
||||||
Console.WriteLine("Deleted assembly.s file. Done!");
|
Console.WriteLine("Deleted assembly.s file. Done!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void Compile(string inputPath, string outputPath)
|
static void Compile(string inputPath, string outputPath, bool debug)
|
||||||
{
|
{
|
||||||
//Lexing
|
//Lexing
|
||||||
Lexer.Lexer lexer = new Lexer.Lexer();
|
Lexer.Lexer lexer = new Lexer.Lexer();
|
||||||
|
|
@ -50,7 +71,10 @@ namespace Compiler
|
||||||
string contents = file.ReadToEnd();
|
string contents = file.ReadToEnd();
|
||||||
|
|
||||||
List<Token> tokens = lexer.Lex(contents);
|
List<Token> tokens = lexer.Lex(contents);
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
Console.WriteLine($"Lexed {inputPath.Split("/").Last()}.");
|
Console.WriteLine($"Lexed {inputPath.Split("/").Last()}.");
|
||||||
|
}
|
||||||
|
|
||||||
//Parsing
|
//Parsing
|
||||||
Parser.Parser p = new Parser.Parser(tokens);
|
Parser.Parser p = new Parser.Parser(tokens);
|
||||||
|
|
@ -58,7 +82,10 @@ namespace Compiler
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Node programNode = p.Parse(NodeType.ProgramNode);
|
Node programNode = p.Parse(NodeType.ProgramNode);
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
Console.WriteLine($"Parsed \"{inputPath.Split("/").Last()}\"");
|
Console.WriteLine($"Parsed \"{inputPath.Split("/").Last()}\"");
|
||||||
|
}
|
||||||
|
|
||||||
//Generating
|
//Generating
|
||||||
Generator.Generator generator = new Generator.Generator();
|
Generator.Generator generator = new Generator.Generator();
|
||||||
|
|
|
||||||
158
test_compiler.sh
Executable file
158
test_compiler.sh
Executable file
|
|
@ -0,0 +1,158 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
padding_dots=$(printf '%0.1s' "."{1..60})
|
||||||
|
padlength=50
|
||||||
|
cmp=$1
|
||||||
|
success_total=0
|
||||||
|
failure_total=0
|
||||||
|
|
||||||
|
print_test_name () {
|
||||||
|
test_name=$1
|
||||||
|
printf '%s' "$test_name"
|
||||||
|
printf '%*.*s' 0 $((padlength - ${#test_name})) "$padding_dots"
|
||||||
|
}
|
||||||
|
|
||||||
|
test_success () {
|
||||||
|
echo "OK"
|
||||||
|
((success++))
|
||||||
|
}
|
||||||
|
|
||||||
|
test_failure () {
|
||||||
|
echo "FAIL"
|
||||||
|
((fail++))
|
||||||
|
}
|
||||||
|
|
||||||
|
test_not_implemented () {
|
||||||
|
echo "NOT IMPLEMENTED"
|
||||||
|
}
|
||||||
|
|
||||||
|
run_our_program () {
|
||||||
|
actual_out=`./$1 2>/dev/null`
|
||||||
|
actual_exit_code=$?
|
||||||
|
rm $1 2>/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
run_correct_program () {
|
||||||
|
expected_out=`./a.out`
|
||||||
|
expected_exit_code=$?
|
||||||
|
rm a.out
|
||||||
|
}
|
||||||
|
|
||||||
|
compare_program_results () {
|
||||||
|
# make sure exit code is correct
|
||||||
|
if [ "$expected_exit_code" -ne "$actual_exit_code" ] || [ "$expected_out" != "$actual_out" ]
|
||||||
|
then
|
||||||
|
test_failure
|
||||||
|
else
|
||||||
|
test_success
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
test_stage () {
|
||||||
|
success=0
|
||||||
|
fail=0
|
||||||
|
echo "===================================================="
|
||||||
|
echo "STAGE $1"
|
||||||
|
echo "===================Valid Programs==================="
|
||||||
|
for prog in `find . -type f -name "*.c" -path "./stage_$1/valid/*" -not -path "*/valid_multifile/*" 2>/dev/null`; do
|
||||||
|
|
||||||
|
gcc -w $prog
|
||||||
|
run_correct_program
|
||||||
|
|
||||||
|
base="${prog%.*}" #name of executable (filename w/out extension)
|
||||||
|
test_name="${base##*valid/}"
|
||||||
|
|
||||||
|
print_test_name $test_name
|
||||||
|
$cmp $prog 2>/dev/null
|
||||||
|
status=$?
|
||||||
|
|
||||||
|
if [[ $test_name == "skip_on_failure"* ]]; then
|
||||||
|
# this may depend on features we haven't implemented yet
|
||||||
|
# if compilation succeeds, make sure it gives the right result
|
||||||
|
# otherwise don't count it as success or failure
|
||||||
|
if [[ -f $base ]] && [[ $status -eq 0 ]]; then
|
||||||
|
# it succeeded, so run it and make sure it gives the right result
|
||||||
|
run_our_program $base
|
||||||
|
compare_program_results
|
||||||
|
else
|
||||||
|
test_not_implemented
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
run_our_program $base
|
||||||
|
compare_program_results
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
# programs with multiple source files
|
||||||
|
for dir in `ls -d stage_$1/valid_multifile/* 2>/dev/null` ; do
|
||||||
|
gcc -w $dir/*
|
||||||
|
|
||||||
|
run_correct_program
|
||||||
|
|
||||||
|
base="${dir%.*}" #name of executable (directory w/out extension)
|
||||||
|
test_name="${base##*valid_multifile/}"
|
||||||
|
|
||||||
|
# need to explicitly specify output name
|
||||||
|
$cmp -o "$test_name" $dir/* >/dev/null
|
||||||
|
|
||||||
|
print_test_name $test_name
|
||||||
|
|
||||||
|
# check output/exit codes
|
||||||
|
run_our_program $test_name
|
||||||
|
compare_program_results
|
||||||
|
|
||||||
|
done
|
||||||
|
echo "===================Invalid Programs================="
|
||||||
|
for prog in `ls stage_$1/invalid/{,**/}*.c 2>/dev/null`; do
|
||||||
|
|
||||||
|
base="${prog%.*}" #name of executable (filename w/out extension)
|
||||||
|
test_name="${base##*invalid/}"
|
||||||
|
|
||||||
|
$cmp $prog >/dev/null 2>&1
|
||||||
|
status=$? #failed, as we expect, if exit code != 0
|
||||||
|
print_test_name $test_name
|
||||||
|
|
||||||
|
# make sure neither executable nor assembly was produced
|
||||||
|
# and exit code is non-zero
|
||||||
|
if [[ -f $base || -f $base".s" ]]
|
||||||
|
then
|
||||||
|
test_failure
|
||||||
|
rm $base 2>/dev/null
|
||||||
|
rm $base".s" 2>/dev/null
|
||||||
|
else
|
||||||
|
test_success
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
echo "===================Stage $1 Summary================="
|
||||||
|
printf "%d successes, %d failures\n" $success $fail
|
||||||
|
((success_total=success_total+success))
|
||||||
|
((failure_total=failure_total + fail))
|
||||||
|
}
|
||||||
|
|
||||||
|
total_summary () {
|
||||||
|
echo "===================TOTAL SUMMARY===================="
|
||||||
|
printf "%d successes, %d failures\n" $success_total $failure_total
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ "$1" == "" ]; then
|
||||||
|
echo "USAGE: ./test_compiler.sh /path/to/compiler [stages(optional)]"
|
||||||
|
echo "EXAMPLE(test specific stages): ./test_compiler.sh ./mycompiler 1 2 4"
|
||||||
|
echo "EXAMPLE(test all): ./test_compiler.sh ./mycompiler"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test 1 -lt $#; then
|
||||||
|
testcases=("$@") # [1..-1] is testcases
|
||||||
|
for i in `seq 2 $#`; do
|
||||||
|
test_stage ${testcases[$i-1]}
|
||||||
|
done
|
||||||
|
total_summary
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
num_stages=10
|
||||||
|
|
||||||
|
for i in `seq 1 $num_stages`; do
|
||||||
|
test_stage $i
|
||||||
|
done
|
||||||
|
|
||||||
|
total_summary
|
||||||
Loading…
Add table
Add a link
Reference in a new issue