* 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>
* cbci: new command. Simple Cflat interpriter.

31
cbci
View File

@ -117,9 +117,7 @@ def interprit(path, verbose)
exit 1 unless $? == 0
begin
exe = File.basename(path, '.cb')
system "./#{exe}"
st = $?
$stderr.puts "status: #{st}"
invoke "./#{exe}", verbose
exit 0
rescue SystemCallError => err
error_exit err.message
@ -130,4 +128,31 @@ def interprit(path, verbose)
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

View File

@ -71,7 +71,16 @@ public class Compiler {
opts.loader = new LibraryLoader();
while (it.hasNext()) {
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")
|| arg.equals("--dump-tokens")
|| arg.equals("--dump-ast")
@ -79,6 +88,7 @@ public class Compiler {
|| arg.equals("--dump-reference")
|| arg.equals("--dump-semantic")
|| arg.equals("-S")
|| arg.equals("--dump-asm")
|| arg.equals("-c")) {
if (opts.mode != null) {
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-semantic Checks semantics and dumps AST.");
out.println(" -S Generates an assembly source.");
out.println(" --dump-asm Dumps an assembly source.");
out.println(" -c Generates an object file.");
out.println(" -I PATH Adds import file loading path.");
out.println(" -o PATH Places output in file PATH.");
@ -208,6 +219,10 @@ public class Compiler {
return;
}
String asm = CodeGenerator.generate(ast, opts.typeTable, errorHandler);
if (opts.isMode("--dump-asm")) {
System.out.println(asm);
return;
}
writeFile(asmFileName(opts), asm);
if (opts.isMode("-S")) {
return;

View File

@ -568,11 +568,12 @@ class TypeChecker extends Visitor {
}
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) {
return t.isVoid();
return t.isVoid() || (t.isArray() && ! t.isAllocatedArray());
}
protected boolean isInvalidLHSType(Type t) {

View File

@ -17,14 +17,21 @@ public class ArrayType extends Type {
}
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 isPointerAlike() { return isUnallocatedArray(); }
public boolean isPointerAlike() { return length == undefined; }
public boolean isScalar() { return true; }
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() {
return baseType;
}
@ -40,11 +47,11 @@ public class ArrayType extends Type {
// Value size as allocated array
public long allocSize() {
if (isAllocated()) {
return baseType.allocSize() * length;
if (length == undefined) {
return size();
}
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"); }
public boolean isPointer() { return false; }
public boolean isArray() { return false; }
public boolean isAllocatedArray() { return false; }
public boolean isUnallocatedArray() { return false; }
public boolean isComplexType() { return false; }
public boolean isStruct() { return false; }
public boolean isUnion() { return false; }
@ -28,6 +26,8 @@ public abstract class Type {
// Ability methods (unary)
public boolean isDereferable() { return false; }
public boolean isPointerAlike() { return false; }
public boolean isAllocatedArray() { return false; }
public boolean isIncompleteArray() { return false; }
public boolean isScalar() { 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 isArray() { return realType().isArray(); }
public boolean isAllocatedArray() { return realType().isAllocatedArray(); }
public boolean isUnallocatedArray() { return realType().isUnallocatedArray(); }
public boolean isComplexType() { return realType().isComplexType(); }
public boolean isStruct() { return realType().isStruct(); }
public boolean isUnion() { return realType().isUnion(); }

View File

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

View File

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

View File

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