mirror of https://github.com/aamine/cbc
* 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:
parent
ffba97e811
commit
09f1c83a3b
33
ChangeLog
33
ChangeLog
|
@ -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
31
cbci
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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; }
|
||||
|
||||
|
|
|
@ -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(); }
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/ksh
|
||||
#!/bin/bash
|
||||
|
||||
main() {
|
||||
local pattern="."
|
||||
|
|
|
@ -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 "----"
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue