* net/loveruby/cflat/compiler/TypeChecker.java: reject incomplete multi-dimension array for function parameters.

* net/loveruby/cflat/compiler/TypeChecker.java: reject array variable definition without length.
* net/loveruby/cflat/type/Type.java: remove #isAllocated.
* net/loveruby/cflat/type/UserType.java: ditto.
* net/loveruby/cflat/type/ArrayType.java: change #isAllocatedArray semantics.  isAllocatedArray requires the all consecutive array types have its length, recursively.
* net/loveruby/cflat/type/ArrayType.java: new method #isIncompleteArray.
* net/loveruby/cflat/compiler/Compiler.java: new option --dump-asm.
* net/loveruby/cflat/compiler/Compiler.java: handle "--" on command line.
* test/run.sh: use bash.
* test/shunit.sh: show program name on core dump.
* test/syntax1.cb: int[][] is now invalid.
* cbci: print coredump and signal.


git-svn-id: file:///Users/aamine/c/gitwork/public/cbc/trunk@4010 1b9489fe-b721-0410-924e-b54b9192deb8
This commit is contained in:
Minero Aoki 2008-09-13 17:28:00 +00:00
parent ffba97e811
commit 09f1c83a3b
10 changed files with 121 additions and 39 deletions

View File

@ -1,3 +1,36 @@
Sun Sep 14 02:27:56 2008 Minero Aoki <aamine@loveruby.net>
* net/loveruby/cflat/compiler/TypeChecker.java: reject incomplete
multi-dimension array for function parameters.
* net/loveruby/cflat/compiler/TypeChecker.java: reject array
variable definition without length.
* net/loveruby/cflat/type/Type.java: remove #isAllocated.
* net/loveruby/cflat/type/UserType.java: ditto.
* net/loveruby/cflat/type/ArrayType.java: change #isAllocatedArray
semantics. isAllocatedArray requires the all consecutive array
types have its length, recursively.
* net/loveruby/cflat/type/ArrayType.java: new method
#isIncompleteArray.
* net/loveruby/cflat/compiler/Compiler.java: new option
--dump-asm.
* net/loveruby/cflat/compiler/Compiler.java: handle "--" on
command line.
* test/run.sh: use bash.
* test/shunit.sh: show program name on core dump.
* test/syntax1.cb: int[][] is now invalid.
* cbci: print coredump and signal.
Sun Sep 14 00:13:37 2008 Minero Aoki <aamine@loveruby.net> Sun Sep 14 00:13:37 2008 Minero Aoki <aamine@loveruby.net>
* cbci: new command. Simple Cflat interpriter. * cbci: new command. Simple Cflat interpriter.

31
cbci
View File

@ -117,9 +117,7 @@ def interprit(path, verbose)
exit 1 unless $? == 0 exit 1 unless $? == 0
begin begin
exe = File.basename(path, '.cb') exe = File.basename(path, '.cb')
system "./#{exe}" invoke "./#{exe}", verbose
st = $?
$stderr.puts "status: #{st}"
exit 0 exit 0
rescue SystemCallError => err rescue SystemCallError => err
error_exit err.message error_exit err.message
@ -130,4 +128,31 @@ def interprit(path, verbose)
end end
end end
def invoke(cmd, verbose)
$stderr.puts cmd if verbose
system cmd
st = $?
show_status st if st.exitstatus != 0 or verbose
st
end
module Signal # reopen
NAMES = Signal.list.invert
def Signal.name(num)
NAMES[num] or raise ArgumentError, "undefined signal number"
end
end
def show_status(st)
case
when st.coredump?
$stderr.puts "core dumped (SIG#{Signal.name(st.termsig)})"
when st.signaled?
$stderr.puts "terminated by signal (SIG#{Signal.name(st.termsig)})"
else
$stderr.puts "status: #{st.exitstatus}"
end
end
main main

View File

@ -71,7 +71,16 @@ public class Compiler {
opts.loader = new LibraryLoader(); opts.loader = new LibraryLoader();
while (it.hasNext()) { while (it.hasNext()) {
String arg = (String)it.next(); String arg = (String)it.next();
if (arg.startsWith("-")) { if (arg.equals("-")) {
System.err.println("FIXME: stdin is not supported yet");
System.exit(1);
}
else if (arg.equals("--")) {
// "--" Stops command line processing
it.remove();
break;
}
else if (arg.startsWith("-")) {
if (arg.equals("--check-syntax") if (arg.equals("--check-syntax")
|| arg.equals("--dump-tokens") || arg.equals("--dump-tokens")
|| arg.equals("--dump-ast") || arg.equals("--dump-ast")
@ -79,6 +88,7 @@ public class Compiler {
|| arg.equals("--dump-reference") || arg.equals("--dump-reference")
|| arg.equals("--dump-semantic") || arg.equals("--dump-semantic")
|| arg.equals("-S") || arg.equals("-S")
|| arg.equals("--dump-asm")
|| arg.equals("-c")) { || arg.equals("-c")) {
if (opts.mode != null) { if (opts.mode != null) {
errorExit(opts.mode + " option and " errorExit(opts.mode + " option and "
@ -141,6 +151,7 @@ public class Compiler {
out.println(" --dump-ast Parses source file and dumps AST."); out.println(" --dump-ast Parses source file and dumps AST.");
out.println(" --dump-semantic Checks semantics and dumps AST."); out.println(" --dump-semantic Checks semantics and dumps AST.");
out.println(" -S Generates an assembly source."); out.println(" -S Generates an assembly source.");
out.println(" --dump-asm Dumps an assembly source.");
out.println(" -c Generates an object file."); out.println(" -c Generates an object file.");
out.println(" -I PATH Adds import file loading path."); out.println(" -I PATH Adds import file loading path.");
out.println(" -o PATH Places output in file PATH."); out.println(" -o PATH Places output in file PATH.");
@ -208,6 +219,10 @@ public class Compiler {
return; return;
} }
String asm = CodeGenerator.generate(ast, opts.typeTable, errorHandler); String asm = CodeGenerator.generate(ast, opts.typeTable, errorHandler);
if (opts.isMode("--dump-asm")) {
System.out.println(asm);
return;
}
writeFile(asmFileName(opts), asm); writeFile(asmFileName(opts), asm);
if (opts.isMode("-S")) { if (opts.isMode("-S")) {
return; return;

View File

@ -568,11 +568,12 @@ class TypeChecker extends Visitor {
} }
protected boolean isInvalidParameterType(Type t) { protected boolean isInvalidParameterType(Type t) {
return t.isStruct() || t.isUnion() || t.isVoid(); return t.isStruct() || t.isUnion() || t.isVoid()
|| t.isIncompleteArray();
} }
protected boolean isInvalidVariableType(Type t) { protected boolean isInvalidVariableType(Type t) {
return t.isVoid(); return t.isVoid() || (t.isArray() && ! t.isAllocatedArray());
} }
protected boolean isInvalidLHSType(Type t) { protected boolean isInvalidLHSType(Type t) {

View File

@ -17,14 +17,21 @@ public class ArrayType extends Type {
} }
public boolean isArray() { return true; } public boolean isArray() { return true; }
public boolean isAllocated() { return length != undefined; }
public boolean isAllocatedArray() { return isAllocated(); }
public boolean isUnallocatedArray() { return !isAllocated(); }
public boolean isDereferable() { return true; } public boolean isDereferable() { return true; }
public boolean isPointerAlike() { return isUnallocatedArray(); } public boolean isPointerAlike() { return length == undefined; }
public boolean isScalar() { return true; } public boolean isScalar() { return true; }
public boolean isSigned() { return false; } public boolean isSigned() { return false; }
public boolean isAllocatedArray() {
return length != undefined &&
(!baseType.isArray() || baseType.isAllocatedArray());
}
public boolean isIncompleteArray() {
if (! baseType.isArray()) return false;
return !baseType.isAllocatedArray();
}
public Type baseType() { public Type baseType() {
return baseType; return baseType;
} }
@ -40,11 +47,11 @@ public class ArrayType extends Type {
// Value size as allocated array // Value size as allocated array
public long allocSize() { public long allocSize() {
if (isAllocated()) { if (length == undefined) {
return baseType.allocSize() * length; return size();
} }
else { else {
return size(); return baseType.allocSize() * length;
} }
} }

View File

@ -17,8 +17,6 @@ public abstract class Type {
{ throw new Error("#isSigned for non-integer type"); } { throw new Error("#isSigned for non-integer type"); }
public boolean isPointer() { return false; } public boolean isPointer() { return false; }
public boolean isArray() { return false; } public boolean isArray() { return false; }
public boolean isAllocatedArray() { return false; }
public boolean isUnallocatedArray() { return false; }
public boolean isComplexType() { return false; } public boolean isComplexType() { return false; }
public boolean isStruct() { return false; } public boolean isStruct() { return false; }
public boolean isUnion() { return false; } public boolean isUnion() { return false; }
@ -28,6 +26,8 @@ public abstract class Type {
// Ability methods (unary) // Ability methods (unary)
public boolean isDereferable() { return false; } public boolean isDereferable() { return false; }
public boolean isPointerAlike() { return false; } public boolean isPointerAlike() { return false; }
public boolean isAllocatedArray() { return false; }
public boolean isIncompleteArray() { return false; }
public boolean isScalar() { return false; } public boolean isScalar() { return false; }
public boolean isCallable() { return false; } public boolean isCallable() { return false; }

View File

@ -33,7 +33,6 @@ public class UserType extends NamedType {
public boolean isPointer() { return realType().isPointer(); } public boolean isPointer() { return realType().isPointer(); }
public boolean isArray() { return realType().isArray(); } public boolean isArray() { return realType().isArray(); }
public boolean isAllocatedArray() { return realType().isAllocatedArray(); } public boolean isAllocatedArray() { return realType().isAllocatedArray(); }
public boolean isUnallocatedArray() { return realType().isUnallocatedArray(); }
public boolean isComplexType() { return realType().isComplexType(); } public boolean isComplexType() { return realType().isComplexType(); }
public boolean isStruct() { return realType().isStruct(); } public boolean isStruct() { return realType().isStruct(); }
public boolean isUnion() { return realType().isUnion(); } public boolean isUnion() { return realType().isUnion(); }

View File

@ -1,4 +1,4 @@
#!/usr/bin/ksh #!/bin/bash
main() { main() {
local pattern="." local pattern="."

View File

@ -59,7 +59,7 @@ assert_status() {
expected=$1; shift expected=$1; shift
shunit_invoke "$@" shunit_invoke "$@"
really=$? really=$?
assert_not_coredump || return assert_not_coredump "$1" || return
if [ "$really" != "$expected" ] if [ "$really" != "$expected" ]
then then
echo "shunit[$@]: status $expected expected but was: $really" echo "shunit[$@]: status $expected expected but was: $really"
@ -73,7 +73,7 @@ assert_error() {
shunit_begin_test shunit_begin_test
shunit_invoke "$@" shunit_invoke "$@"
really=$? really=$?
assert_not_coredump || return assert_not_coredump "$1" || return
if [ "$really" = "0" ] if [ "$really" = "0" ]
then then
echo "shunit[$@]: non-zero status expected but was: $really" echo "shunit[$@]: non-zero status expected but was: $really"
@ -103,7 +103,7 @@ assert_equal() {
mycmd=$2 mycmd=$2
eval "$excmd" >tc.out.expected 2>tc.err.expected eval "$excmd" >tc.out.expected 2>tc.err.expected
eval "$mycmd" >tc.out.real 2>tc.err.real eval "$mycmd" >tc.out.real 2>tc.err.real
assert_not_coredump || return assert_not_coredump "$mycmd" || return
cmp tc.out.real tc.out.expected >/dev/null 2>&1 cmp tc.out.real tc.out.expected >/dev/null 2>&1
if [ "$?" != "0" ] if [ "$?" != "0" ]
then then
@ -135,7 +135,7 @@ assert_equal_stdout() {
mycmd=$1; shift mycmd=$1; shift
eval "$excmd" >tc.out.expected 2>/dev/null eval "$excmd" >tc.out.expected 2>/dev/null
eval "$mycmd" >tc.out.real 2>/dev/null eval "$mycmd" >tc.out.real 2>/dev/null
assert_not_coredump || return assert_not_coredump "$mycmd" || return
cmp tc.out.real tc.out.expected >/dev/null 2>&1 cmp tc.out.real tc.out.expected >/dev/null 2>&1
if [ "$?" != "0" ] if [ "$?" != "0" ]
then then
@ -152,7 +152,7 @@ assert_stdout() {
expected=$1; shift expected=$1; shift
echo "$expected" > tc.out.expected echo "$expected" > tc.out.expected
"$@" >tc.out.real 2>/dev/null "$@" >tc.out.real 2>/dev/null
assert_not_coredump || return assert_not_coredump "$1" || return
cmp tc.out.expected tc.out.real >/dev/null 2>&1 cmp tc.out.expected tc.out.real >/dev/null 2>&1
if [ "$?" != "0" ] if [ "$?" != "0" ]
then then
@ -166,22 +166,25 @@ assert_stdout() {
rm -f core rm -f core
assert_not_coredump() { assert_not_coredump() {
local cmd="$1"
shunit_begin_test shunit_begin_test
if [ -f core ] if [ -f core ]
then then
echo "core dumped: $mycmd" echo "core dumped: $cmd"
echo "----" echo "----"
shunit_test_failed shunit_test_failed
rm -f core
return 1 return 1
fi fi
rm -f core
return 0 return 0
} }
assert_not_exist() { assert_not_exist() {
local file="$1"; shift
shunit_begin_test shunit_begin_test
file=$1; shift if [ -f "$file" ]
if [ -f $file ]
then then
echo "exists: $file" echo "exists: $file"
echo "----" echo "----"
@ -192,9 +195,10 @@ assert_not_exist() {
} }
assert_directory() { assert_directory() {
local dir="$1"; shift
shunit_begin_test shunit_begin_test
dir=$1; shift if [ ! -d "$dir" ]
if [ ! -d $dir ]
then then
echo "not directory: $dir" echo "not directory: $dir"
echo "----" echo "----"

View File

@ -28,20 +28,18 @@ int*** ppp;
int**** pppp; int**** pppp;
int***** ppppp; int***** ppppp;
int[] a; int[1] a;
int[][] aa; int[1][1] aa;
int[][][] aaa; int[1][1][1] aaa;
int[][][][] aaaa;
int[][][][][] aaaaa;
int*[] pa; int*[1] pa;
int[]* ap; int[]* ap;
int**[] ppa; int**[1] ppa;
int*[]* pap; int*[]* pap;
int[]** app; int[]** app;
int[][]* aap; int[1][1]* aap;
int[]*[] apa; int[]*[1] apa;
int*[][] paa; int*[1][1] paa;
struct file { struct file {
int fd; int fd;
@ -66,7 +64,7 @@ union node {
typedef int myint; typedef int myint;
int int
main(int argc, char[][] argv) main(int argc, char** argv)
{ {
ff(); ff();
return f(1, 2, 3); return f(1, 2, 3);