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>
|
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
31
cbci
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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; }
|
||||||
|
|
||||||
|
|
|
@ -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(); }
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#!/usr/bin/ksh
|
#!/bin/bash
|
||||||
|
|
||||||
main() {
|
main() {
|
||||||
local pattern="."
|
local pattern="."
|
||||||
|
|
|
@ -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 "----"
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue