├── ChangeLog ├── Makefile ├── README.md ├── ToDo ├── bin ├── cbc ├── cbci.rb └── cbci.sh ├── build.properties ├── build.xml ├── docker └── Dockerfile ├── import ├── alloca.hb ├── dlfcn.hb ├── errno.hb ├── setjmp.hb ├── stdarg.hb ├── stddef.hb ├── stdio.hb ├── stdlib.hb ├── string.hb ├── strings.hb ├── sys │ └── types.hb └── unistd.hb ├── install.sh ├── lib ├── Makefile ├── alloca.o ├── alloca.s ├── cbc.jar ├── libcbc.a ├── sizeof_jmpbuf.c ├── stdarg.cb ├── stdarg.o └── stdarg.s ├── net └── loveruby │ └── cflat │ ├── asm │ ├── AbsoluteAddress.java │ ├── Assembly.java │ ├── BaseSymbol.java │ ├── Comment.java │ ├── DirectMemoryReference.java │ ├── Directive.java │ ├── ImmediateValue.java │ ├── IndirectMemoryReference.java │ ├── Instruction.java │ ├── IntegerLiteral.java │ ├── Label.java │ ├── Literal.java │ ├── MemoryReference.java │ ├── NamedSymbol.java │ ├── Operand.java │ ├── OperandPattern.java │ ├── Register.java │ ├── Statistics.java │ ├── SuffixedSymbol.java │ ├── Symbol.java │ ├── SymbolTable.java │ ├── Type.java │ └── UnnamedSymbol.java │ ├── ast │ ├── AST.java │ ├── ASTVisitor.java │ ├── AbstractAssignNode.java │ ├── AddressNode.java │ ├── ArefNode.java │ ├── AssignNode.java │ ├── BinaryOpNode.java │ ├── BlockNode.java │ ├── BreakNode.java │ ├── CaseNode.java │ ├── CastNode.java │ ├── CflatToken.java │ ├── CompositeTypeDefinition.java │ ├── CondExprNode.java │ ├── ContinueNode.java │ ├── DeclarationVisitor.java │ ├── Declarations.java │ ├── DereferenceNode.java │ ├── DoWhileNode.java │ ├── Dumpable.java │ ├── Dumper.java │ ├── ExprNode.java │ ├── ExprStmtNode.java │ ├── ForNode.java │ ├── FuncallNode.java │ ├── GotoNode.java │ ├── IfNode.java │ ├── IntegerLiteralNode.java │ ├── LHSNode.java │ ├── LabelNode.java │ ├── LiteralNode.java │ ├── Location.java │ ├── LogicalAndNode.java │ ├── LogicalOrNode.java │ ├── MemberNode.java │ ├── Node.java │ ├── OpAssignNode.java │ ├── PrefixOpNode.java │ ├── PtrMemberNode.java │ ├── ReturnNode.java │ ├── SizeofExprNode.java │ ├── SizeofTypeNode.java │ ├── Slot.java │ ├── StmtNode.java │ ├── StringLiteralNode.java │ ├── StructNode.java │ ├── SuffixOpNode.java │ ├── SwitchNode.java │ ├── TypeDefinition.java │ ├── TypeNode.java │ ├── TypedefNode.java │ ├── UnaryArithmeticOpNode.java │ ├── UnaryOpNode.java │ ├── UnionNode.java │ ├── VariableNode.java │ └── WhileNode.java │ ├── compiler │ ├── Compiler.java │ ├── CompilerMode.java │ ├── DereferenceChecker.java │ ├── IRGenerator.java │ ├── LdArg.java │ ├── LdOption.java │ ├── LocalResolver.java │ ├── Options.java │ ├── SourceFile.java │ ├── TypeChecker.java │ ├── TypeResolver.java │ └── Visitor.java │ ├── entity │ ├── CBCParameter.java │ ├── Constant.java │ ├── ConstantEntry.java │ ├── ConstantTable.java │ ├── DefinedFunction.java │ ├── DefinedVariable.java │ ├── Entity.java │ ├── EntityVisitor.java │ ├── Function.java │ ├── LocalScope.java │ ├── ParamSlots.java │ ├── Params.java │ ├── Scope.java │ ├── ToplevelScope.java │ ├── UndefinedFunction.java │ ├── UndefinedVariable.java │ └── Variable.java │ ├── exception │ ├── CompileException.java │ ├── FileException.java │ ├── IPCException.java │ ├── JumpError.java │ ├── OptionParseError.java │ ├── SemanticError.java │ ├── SemanticException.java │ └── SyntaxException.java │ ├── ir │ ├── Addr.java │ ├── Assign.java │ ├── Bin.java │ ├── CJump.java │ ├── Call.java │ ├── Case.java │ ├── Dumpable.java │ ├── Dumper.java │ ├── Expr.java │ ├── ExprStmt.java │ ├── IR.java │ ├── IRVisitor.java │ ├── Int.java │ ├── Jump.java │ ├── LabelStmt.java │ ├── Mem.java │ ├── Op.java │ ├── Return.java │ ├── Stmt.java │ ├── Str.java │ ├── Switch.java │ ├── Uni.java │ └── Var.java │ ├── parser │ ├── LibraryLoader.java │ └── Parser.jj │ ├── sysdep │ ├── Assembler.java │ ├── AssemblerOptions.java │ ├── AssemblyCode.java │ ├── CodeGenerator.java │ ├── CodeGeneratorOptions.java │ ├── GNUAssembler.java │ ├── GNULinker.java │ ├── Linker.java │ ├── LinkerOptions.java │ ├── Platform.java │ ├── X86Linux.java │ └── x86 │ │ ├── AssemblyCode.java │ │ ├── CodeGenerator.java │ │ ├── ELFConstants.java │ │ ├── PeepholeOptimizer.java │ │ ├── Register.java │ │ └── RegisterClass.java │ ├── type │ ├── ArrayType.java │ ├── ArrayTypeRef.java │ ├── CompositeType.java │ ├── FunctionType.java │ ├── FunctionTypeRef.java │ ├── IntegerType.java │ ├── IntegerTypeRef.java │ ├── NamedType.java │ ├── ParamTypeRefs.java │ ├── ParamTypes.java │ ├── PointerType.java │ ├── PointerTypeRef.java │ ├── StructType.java │ ├── StructTypeRef.java │ ├── Type.java │ ├── TypeRef.java │ ├── TypeTable.java │ ├── UnionType.java │ ├── UnionTypeRef.java │ ├── UserType.java │ ├── UserTypeRef.java │ ├── VoidType.java │ └── VoidTypeRef.java │ └── utils │ ├── AsmUtils.java │ ├── CommandUtils.java │ ├── Cursor.java │ ├── ErrorHandler.java │ ├── ListUtils.java │ └── TextUtils.java ├── test ├── Makefile ├── TARGETS ├── add.cb ├── addressof.cb ├── alloca.cb ├── alloca2.cb ├── aref-semcheck.cb ├── aref-semcheck2.cb ├── array-semcheck1.cb ├── array.cb ├── array2.cb ├── assign.cb ├── assoc.cb ├── bitand.cb ├── bitnot.cb ├── bitor.cb ├── bitxor.cb ├── block.cb ├── break-semcheck.cb ├── cast.cb ├── cast2.cb ├── charops.cb ├── charops2.cb ├── comm.cb ├── condexpr.cb ├── const.cb ├── continue-semcheck.cb ├── dec.cb ├── decloverride.cb ├── decloverride.hb ├── decloverride2.cb ├── decloverride2.hb ├── defun-semcheck.cb ├── defun-semcheck2.cb ├── defun-semcheck3.cb ├── defun-semcheck4.cb ├── defun-semcheck5.cb ├── defun-semcheck6.cb ├── defun-semcheck7.cb ├── defun-semcheck8.cb ├── defvar.cb ├── deref-semcheck1.cb ├── deref-semcheck2.cb ├── deref-semcheck3.cb ├── deref-semcheck4.cb ├── deref-semcheck5.cb ├── div.cb ├── dowhile-break.cb ├── dowhile-continue.cb ├── dowhile1.cb ├── dowhile2.cb ├── dowhile3.cb ├── duplicated-import.cb ├── empstruct.cb ├── eq.cb ├── for-break.cb ├── for-continue.cb ├── for1.cb ├── fork.cb ├── funcall-semcheck.cb ├── funcall-semcheck2.cb ├── funcall0.cb ├── funcall1.cb ├── funcall2.cb ├── funcall3.cb ├── funcall4.cb ├── funcall5.cb ├── funcptr.cb ├── gt.cb ├── gteq.cb ├── gvar.cb ├── hello.cb ├── hello2.cb ├── hello3.cb ├── hello4.cb ├── if1.cb ├── if2.cb ├── implicitaddr.cb ├── inc.cb ├── initializer.cb ├── integer.cb ├── intops.cb ├── invalidstmt1.cb ├── invalidstmt2.cb ├── logicaland.cb ├── logicalnot.cb ├── logicalor.cb ├── longops.cb ├── lshift.cb ├── lt.cb ├── lteq.cb ├── lvar1.cb ├── lvar2.cb ├── mdarray.cb ├── mdarray2.cb ├── mod.cb ├── mul.cb ├── neq.cb ├── noreturn.cb ├── one.cb ├── opassign.cb ├── param.cb ├── pointer.cb ├── pointer2.cb ├── pointer3.cb ├── pointer4.cb ├── ptrarray.cb ├── ptrdiff.cb ├── ptrmemb.cb ├── ptrmemb2.cb ├── recursivetypedef.cb ├── rshift.cb ├── run.sh ├── scomm.cb ├── setjmptest.cb ├── sgvar.cb ├── shortops.cb ├── shortops2.cb ├── shunit.sh ├── sizeof-expr.cb ├── sizeof-struct.cb ├── sizeof-type.cb ├── sizeof-union.cb ├── slcomm.cb ├── slvar.cb ├── src1.cb ├── src1.hb ├── src2.cb ├── staticfunc.cb ├── string.cb ├── struct-semcheck.cb ├── struct-semcheck10.cb ├── struct-semcheck2.cb ├── struct-semcheck3.cb ├── struct-semcheck4.cb ├── struct-semcheck5.cb ├── struct-semcheck6.cb ├── struct-semcheck7.cb ├── struct-semcheck8.cb ├── struct-semcheck9.cb ├── struct.cb ├── struct2.cb ├── struct3.cb ├── sub.cb ├── switch.cb ├── syntax1.cb ├── syntax2.cb ├── syntax3.cb ├── test_cbc.sh ├── textwrite.cb ├── ucharops.cb ├── ucharops2.cb ├── uintops.cb ├── ulongops.cb ├── unaryminus.cb ├── unaryplus.cb ├── union-semcheck.cb ├── union-semcheck10.cb ├── union-semcheck2.cb ├── union-semcheck3.cb ├── union-semcheck4.cb ├── union-semcheck5.cb ├── union-semcheck6.cb ├── union-semcheck7.cb ├── union-semcheck8.cb ├── union-semcheck9.cb ├── union.cb ├── usertype.cb ├── ushortops.cb ├── ushortops2.cb ├── utf.cb ├── utf.out ├── validstmt1.cb ├── var-semcheck.cb ├── varargs.cb ├── vardecl.cb ├── while-break.cb ├── while-continue.cb ├── while1.cb ├── while2.cb ├── while3.cb └── zero.cb ├── tools ├── diffoptimized.sh └── list-untested.rb └── unit ├── Makefile ├── TestAll.java ├── TestAsmUtils.java ├── TestCursor.java ├── TestListUtils.java ├── TestTextUtils.java ├── junit-4.5.jar └── run.sh /Makefile: -------------------------------------------------------------------------------- 1 | ANT = ant 2 | VERSION = 1.0.1 3 | BINVERSION = 1.0 4 | 5 | default: all 6 | 7 | all: lib/cbc.jar lib/libcbc.a 8 | 9 | lib/cbc.jar: 10 | $(ANT) compile 11 | 12 | lib/libcbc.a: 13 | cd lib; $(MAKE) libcbc.a 14 | 15 | clean: 16 | $(ANT) clean 17 | cd lib; $(MAKE) clean 18 | cd test; $(MAKE) clean 19 | 20 | test: check 21 | check: 22 | cd test; $(MAKE) test 23 | 24 | unittest: 25 | cd unit; $(MAKE) test 26 | 27 | dist: 28 | rm -rf cbc-$(VERSION) cbc-$(BINVERSION) 29 | svn export http://i.loveruby.net/svn/public/cbc/tags/$(VERSION) cbc-$(VERSION) 30 | cd cbc-$(VERSION); $(MAKE) 31 | cd cbc-$(VERSION); $(ANT) clean-build 32 | tar c cbc-$(VERSION) | gzip -n > cbc-$(VERSION).tar.gz 33 | mv cbc-$(VERSION) cbc-$(BINVERSION) 34 | tar c cbc-$(BINVERSION) | gzip -n > cbc-$(BINVERSION).tar.gz 35 | rm -rf cbc-$(BINVERSION) 36 | -------------------------------------------------------------------------------- /bin/cbc: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # cbc -- cflat compiler 3 | 4 | JAVA=${JAVA:-java} 5 | 6 | cmd_path="$(readlink -f $0)" 7 | srcdir_root="$(dirname "$(dirname "$cmd_path")")" 8 | "$JAVA" -classpath "$srcdir_root/lib/cbc.jar" \ 9 | net.loveruby.cflat.compiler.Compiler \ 10 | -I"$srcdir_root/import" \ 11 | -L"$srcdir_root/lib" \ 12 | "$@" 13 | -------------------------------------------------------------------------------- /bin/cbci.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | TMPDIR=/tmp 4 | TMPNAME="cflatexpr$$" 5 | 6 | main() { 7 | local basedir="$(expand_path "$(dirname "$0")")" 8 | 9 | cd "$TMPDIR" 10 | trap "rm -f $TMPNAME*" EXIT 11 | cat < "$TMPNAME.cb" 12 | import stdio; 13 | 14 | int 15 | main(int argc, char** argv) 16 | { 17 | printf("%d\n", $1); 18 | return 0; 19 | } 20 | EndSource 21 | "$basedir/cbc" "$TMPNAME.cb" || exit 1 22 | "./$TMPNAME" 23 | st=$? 24 | echo "status: $st" 1>&2 25 | exit 0 26 | } 27 | 28 | expand_path() { 29 | local path="$1" 30 | 31 | if [ $(expr "$path" : "/") -eq 1 ] 32 | then 33 | echo "$path" 34 | else 35 | echo "$(pwd)/$path" 36 | fi 37 | } 38 | 39 | main "$@" 40 | -------------------------------------------------------------------------------- /build.properties: -------------------------------------------------------------------------------- 1 | javacc.dir=/usr/share/java 2 | 3 | src.dir=. 4 | build.dir=build 5 | build.classes.dir=build/classes 6 | build.jar=lib/cbc.jar 7 | 8 | src.jj.file=./net/loveruby/cflat/parser/Parser.jj 9 | build.parser.dir=./net/loveruby/cflat/parser 10 | -------------------------------------------------------------------------------- /docker/Dockerfile: -------------------------------------------------------------------------------- 1 | # This dockerfile use the ubuntu image 2 | FROM ubuntu:16.04 3 | 4 | # maintainer is leungwensen 5 | MAINTAINER leungwensen 6 | 7 | # commands to update the image 8 | RUN apt-get update && apt-get install -y \ 9 | gcc-multilib g++-multilib libc6-i386 lib32ncurses5 lib32stdc++6 \ 10 | openjdk-8-jre \ 11 | git 12 | 13 | RUN git clone https://github.com/leungwensen/cbc-ubuntu-64bit.git 14 | 15 | RUN cd cbc-ubuntu-64bit && bash install.sh 16 | 17 | RUN echo 'PATH=/usr/local/cbc/bin:$PATH' >> $HOME/.bashrc 18 | 19 | RUN echo 'alias cbc="cbc -Wa,--32 -Wl,-melf_i386"' >> $HOME/.bashrc 20 | 21 | # commands when creating a new container 22 | 23 | -------------------------------------------------------------------------------- /import/alloca.hb: -------------------------------------------------------------------------------- 1 | import stddef; 2 | 3 | extern void* alloca(size_t len); 4 | -------------------------------------------------------------------------------- /import/dlfcn.hb: -------------------------------------------------------------------------------- 1 | // dlfcn.hb 2 | 3 | // from bits/dlfcn.h 4 | const int RTLD_LAZY = 0x0001; 5 | const int RTLD_NOW = 0x0002; 6 | const int RTLD_NOLOAD = 0x0004; 7 | const int RTLD_DEEPBIND = 0x0008; 8 | const int RTLD_LOCAL = 0x0000; 9 | const int RTLD_GLOBAL = 0x0100; 10 | const int RTLD_NODELETE = 0x1000; 11 | 12 | // from dlfcn.h 13 | extern void* dlopen(char* filename, int flag); 14 | extern char* dlerror(void); 15 | extern void* dlsym(void* handle, char* symbol); 16 | extern int dlclose(void* handle); 17 | -------------------------------------------------------------------------------- /import/errno.hb: -------------------------------------------------------------------------------- 1 | // errno.hb 2 | 3 | extern char*[] sys_errlist; 4 | extern int sys_nerr; 5 | extern int errno; 6 | -------------------------------------------------------------------------------- /import/setjmp.hb: -------------------------------------------------------------------------------- 1 | // setjmp.hb 2 | 3 | // sizeof(jmp_buf)==156 on Linux/i386/glibc2.3. 4 | typedef char[156] jmp_buf; 5 | typedef char[156] sigjmp_buf; 6 | 7 | extern int setjmp(jmp_buf buf); 8 | extern int sigsetjmp(sigjmp_buf buf, int savesigs); 9 | extern void longjmp(jmp_buf buf, int value); 10 | extern void siglongjmp(sigjmp_buf buf, int value); 11 | -------------------------------------------------------------------------------- /import/stdarg.hb: -------------------------------------------------------------------------------- 1 | // stdarg.hb 2 | 3 | typedef unsigned long va_arg_t; 4 | typedef va_arg_t* va_list; 5 | 6 | extern va_list va_init(void* arg); 7 | extern void* va_next(va_list* ap); 8 | -------------------------------------------------------------------------------- /import/stddef.hb: -------------------------------------------------------------------------------- 1 | // stddef.h 2 | 3 | const void* NULL = 0; 4 | typedef unsigned long size_t; 5 | typedef long ptrdiff_t; 6 | -------------------------------------------------------------------------------- /import/stdio.hb: -------------------------------------------------------------------------------- 1 | // #@@range/head{ 2 | // stdio.hb 3 | 4 | import stddef; // for NULL and size_t 5 | import stdarg; 6 | 7 | typedef unsigned long FILE; // dummy 8 | 9 | extern FILE* stdin; 10 | extern FILE* stdout; 11 | extern FILE* stderr; 12 | 13 | extern FILE* fopen(char* path, char* mode); 14 | extern FILE* fdopen(int fd, char* mode); 15 | extern FILE* freopen(char* path, char* mode, FILE* stream); 16 | extern int fclose(FILE* stream); 17 | // #@@} 18 | extern int getchar(void); 19 | extern int getc(FILE* stream); 20 | extern int fgetc(FILE* stream); 21 | extern int ungetc(int c, FILE* stream); 22 | extern char* gets(char* buf); 23 | extern char* fgets(char* buf, int size, FILE* stream); 24 | extern int putc(int c); 25 | extern int putchar(int c); 26 | extern int fputc(int c, FILE* stream); 27 | extern int puts(char *str); 28 | extern int fputs(char* str, FILE* stream); 29 | extern int printf(char *fmt, ...); 30 | extern int fprintf(FILE* stream, char* fmt, ...); 31 | extern int sprintf(char* buf, char* fmt, ...); 32 | extern int snprintf(char* buf, size_t size, char* fmt, ...); 33 | extern size_t fread(void* buf, size_t size, size_t nmemb, FILE* stream); 34 | extern size_t fwrite(void* buf, size_t size, size_t nmemb, FILE* stream); 35 | extern int feof(FILE* stream); 36 | extern int ferror(FILE* stream); 37 | extern int fileno(FILE* stream); 38 | extern void clearerr(FILE* stream); 39 | extern void perror(char* param); 40 | extern int vprintf(char* fmt, va_list ap); 41 | extern int vfprintf(FILE* s, char* fmt, va_list ap); 42 | extern int vsprintf(char *buf, char* fmt, va_list ap); 43 | extern int vsnprintf(char *buf, size_t size, char* fmt, va_list ap); 44 | -------------------------------------------------------------------------------- /import/stdlib.hb: -------------------------------------------------------------------------------- 1 | // stdlib.hb 2 | 3 | import stddef; // for size_t 4 | 5 | extern void exit(int status); 6 | extern void* calloc(size_t nmemb, size_t size); 7 | extern void* malloc(size_t size); 8 | extern void free(void* ptr); 9 | extern void* realloc(void* ptr, size_t size); 10 | extern int system(char* command); 11 | -------------------------------------------------------------------------------- /import/string.hb: -------------------------------------------------------------------------------- 1 | // string.hb 2 | 3 | import stddef; // for size_t 4 | 5 | extern char* strcat(char* dest, char* src); 6 | extern char* strncat(char* dest, char* src, size_t len); 7 | extern char* strchr(char* str, int c); 8 | extern char* strrchr(char* str, int c); 9 | extern int strcmp(char* str1, char* str2); 10 | extern int strncmp(char* str1, char* str2, size_t len); 11 | extern char* strcpy(char* dest, char* src); 12 | extern char* strncpy(char* dest, char* src, size_t len); 13 | extern char* strdup(char* str); 14 | extern size_t strlen(char* str); 15 | extern char* strstr(char* str, char* pattern); 16 | extern size_t strspn(char* str, char* accept); 17 | extern size_t strcspn(char* str, char* reject); 18 | extern char* strerror(int errnum); 19 | extern char* strerror_r(int errnum, char* buf, size_t len); 20 | extern void* memcpy(void* dest, void* src, size_t len); 21 | extern void* memccpy(void* dest, void* src, int c, size_t len); 22 | extern void* memmove(void* dest, void* src, size_t len); 23 | -------------------------------------------------------------------------------- /import/strings.hb: -------------------------------------------------------------------------------- 1 | // strings.hb 2 | 3 | import stddef; 4 | 5 | extern int strcasecmp(char* str1, char* str2); 6 | extern int strncasecmp(char* str1, char* str2, size_t len); 7 | extern char* index(char* src, int ch); 8 | extern char* rindex(char* src, int ch); 9 | -------------------------------------------------------------------------------- /import/sys/types.hb: -------------------------------------------------------------------------------- 1 | // sys/types.hb 2 | 3 | typedef int pid_t; 4 | -------------------------------------------------------------------------------- /import/unistd.hb: -------------------------------------------------------------------------------- 1 | // unistd.hb 2 | 3 | import sys.types; 4 | 5 | extern void _exit(int status); 6 | extern pid_t fork(void); 7 | extern pid_t getpid(void); 8 | extern pid_t getppid(void); 9 | extern unsigned int sleep(unsigned int secs); 10 | -------------------------------------------------------------------------------- /install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | prefix="${1:-/usr/local/cbc}" 4 | BINS="bin/cbc" 5 | LIBS="lib/cbc.jar lib/libcbc.a" 6 | 7 | main() 8 | { 9 | if ! [[ -f lib/cbc.jar && -f lib/libcbc.a ]] 10 | then 11 | echo "lib/cbc.jar and lib/libcbc.a do not exist. Build it first" 1>&2 12 | exit 1 13 | fi 14 | echo "prefix=$prefix" 15 | invoke mkdir -p "$prefix/bin" 16 | invoke install -m755 $BINS "$prefix/bin" 17 | invoke mkdir -p "$prefix/lib" 18 | invoke cp $LIBS "$prefix/lib" 19 | invoke rm -rf "$prefix/import" 20 | invoke cp -r import "$prefix/import" 21 | echo "cbc successfully installed as $prefix/bin/cbc" 22 | } 23 | 24 | invoke() 25 | { 26 | echo "$@" 27 | if ! "$@" 28 | then 29 | echo "install failed." 1>&2 30 | exit 1 31 | fi 32 | } 33 | 34 | main "$@" 35 | -------------------------------------------------------------------------------- /lib/Makefile: -------------------------------------------------------------------------------- 1 | CBC = ../bin/cbc 2 | CBFLAGS = -O -fPIC 3 | TARGET = libcbc.a 4 | OBJS = stdarg.o alloca.o 5 | 6 | CC = gcc 7 | CFLAGS = -Wall 8 | AR_CREATE = ar crs 9 | 10 | .SUFFIXES: 11 | .SUFFIXES: .cb .s .o 12 | 13 | .cb.o: 14 | $(CBC) $(CBFLAGS) -Wa,"--32" -c $< -o $@ 15 | .s.o: 16 | $(CBC) -Wa,"--32" -c $< 17 | 18 | $(TARGET): $(OBJS) 19 | $(AR_CREATE) $(TARGET) $(OBJS) 20 | 21 | stdarg.o: stdarg.cb 22 | 23 | sizeof_jmpbuf: sizeof_jmpbuf.c 24 | $(CC) $(CFLAGS) -o $@ $< 25 | 26 | clean: 27 | rm -f $(TARGET) *.o stdarg.s 28 | -------------------------------------------------------------------------------- /lib/alloca.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leungwensen/cbc-ubuntu-64bit/8e1121c4afff63fdc4bddd0e5e199adf9e23528f/lib/alloca.o -------------------------------------------------------------------------------- /lib/alloca.s: -------------------------------------------------------------------------------- 1 | .text 2 | .globl alloca 3 | .type alloca,@function 4 | alloca: 5 | popl %ecx 6 | movl (%esp), %eax 7 | addl $3, %eax 8 | andl $-4, %eax 9 | subl %eax, %esp 10 | leal 4(%esp), %eax 11 | jmp *%ecx 12 | .size alloca, .-alloca 13 | -------------------------------------------------------------------------------- /lib/cbc.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leungwensen/cbc-ubuntu-64bit/8e1121c4afff63fdc4bddd0e5e199adf9e23528f/lib/cbc.jar -------------------------------------------------------------------------------- /lib/libcbc.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leungwensen/cbc-ubuntu-64bit/8e1121c4afff63fdc4bddd0e5e199adf9e23528f/lib/libcbc.a -------------------------------------------------------------------------------- /lib/sizeof_jmpbuf.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int 5 | main(int argc, char **argv) 6 | { 7 | printf("sizeof(jmp_buf)=%lu\n", (unsigned long)sizeof(jmp_buf)); 8 | printf("sizeof(sigjmp_buf)=%lu\n", (unsigned long)sizeof(sigjmp_buf)); 9 | return 0; 10 | } 11 | -------------------------------------------------------------------------------- /lib/stdarg.cb: -------------------------------------------------------------------------------- 1 | import stdarg; 2 | 3 | va_list 4 | va_init(void *arg) 5 | { 6 | return (va_list)arg + 1; 7 | } 8 | 9 | va_arg_t 10 | va_next(va_list* ap) 11 | { 12 | va_arg_t arg = **ap; 13 | (*ap)++; 14 | return arg; 15 | } 16 | -------------------------------------------------------------------------------- /lib/stdarg.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leungwensen/cbc-ubuntu-64bit/8e1121c4afff63fdc4bddd0e5e199adf9e23528f/lib/stdarg.o -------------------------------------------------------------------------------- /lib/stdarg.s: -------------------------------------------------------------------------------- 1 | .file "stdarg.cb" 2 | .text 3 | .globl va_init 4 | .type va_init,@function 5 | va_init: 6 | pushl %ebp 7 | movl %esp, %ebp 8 | movl $1, %eax 9 | sall $2, %eax 10 | movl %eax, %ecx 11 | movl 8(%ebp), %eax 12 | addl %ecx, %eax 13 | movl %ebp, %esp 14 | popl %ebp 15 | ret 16 | .size va_init,.-va_init 17 | .globl va_next 18 | .type va_next,@function 19 | va_next: 20 | pushl %ebp 21 | movl %esp, %ebp 22 | subl $12, %esp 23 | movl 8(%ebp), %eax 24 | movl (%eax), %eax 25 | movl (%eax), %eax 26 | movl %eax, -4(%ebp) 27 | movl 8(%ebp), %eax 28 | movl %eax, -8(%ebp) 29 | movl $1, %eax 30 | sall $2, %eax 31 | movl %eax, -12(%ebp) 32 | movl -8(%ebp), %eax 33 | movl (%eax), %eax 34 | movl -12(%ebp), %ecx 35 | addl %ecx, %eax 36 | movl %eax, -12(%ebp) 37 | movl -8(%ebp), %eax 38 | movl %eax, %ecx 39 | movl -12(%ebp), %eax 40 | movl %eax, (%ecx) 41 | movl -4(%ebp), %eax 42 | movl %ebp, %esp 43 | popl %ebp 44 | ret 45 | .size va_next,.-va_next 46 | .section .text.__i686.get_pc_thunk.bx,"axG",@progbits,__i686.get_pc_thunk.bx,comdat 47 | .globl __i686.get_pc_thunk.bx 48 | .hidden __i686.get_pc_thunk.bx 49 | .type __i686.get_pc_thunk.bx,@function 50 | __i686.get_pc_thunk.bx: 51 | movl (%esp), %ebx 52 | ret 53 | -------------------------------------------------------------------------------- /net/loveruby/cflat/asm/AbsoluteAddress.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.asm; 2 | 3 | public class AbsoluteAddress extends Operand { 4 | protected Register register; 5 | 6 | public AbsoluteAddress(Register reg) { 7 | this.register = reg; 8 | } 9 | 10 | public Operand register() { 11 | return this.register; 12 | } 13 | 14 | public void collectStatistics(Statistics stats) { 15 | register.collectStatistics(stats); 16 | } 17 | 18 | public String toSource(SymbolTable table) { 19 | return "*" + register.toSource(table); 20 | } 21 | 22 | public String dump() { 23 | return "(AbsoluteAddress " + register.dump() + ")"; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /net/loveruby/cflat/asm/Assembly.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.asm; 2 | 3 | abstract public class Assembly { 4 | abstract public String toSource(SymbolTable table); 5 | abstract public String dump(); 6 | 7 | public boolean isInstruction() { 8 | return false; 9 | } 10 | 11 | public boolean isLabel() { 12 | return false; 13 | } 14 | 15 | public boolean isDirective() { 16 | return false; 17 | } 18 | 19 | public boolean isComment() { 20 | return false; 21 | } 22 | 23 | public void collectStatistics(Statistics stats) { 24 | // does nothing by default. 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /net/loveruby/cflat/asm/BaseSymbol.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.asm; 2 | 3 | abstract public class BaseSymbol implements Symbol { 4 | public boolean isZero() { 5 | return false; 6 | } 7 | 8 | public void collectStatistics(Statistics stats) { 9 | stats.symbolUsed(this); 10 | } 11 | 12 | public Literal plus(long n) { 13 | throw new Error("must not happen: BaseSymbol.plus called"); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /net/loveruby/cflat/asm/Comment.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.asm; 2 | import net.loveruby.cflat.utils.TextUtils; 3 | 4 | public class Comment extends Assembly { 5 | protected String string; 6 | protected int indentLevel; 7 | 8 | public Comment(String string) { 9 | this(string, 0); 10 | } 11 | 12 | public Comment(String string, int indentLevel) { 13 | this.string = string; 14 | this.indentLevel = indentLevel; 15 | } 16 | 17 | public boolean isComment() { 18 | return true; 19 | } 20 | 21 | public String toSource(SymbolTable table) { 22 | return "\t" + indent() + "# " + string; 23 | } 24 | 25 | protected String indent() { 26 | StringBuffer buf = new StringBuffer(); 27 | for (int i = 0; i < indentLevel; i++) { 28 | buf.append(" "); 29 | } 30 | return buf.toString(); 31 | } 32 | 33 | public String dump() { 34 | return "(Comment " + TextUtils.dumpString(string) + ")"; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /net/loveruby/cflat/asm/DirectMemoryReference.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.asm; 2 | 3 | public class DirectMemoryReference extends MemoryReference { 4 | protected Literal value; 5 | 6 | public DirectMemoryReference(Literal val) { 7 | this.value = val; 8 | } 9 | 10 | public Literal value() { 11 | return this.value; 12 | } 13 | 14 | public void collectStatistics(Statistics stats) { 15 | value.collectStatistics(stats); 16 | } 17 | 18 | public void fixOffset(long diff) { 19 | throw new Error("DirectMemoryReference#fixOffset"); 20 | } 21 | 22 | public String toString() { 23 | return toSource(SymbolTable.dummy()); 24 | } 25 | 26 | public String toSource(SymbolTable table) { 27 | return this.value.toSource(table); 28 | } 29 | 30 | public int compareTo(MemoryReference mem) { 31 | return -(mem.cmp(this)); 32 | } 33 | 34 | protected int cmp(IndirectMemoryReference mem) { 35 | return 1; 36 | } 37 | 38 | protected int cmp(DirectMemoryReference mem) { 39 | return value.compareTo(mem.value); 40 | } 41 | 42 | public String dump() { 43 | return "(DirectMemoryReference " + value.dump() + ")"; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /net/loveruby/cflat/asm/Directive.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.asm; 2 | import net.loveruby.cflat.utils.TextUtils; 3 | 4 | public class Directive extends Assembly { 5 | protected String content; 6 | 7 | public Directive(String content) { 8 | this.content = content; 9 | } 10 | 11 | public boolean isDirective() { 12 | return true; 13 | } 14 | 15 | public String toSource(SymbolTable table) { 16 | return this.content; 17 | } 18 | 19 | public String dump() { 20 | return "(Directive " + TextUtils.dumpString(content.trim()) + ")"; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /net/loveruby/cflat/asm/ImmediateValue.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.asm; 2 | 3 | public class ImmediateValue extends Operand { 4 | protected Literal expr; 5 | 6 | public ImmediateValue(long n) { 7 | this(new IntegerLiteral(n)); 8 | } 9 | 10 | public ImmediateValue(Literal expr) { 11 | this.expr = expr; 12 | } 13 | 14 | public boolean equals(Object other) { 15 | if (!(other instanceof ImmediateValue)) return false; 16 | ImmediateValue imm = (ImmediateValue)other; 17 | return expr.equals(imm.expr); 18 | } 19 | 20 | public Literal expr() { 21 | return this.expr; 22 | } 23 | 24 | public void collectStatistics(Statistics stats) { 25 | // does nothing 26 | } 27 | 28 | public String toSource(SymbolTable table) { 29 | return "$" + expr.toSource(table); 30 | } 31 | 32 | public String dump() { 33 | return "(ImmediateValue " + expr.dump() + ")"; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /net/loveruby/cflat/asm/Label.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.asm; 2 | 3 | public class Label extends Assembly { 4 | protected Symbol symbol; 5 | 6 | public Label() { 7 | this(new UnnamedSymbol()); 8 | } 9 | 10 | public Label(Symbol sym) { 11 | this.symbol = sym; 12 | } 13 | 14 | public Symbol symbol() { 15 | return symbol; 16 | } 17 | 18 | public boolean isLabel() { 19 | return true; 20 | } 21 | 22 | public String toSource(SymbolTable table) { 23 | return symbol.toSource(table) + ":"; 24 | } 25 | 26 | public String dump() { 27 | return "(Label " + symbol.dump() + ")"; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /net/loveruby/cflat/asm/Literal.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.asm; 2 | 3 | public interface Literal extends Comparable { 4 | public String toSource(); 5 | public String toSource(SymbolTable table); 6 | public String dump(); 7 | public void collectStatistics(Statistics stats); 8 | public boolean isZero(); 9 | public Literal plus(long diff); 10 | public int cmp(IntegerLiteral i); 11 | public int cmp(NamedSymbol sym); 12 | public int cmp(UnnamedSymbol sym); 13 | public int cmp(SuffixedSymbol sym); 14 | } 15 | -------------------------------------------------------------------------------- /net/loveruby/cflat/asm/MemoryReference.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.asm; 2 | 3 | abstract public class MemoryReference 4 | extends Operand implements Comparable { 5 | public boolean isMemoryReference() { 6 | return true; 7 | } 8 | 9 | abstract public void fixOffset(long diff); 10 | abstract protected int cmp(DirectMemoryReference mem); 11 | abstract protected int cmp(IndirectMemoryReference mem); 12 | } 13 | -------------------------------------------------------------------------------- /net/loveruby/cflat/asm/NamedSymbol.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.asm; 2 | import net.loveruby.cflat.utils.TextUtils; 3 | 4 | public class NamedSymbol extends BaseSymbol { 5 | protected String name; 6 | 7 | public NamedSymbol(String name) { 8 | this.name = name; 9 | } 10 | 11 | public String name() { 12 | return name; 13 | } 14 | 15 | public String toSource() { 16 | return name; 17 | } 18 | 19 | public String toSource(SymbolTable table) { 20 | return name; 21 | } 22 | 23 | public String toString() { 24 | return "#" + name; 25 | } 26 | 27 | public int compareTo(Literal lit) { 28 | return -(lit.compareTo(this)); 29 | } 30 | 31 | public int cmp(IntegerLiteral i) { 32 | return 1; 33 | } 34 | 35 | public int cmp(NamedSymbol sym) { 36 | return name.compareTo(sym.name); 37 | } 38 | 39 | public int cmp(UnnamedSymbol sym) { 40 | return -1; 41 | } 42 | 43 | public int cmp(SuffixedSymbol sym) { 44 | return toString().compareTo(sym.toString()); 45 | } 46 | 47 | public String dump() { 48 | return "(NamedSymbol " + TextUtils.dumpString(name) + ")"; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /net/loveruby/cflat/asm/Operand.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.asm; 2 | 3 | abstract public class Operand implements OperandPattern { 4 | abstract public String toSource(SymbolTable table); 5 | abstract public String dump(); 6 | 7 | public boolean isRegister() { 8 | return false; 9 | } 10 | 11 | public boolean isMemoryReference() { 12 | return false; 13 | } 14 | 15 | public IntegerLiteral integerLiteral() { 16 | return null; 17 | } 18 | 19 | abstract public void collectStatistics(Statistics stats); 20 | 21 | // default implementation 22 | public boolean match(Operand operand) { 23 | return equals(operand); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /net/loveruby/cflat/asm/OperandPattern.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.asm; 2 | 3 | public interface OperandPattern { 4 | public boolean match(Operand operand); 5 | } 6 | -------------------------------------------------------------------------------- /net/loveruby/cflat/asm/Register.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.asm; 2 | 3 | abstract public class Register extends Operand { 4 | public boolean isRegister() { 5 | return true; 6 | } 7 | 8 | public void collectStatistics(Statistics stats) { 9 | stats.registerUsed(this); 10 | } 11 | 12 | abstract public String toSource(SymbolTable syms); 13 | abstract public String dump(); 14 | } 15 | -------------------------------------------------------------------------------- /net/loveruby/cflat/asm/Symbol.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.asm; 2 | 3 | public interface Symbol extends Literal { 4 | public String name(); 5 | public String toString(); 6 | public String dump(); 7 | } 8 | -------------------------------------------------------------------------------- /net/loveruby/cflat/asm/SymbolTable.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.asm; 2 | import java.util.*; 3 | 4 | public class SymbolTable { 5 | protected String base; 6 | protected Map map; 7 | protected long seq = 0; 8 | 9 | static private final String DUMMY_SYMBOL_BASE = "L"; 10 | static private final SymbolTable dummy = new SymbolTable(DUMMY_SYMBOL_BASE); 11 | 12 | static public SymbolTable dummy() { 13 | return dummy; 14 | } 15 | 16 | public SymbolTable(String base) { 17 | this.base = base; 18 | this.map = new HashMap(); 19 | } 20 | 21 | public Symbol newSymbol() { 22 | return new NamedSymbol(newString()); 23 | } 24 | 25 | public String symbolString(UnnamedSymbol sym) { 26 | String str = map.get(sym); 27 | if (str != null) { 28 | return str; 29 | } 30 | else { 31 | String newStr = newString(); 32 | map.put(sym, newStr); 33 | return newStr; 34 | } 35 | } 36 | 37 | protected String newString() { 38 | return base + seq++; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /net/loveruby/cflat/asm/Type.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.asm; 2 | 3 | public enum Type { 4 | INT8, INT16, INT32, INT64; 5 | 6 | static public Type get(long size) { 7 | switch ((int)size) { 8 | case 1: 9 | return INT8; 10 | case 2: 11 | return INT16; 12 | case 4: 13 | return INT32; 14 | case 8: 15 | return INT64; 16 | default: 17 | throw new Error("unsupported asm type size: " + size); 18 | } 19 | } 20 | 21 | public int size() { 22 | switch (this) { 23 | case INT8: 24 | return 1; 25 | case INT16: 26 | return 2; 27 | case INT32: 28 | return 4; 29 | case INT64: 30 | return 8; 31 | default: 32 | throw new Error("must not happen"); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /net/loveruby/cflat/asm/UnnamedSymbol.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.asm; 2 | 3 | public class UnnamedSymbol extends BaseSymbol { 4 | public UnnamedSymbol() { 5 | super(); 6 | } 7 | 8 | public String name() { 9 | throw new Error("unnamed symbol"); 10 | } 11 | 12 | public String toSource() { 13 | throw new Error("UnnamedSymbol#toSource() called"); 14 | } 15 | 16 | public String toSource(SymbolTable table) { 17 | return table.symbolString(this); 18 | } 19 | 20 | public String toString() { 21 | return super.toString(); 22 | } 23 | 24 | public int compareTo(Literal lit) { 25 | return -(lit.compareTo(this)); 26 | } 27 | 28 | public int cmp(IntegerLiteral i) { 29 | return 1; 30 | } 31 | 32 | public int cmp(NamedSymbol sym) { 33 | return 1; 34 | } 35 | 36 | public int cmp(UnnamedSymbol sym) { 37 | return toString().compareTo(sym.toString()); 38 | } 39 | 40 | public int cmp(SuffixedSymbol sym) { 41 | return 1; 42 | } 43 | 44 | public String dump() { 45 | return "(UnnamedSymbol @" + Integer.toHexString(hashCode()) + ")"; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ast/ASTVisitor.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ast; 2 | 3 | public interface ASTVisitor { 4 | // Statements 5 | public S visit(BlockNode node); 6 | public S visit(ExprStmtNode node); 7 | public S visit(IfNode node); 8 | public S visit(SwitchNode node); 9 | public S visit(CaseNode node); 10 | public S visit(WhileNode node); 11 | public S visit(DoWhileNode node); 12 | public S visit(ForNode node); 13 | public S visit(BreakNode node); 14 | public S visit(ContinueNode node); 15 | public S visit(GotoNode node); 16 | public S visit(LabelNode node); 17 | public S visit(ReturnNode node); 18 | 19 | // Expressions 20 | public E visit(AssignNode node); 21 | public E visit(OpAssignNode node); 22 | public E visit(CondExprNode node); 23 | public E visit(LogicalOrNode node); 24 | public E visit(LogicalAndNode node); 25 | public E visit(BinaryOpNode node); 26 | public E visit(UnaryOpNode node); 27 | public E visit(PrefixOpNode node); 28 | public E visit(SuffixOpNode node); 29 | public E visit(ArefNode node); 30 | public E visit(MemberNode node); 31 | public E visit(PtrMemberNode node); 32 | public E visit(FuncallNode node); 33 | public E visit(DereferenceNode node); 34 | public E visit(AddressNode node); 35 | public E visit(CastNode node); 36 | public E visit(SizeofExprNode node); 37 | public E visit(SizeofTypeNode node); 38 | public E visit(VariableNode node); 39 | public E visit(IntegerLiteralNode node); 40 | public E visit(StringLiteralNode node); 41 | } 42 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ast/AbstractAssignNode.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ast; 2 | import net.loveruby.cflat.type.*; 3 | 4 | abstract public class AbstractAssignNode extends ExprNode { 5 | ExprNode lhs, rhs; 6 | 7 | public AbstractAssignNode(ExprNode lhs, ExprNode rhs) { 8 | super(); 9 | this.lhs = lhs; 10 | this.rhs = rhs; 11 | } 12 | 13 | public Type type() { 14 | return lhs.type(); 15 | } 16 | 17 | public ExprNode lhs() { 18 | return lhs; 19 | } 20 | 21 | public ExprNode rhs() { 22 | return rhs; 23 | } 24 | 25 | public void setRHS(ExprNode expr) { 26 | this.rhs = expr; 27 | } 28 | 29 | public Location location() { 30 | return lhs.location(); 31 | } 32 | 33 | protected void _dump(Dumper d) { 34 | d.printMember("lhs", lhs); 35 | d.printMember("rhs", rhs); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ast/AddressNode.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ast; 2 | import net.loveruby.cflat.type.Type; 3 | 4 | public class AddressNode extends ExprNode { 5 | final ExprNode expr; 6 | Type type; 7 | 8 | public AddressNode(ExprNode expr) { 9 | this.expr = expr; 10 | } 11 | 12 | public ExprNode expr() { 13 | return expr; 14 | } 15 | 16 | public Type type() { 17 | if (type == null) throw new Error("type is null"); 18 | return type; 19 | } 20 | 21 | /** Decides type of this node. 22 | * This method is called from DereferenceChecker. */ 23 | public void setType(Type type) { 24 | if (this.type != null) throw new Error("type set twice"); 25 | this.type = type; 26 | } 27 | 28 | public Location location() { 29 | return expr.location(); 30 | } 31 | 32 | protected void _dump(Dumper d) { 33 | if (type != null) { 34 | d.printMember("type", type); 35 | } 36 | d.printMember("expr", expr); 37 | } 38 | 39 | public E accept(ASTVisitor visitor) { 40 | return visitor.visit(this); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ast/ArefNode.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ast; 2 | import net.loveruby.cflat.type.*; 3 | 4 | public class ArefNode extends LHSNode { 5 | private ExprNode expr, index; 6 | 7 | public ArefNode(ExprNode expr, ExprNode index) { 8 | this.expr = expr; 9 | this.index = index; 10 | } 11 | 12 | public ExprNode expr() { return expr; } 13 | public ExprNode index() { return index; } 14 | 15 | // isMultiDimension a[x][y][z] = true. 16 | // isMultiDimension a[x][y] = true. 17 | // isMultiDimension a[x] = false. 18 | public boolean isMultiDimension() { 19 | return (expr instanceof ArefNode) && !expr.origType().isPointer(); 20 | } 21 | 22 | // Returns base expression of (multi-dimension) array. 23 | // e.g. baseExpr of a[x][y][z] is a. 24 | public ExprNode baseExpr() { 25 | return isMultiDimension() ? ((ArefNode)expr).baseExpr() : expr; 26 | } 27 | 28 | // element size of this (multi-dimension) array 29 | public long elementSize() { 30 | return origType().allocSize(); 31 | } 32 | 33 | public long length() { 34 | return ((ArrayType)expr.origType()).length(); 35 | } 36 | 37 | protected Type origType() { 38 | return expr.origType().baseType(); 39 | } 40 | 41 | public Location location() { 42 | return expr.location(); 43 | } 44 | 45 | protected void _dump(Dumper d) { 46 | if (type != null) { 47 | d.printMember("type", type); 48 | } 49 | d.printMember("expr", expr); 50 | d.printMember("index", index); 51 | } 52 | 53 | public E accept(ASTVisitor visitor) { 54 | return visitor.visit(this); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ast/AssignNode.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ast; 2 | 3 | public class AssignNode extends AbstractAssignNode { 4 | public AssignNode(ExprNode lhs, ExprNode rhs) { 5 | super(lhs, rhs); 6 | } 7 | 8 | public E accept(ASTVisitor visitor) { 9 | return visitor.visit(this); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ast/BlockNode.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ast; 2 | import net.loveruby.cflat.entity.DefinedVariable; 3 | import net.loveruby.cflat.entity.LocalScope; 4 | import java.util.*; 5 | 6 | public class BlockNode extends StmtNode { 7 | protected List variables; 8 | protected List stmts; 9 | protected LocalScope scope; 10 | 11 | public BlockNode(Location loc, List vars, List stmts) { 12 | super(loc); 13 | this.variables = vars; 14 | this.stmts = stmts; 15 | } 16 | 17 | public List variables() { 18 | return variables; 19 | } 20 | 21 | public List stmts() { 22 | return stmts; 23 | } 24 | 25 | public StmtNode tailStmt() { 26 | if (stmts.isEmpty()) return null; 27 | return stmts.get(stmts.size() - 1); 28 | } 29 | 30 | public LocalScope scope() { 31 | return scope; 32 | } 33 | 34 | public void setScope(LocalScope scope) { 35 | this.scope = scope; 36 | } 37 | 38 | protected void _dump(Dumper d) { 39 | d.printNodeList("variables", variables); 40 | d.printNodeList("stmts", stmts); 41 | } 42 | 43 | public S accept(ASTVisitor visitor) { 44 | return visitor.visit(this); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ast/BreakNode.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ast; 2 | 3 | public class BreakNode extends StmtNode { 4 | public BreakNode(Location loc) { 5 | super(loc); 6 | } 7 | 8 | protected void _dump(Dumper d) { 9 | } 10 | 11 | public S accept(ASTVisitor visitor) { 12 | return visitor.visit(this); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ast/CaseNode.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ast; 2 | import net.loveruby.cflat.asm.Label; 3 | import java.util.*; 4 | 5 | public class CaseNode extends StmtNode { 6 | protected Label label; 7 | protected List values; 8 | protected BlockNode body; 9 | 10 | public CaseNode(Location loc, List values, BlockNode body) { 11 | super(loc); 12 | this.values = values; 13 | this.body = body; 14 | this.label = new Label(); 15 | } 16 | 17 | public List values() { 18 | return values; 19 | } 20 | 21 | public boolean isDefault() { 22 | return values.isEmpty(); 23 | } 24 | 25 | public BlockNode body() { 26 | return body; 27 | } 28 | 29 | public Label label() { 30 | return label; 31 | } 32 | 33 | protected void _dump(Dumper d) { 34 | d.printNodeList("values", values); 35 | d.printMember("body", body); 36 | } 37 | 38 | public S accept(ASTVisitor visitor) { 39 | return visitor.visit(this); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ast/CastNode.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ast; 2 | import net.loveruby.cflat.type.*; 3 | 4 | public class CastNode extends ExprNode { 5 | protected TypeNode typeNode; 6 | protected ExprNode expr; 7 | 8 | public CastNode(Type t, ExprNode expr) { 9 | this(new TypeNode(t), expr); 10 | } 11 | 12 | public CastNode(TypeNode t, ExprNode expr) { 13 | this.typeNode = t; 14 | this.expr = expr; 15 | } 16 | 17 | public Type type() { 18 | return typeNode.type(); 19 | } 20 | 21 | public TypeNode typeNode() { 22 | return typeNode; 23 | } 24 | 25 | public ExprNode expr() { 26 | return expr; 27 | } 28 | 29 | public boolean isLvalue() { return expr.isLvalue(); } 30 | public boolean isAssignable() { return expr.isAssignable(); } 31 | 32 | public boolean isEffectiveCast() { 33 | return type().size() > expr.type().size(); 34 | } 35 | 36 | public Location location() { 37 | return typeNode.location(); 38 | } 39 | 40 | protected void _dump(Dumper d) { 41 | d.printMember("typeNode", typeNode); 42 | d.printMember("expr", expr); 43 | } 44 | 45 | public E accept(ASTVisitor visitor) { 46 | return visitor.visit(this); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ast/CompositeTypeDefinition.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ast; 2 | import net.loveruby.cflat.type.*; 3 | import java.util.*; 4 | 5 | abstract public class CompositeTypeDefinition extends TypeDefinition { 6 | protected List members; 7 | 8 | public CompositeTypeDefinition(Location loc, TypeRef ref, 9 | String name, List membs) { 10 | super(loc, ref, name); 11 | members = membs; 12 | } 13 | 14 | public boolean isCompositeType() { 15 | return true; 16 | } 17 | 18 | abstract public String kind(); 19 | 20 | public List members() { 21 | return members; 22 | } 23 | 24 | protected void _dump(Dumper d) { 25 | d.printMember("name", name); 26 | d.printNodeList("members", members); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ast/CondExprNode.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ast; 2 | import net.loveruby.cflat.type.*; 3 | 4 | public class CondExprNode extends ExprNode { 5 | protected ExprNode cond, thenExpr, elseExpr; 6 | 7 | public CondExprNode(ExprNode cond, ExprNode t, ExprNode e) { 8 | super(); 9 | this.cond = cond; 10 | this.thenExpr = t; 11 | this.elseExpr = e; 12 | } 13 | 14 | public Type type() { 15 | return thenExpr.type(); 16 | } 17 | 18 | public ExprNode cond() { 19 | return cond; 20 | } 21 | 22 | public ExprNode thenExpr() { 23 | return thenExpr; 24 | } 25 | 26 | public void setThenExpr(ExprNode expr) { 27 | this.thenExpr = expr; 28 | } 29 | 30 | public ExprNode elseExpr() { 31 | return elseExpr; 32 | } 33 | 34 | public void setElseExpr(ExprNode expr) { 35 | this.elseExpr = expr; 36 | } 37 | 38 | public Location location() { 39 | return cond.location(); 40 | } 41 | 42 | protected void _dump(Dumper d) { 43 | d.printMember("cond", cond); 44 | d.printMember("thenExpr", thenExpr); 45 | d.printMember("elseExpr", elseExpr); 46 | } 47 | 48 | public E accept(ASTVisitor visitor) { 49 | return visitor.visit(this); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ast/ContinueNode.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ast; 2 | 3 | public class ContinueNode extends StmtNode { 4 | public ContinueNode(Location loc) { 5 | super(loc); 6 | } 7 | 8 | protected void _dump(Dumper d) { 9 | } 10 | 11 | public S accept(ASTVisitor visitor) { 12 | return visitor.visit(this); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ast/DeclarationVisitor.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ast; 2 | 3 | public interface DeclarationVisitor { 4 | public T visit(StructNode struct); 5 | public T visit(UnionNode union); 6 | public T visit(TypedefNode typedef); 7 | } 8 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ast/DereferenceNode.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ast; 2 | import net.loveruby.cflat.type.*; 3 | 4 | public class DereferenceNode extends LHSNode { 5 | private ExprNode expr; 6 | 7 | public DereferenceNode(ExprNode expr) { 8 | this.expr = expr; 9 | } 10 | 11 | protected Type origType() { 12 | return expr.type().baseType(); 13 | } 14 | 15 | public ExprNode expr() { 16 | return expr; 17 | } 18 | 19 | public void setExpr(ExprNode expr) { 20 | this.expr = expr; 21 | } 22 | 23 | public Location location() { 24 | return expr.location(); 25 | } 26 | 27 | protected void _dump(Dumper d) { 28 | if (type != null) { 29 | d.printMember("type", type); 30 | } 31 | d.printMember("expr", expr); 32 | } 33 | 34 | public E accept(ASTVisitor visitor) { 35 | return visitor.visit(this); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ast/DoWhileNode.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ast; 2 | 3 | public class DoWhileNode extends StmtNode { 4 | protected StmtNode body; 5 | protected ExprNode cond; 6 | 7 | public DoWhileNode(Location loc, StmtNode body, ExprNode cond) { 8 | super(loc); 9 | this.body = body; 10 | this.cond = cond; 11 | } 12 | 13 | public StmtNode body() { 14 | return body; 15 | } 16 | 17 | public ExprNode cond() { 18 | return cond; 19 | } 20 | 21 | protected void _dump(Dumper d) { 22 | d.printMember("body", body); 23 | d.printMember("cond", cond); 24 | } 25 | 26 | public S accept(ASTVisitor visitor) { 27 | return visitor.visit(this); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ast/Dumpable.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ast; 2 | 3 | public interface Dumpable { 4 | void dump(Dumper d); 5 | } 6 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ast/ExprNode.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ast; 2 | import net.loveruby.cflat.type.Type; 3 | import net.loveruby.cflat.exception.*; 4 | 5 | abstract public class ExprNode extends Node { 6 | public ExprNode() { 7 | super(); 8 | } 9 | 10 | abstract public Type type(); 11 | protected Type origType() { return type(); } 12 | 13 | public long allocSize() { return type().allocSize(); } 14 | 15 | public boolean isConstant() { return false; } 16 | public boolean isParameter() { return false; } 17 | 18 | public boolean isLvalue() { return false; } 19 | public boolean isAssignable() { return false; } 20 | public boolean isLoadable() { return false; } 21 | 22 | public boolean isCallable() { 23 | try { 24 | return type().isCallable(); 25 | } 26 | catch (SemanticError err) { 27 | return false; 28 | } 29 | } 30 | 31 | // #@@range/isPointer{ 32 | public boolean isPointer() { 33 | try { 34 | return type().isPointer(); 35 | } 36 | catch (SemanticError err) { 37 | return false; 38 | } 39 | } 40 | // #@@} 41 | 42 | abstract public E accept(ASTVisitor visitor); 43 | } 44 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ast/ExprStmtNode.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ast; 2 | 3 | public class ExprStmtNode extends StmtNode { 4 | protected ExprNode expr; 5 | 6 | public ExprStmtNode(Location loc, ExprNode expr) { 7 | super(loc); 8 | this.expr = expr; 9 | } 10 | 11 | public ExprNode expr() { 12 | return expr; 13 | } 14 | 15 | public void setExpr(ExprNode expr) { 16 | this.expr = expr; 17 | } 18 | 19 | protected void _dump(Dumper d) { 20 | d.printMember("expr", expr); 21 | } 22 | 23 | public S accept(ASTVisitor visitor) { 24 | return visitor.visit(this); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ast/ForNode.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ast; 2 | import net.loveruby.cflat.type.*; 3 | 4 | public class ForNode extends StmtNode { 5 | protected StmtNode init; 6 | protected ExprNode cond; 7 | protected StmtNode incr; 8 | protected StmtNode body; 9 | 10 | public ForNode(Location loc, 11 | ExprNode init, ExprNode cond, ExprNode incr, StmtNode body) { 12 | super(loc); 13 | if (init != null) { 14 | this.init = new ExprStmtNode(init.location(), init); 15 | } else { 16 | this.init = null; 17 | } 18 | if (cond != null) { 19 | this.cond = cond; 20 | } else { 21 | this.cond = new IntegerLiteralNode(null, IntegerTypeRef.intRef(), 1); 22 | } 23 | if (incr != null) { 24 | this.incr = new ExprStmtNode(incr.location(), incr); 25 | } else { 26 | this.incr = null; 27 | } 28 | this.body = body; 29 | } 30 | 31 | public StmtNode init() { 32 | return init; 33 | } 34 | 35 | public ExprNode cond() { 36 | return cond; 37 | } 38 | 39 | public StmtNode incr() { 40 | return incr; 41 | } 42 | 43 | public StmtNode body() { 44 | return body; 45 | } 46 | 47 | protected void _dump(Dumper d) { 48 | d.printMember("init", init); 49 | d.printMember("cond", cond); 50 | d.printMember("incr", incr); 51 | d.printMember("body", body); 52 | } 53 | 54 | public S accept(ASTVisitor visitor) { 55 | return visitor.visit(this); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ast/GotoNode.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ast; 2 | 3 | public class GotoNode extends StmtNode { 4 | protected String target; 5 | 6 | public GotoNode(Location loc, String target) { 7 | super(loc); 8 | this.target = target; 9 | } 10 | 11 | public String target() { 12 | return target; 13 | } 14 | 15 | protected void _dump(Dumper d) { 16 | d.printMember("target", target); 17 | } 18 | 19 | public S accept(ASTVisitor visitor) { 20 | return visitor.visit(this); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ast/IfNode.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ast; 2 | 3 | public class IfNode extends StmtNode { 4 | protected ExprNode cond; 5 | protected StmtNode thenBody; 6 | protected StmtNode elseBody; 7 | 8 | public IfNode(Location loc, ExprNode c, StmtNode t, StmtNode e) { 9 | super(loc); 10 | this.cond = c; 11 | this.thenBody = t; 12 | this.elseBody = e; 13 | } 14 | 15 | public ExprNode cond() { 16 | return cond; 17 | } 18 | 19 | public StmtNode thenBody() { 20 | return thenBody; 21 | } 22 | 23 | public StmtNode elseBody() { 24 | return elseBody; 25 | } 26 | 27 | protected void _dump(Dumper d) { 28 | d.printMember("cond", cond); 29 | d.printMember("thenBody", thenBody); 30 | d.printMember("elseBody", elseBody); 31 | } 32 | 33 | public S accept(ASTVisitor visitor) { 34 | return visitor.visit(this); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ast/IntegerLiteralNode.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ast; 2 | import net.loveruby.cflat.type.*; 3 | 4 | public class IntegerLiteralNode extends LiteralNode { 5 | protected long value; 6 | 7 | public IntegerLiteralNode(Location loc, TypeRef ref, long value) { 8 | super(loc, ref); 9 | this.value = value; 10 | } 11 | 12 | public long value() { 13 | return value; 14 | } 15 | 16 | protected void _dump(Dumper d) { 17 | d.printMember("typeNode", typeNode); 18 | d.printMember("value", value); 19 | } 20 | 21 | public E accept(ASTVisitor visitor) { 22 | return visitor.visit(this); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ast/LHSNode.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ast; 2 | import net.loveruby.cflat.type.Type; 3 | 4 | abstract public class LHSNode extends ExprNode { 5 | protected Type type, origType; 6 | 7 | public Type type() { 8 | return type != null ? type : origType(); 9 | } 10 | 11 | public void setType(Type t) { 12 | this.type = t; 13 | } 14 | 15 | abstract protected Type origType(); 16 | 17 | public long allocSize() { return origType().allocSize(); } 18 | 19 | public boolean isLvalue() { return true; } 20 | public boolean isAssignable() { return isLoadable(); } 21 | 22 | public boolean isLoadable() { 23 | Type t = origType(); 24 | return !t.isArray() && !t.isFunction(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ast/LabelNode.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ast; 2 | 3 | public class LabelNode extends StmtNode { 4 | protected String name; 5 | protected StmtNode stmt; 6 | 7 | public LabelNode(Location loc, String name, StmtNode stmt) { 8 | super(loc); 9 | this.name = name; 10 | this.stmt = stmt; 11 | } 12 | 13 | public String name() { 14 | return name; 15 | } 16 | 17 | public StmtNode stmt() { 18 | return stmt; 19 | } 20 | 21 | protected void _dump(Dumper d) { 22 | d.printMember("name", name); 23 | d.printMember("stmt", stmt); 24 | } 25 | 26 | public S accept(ASTVisitor visitor) { 27 | return visitor.visit(this); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ast/LiteralNode.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ast; 2 | import net.loveruby.cflat.type.TypeRef; 3 | import net.loveruby.cflat.type.Type; 4 | 5 | abstract public class LiteralNode extends ExprNode { 6 | protected Location location; 7 | protected TypeNode typeNode; 8 | 9 | public LiteralNode(Location loc, TypeRef ref) { 10 | super(); 11 | this.location = loc; 12 | this.typeNode = new TypeNode(ref); 13 | } 14 | 15 | public Location location() { 16 | return location; 17 | } 18 | 19 | public Type type() { 20 | return typeNode.type(); 21 | } 22 | 23 | public TypeNode typeNode() { 24 | return typeNode; 25 | } 26 | 27 | public boolean isConstant() { 28 | return true; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ast/Location.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ast; 2 | import net.loveruby.cflat.parser.Token; 3 | import net.loveruby.cflat.parser.ParserConstants; 4 | import net.loveruby.cflat.utils.TextUtils; 5 | import java.util.*; 6 | 7 | public class Location { 8 | protected String sourceName; 9 | protected CflatToken token; 10 | 11 | public Location(String sourceName, Token token) { 12 | this(sourceName, new CflatToken(token)); 13 | } 14 | 15 | public Location(String sourceName, CflatToken token) { 16 | this.sourceName = sourceName; 17 | this.token = token; 18 | } 19 | 20 | public String sourceName() { 21 | return sourceName; 22 | } 23 | 24 | public CflatToken token() { 25 | return token; 26 | } 27 | 28 | /** line number */ 29 | public int lineno() { 30 | return token.lineno(); 31 | } 32 | 33 | public int column() { 34 | return token.column(); 35 | } 36 | 37 | public String line() { 38 | return token.includedLine(); 39 | } 40 | 41 | public String numberedLine() { 42 | return "line " + token.lineno() + ": " + line(); 43 | } 44 | 45 | public String toString() { 46 | return sourceName + ":" + token.lineno(); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ast/LogicalAndNode.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ast; 2 | 3 | public class LogicalAndNode extends BinaryOpNode { 4 | public LogicalAndNode(ExprNode left, ExprNode right) { 5 | super(left, "&&", right); 6 | } 7 | 8 | public E accept(ASTVisitor visitor) { 9 | return visitor.visit(this); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ast/LogicalOrNode.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ast; 2 | 3 | public class LogicalOrNode extends BinaryOpNode { 4 | public LogicalOrNode(ExprNode left, ExprNode right) { 5 | super(left, "||", right); 6 | } 7 | 8 | public E accept(ASTVisitor visitor) { 9 | return visitor.visit(this); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ast/MemberNode.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ast; 2 | import net.loveruby.cflat.type.Type; 3 | import net.loveruby.cflat.type.CompositeType; 4 | import net.loveruby.cflat.exception.*; 5 | 6 | public class MemberNode extends LHSNode { 7 | private ExprNode expr; 8 | private String member; 9 | 10 | public MemberNode(ExprNode expr, String member) { 11 | this.expr = expr; 12 | this.member = member; 13 | } 14 | 15 | public CompositeType baseType() { 16 | try { 17 | return expr.type().getCompositeType(); 18 | } 19 | catch (ClassCastException err) { 20 | throw new SemanticError(err.getMessage()); 21 | } 22 | } 23 | 24 | public ExprNode expr() { 25 | return expr; 26 | } 27 | 28 | public String member() { 29 | return member; 30 | } 31 | 32 | public long offset() { 33 | return baseType().memberOffset(member); 34 | } 35 | 36 | protected Type origType() { 37 | return baseType().memberType(member); 38 | } 39 | 40 | public Location location() { 41 | return expr.location(); 42 | } 43 | 44 | protected void _dump(Dumper d) { 45 | if (type != null) { 46 | d.printMember("type", type); 47 | } 48 | d.printMember("expr", expr); 49 | d.printMember("member", member); 50 | } 51 | 52 | public E accept(ASTVisitor visitor) { 53 | return visitor.visit(this); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ast/Node.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ast; 2 | import java.io.PrintStream; 3 | 4 | abstract public class Node implements Dumpable { 5 | public Node() { 6 | } 7 | 8 | abstract public Location location(); 9 | 10 | public void dump() { 11 | dump(System.out); 12 | } 13 | 14 | public void dump(PrintStream s) { 15 | dump(new Dumper(s)); 16 | } 17 | 18 | public void dump(Dumper d) { 19 | d.printClass(this, location()); 20 | _dump(d); 21 | } 22 | 23 | abstract protected void _dump(Dumper d); 24 | } 25 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ast/OpAssignNode.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ast; 2 | 3 | public class OpAssignNode extends AbstractAssignNode { 4 | protected String operator; 5 | 6 | public OpAssignNode(ExprNode lhs, String op, ExprNode rhs) { 7 | super(lhs, rhs); 8 | this.operator = op; 9 | } 10 | 11 | public String operator() { 12 | return operator; 13 | } 14 | 15 | public E accept(ASTVisitor visitor) { 16 | return visitor.visit(this); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ast/PrefixOpNode.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ast; 2 | 3 | public class PrefixOpNode extends UnaryArithmeticOpNode { 4 | public PrefixOpNode(String op, ExprNode expr) { 5 | super(op, expr); 6 | } 7 | 8 | public E accept(ASTVisitor visitor) { 9 | return visitor.visit(this); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ast/ReturnNode.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ast; 2 | 3 | public class ReturnNode extends StmtNode { 4 | protected ExprNode expr; 5 | 6 | public ReturnNode(Location loc, ExprNode expr) { 7 | super(loc); 8 | this.expr = expr; 9 | } 10 | 11 | public ExprNode expr() { 12 | return this.expr; 13 | } 14 | 15 | public void setExpr(ExprNode expr) { 16 | this.expr = expr; 17 | } 18 | 19 | protected void _dump(Dumper d) { 20 | d.printMember("expr", expr); 21 | } 22 | 23 | public S accept(ASTVisitor visitor) { 24 | return visitor.visit(this); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ast/SizeofExprNode.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ast; 2 | import net.loveruby.cflat.type.*; 3 | 4 | public class SizeofExprNode extends ExprNode { 5 | protected ExprNode expr; 6 | protected TypeNode type; 7 | 8 | public SizeofExprNode(ExprNode expr, TypeRef type) { 9 | this.expr = expr; 10 | this.type = new TypeNode(type); 11 | } 12 | 13 | public ExprNode expr() { 14 | return this.expr; 15 | } 16 | 17 | public void setExpr(ExprNode expr) { 18 | this.expr = expr; 19 | } 20 | 21 | public Type type() { 22 | return this.type.type(); 23 | } 24 | 25 | public TypeNode typeNode() { 26 | return this.type; 27 | } 28 | 29 | public Location location() { 30 | return expr.location(); 31 | } 32 | 33 | protected void _dump(Dumper d) { 34 | d.printMember("expr", expr); 35 | } 36 | 37 | public E accept(ASTVisitor visitor) { 38 | return visitor.visit(this); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ast/SizeofTypeNode.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ast; 2 | import net.loveruby.cflat.type.*; 3 | 4 | public class SizeofTypeNode extends ExprNode { 5 | protected TypeNode operand; 6 | protected TypeNode type; 7 | 8 | public SizeofTypeNode(TypeNode operand, TypeRef type) { 9 | this.operand = operand; 10 | this.type = new TypeNode(type); 11 | } 12 | 13 | public Type operand() { 14 | return operand.type(); 15 | } 16 | 17 | public TypeNode operandTypeNode() { 18 | return operand; 19 | } 20 | 21 | public Type type() { 22 | return type.type(); 23 | } 24 | 25 | public TypeNode typeNode() { 26 | return type; 27 | } 28 | 29 | public Location location() { 30 | return operand.location(); 31 | } 32 | 33 | protected void _dump(Dumper d) { 34 | d.printMember("operand", operand); 35 | } 36 | 37 | public E accept(ASTVisitor visitor) { 38 | return visitor.visit(this); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ast/Slot.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ast; 2 | import net.loveruby.cflat.type.*; 3 | 4 | public class Slot extends Node { 5 | protected TypeNode typeNode; 6 | protected String name; 7 | protected long offset; 8 | 9 | public Slot(TypeNode t, String n) { 10 | typeNode = t; 11 | name = n; 12 | offset = Type.sizeUnknown; 13 | } 14 | 15 | public TypeNode typeNode() { 16 | return typeNode; 17 | } 18 | 19 | public TypeRef typeRef() { 20 | return typeNode.typeRef(); 21 | } 22 | 23 | public Type type() { 24 | return typeNode.type(); 25 | } 26 | 27 | public String name() { 28 | return name; 29 | } 30 | 31 | public long size() { 32 | return type().size(); 33 | } 34 | 35 | public long allocSize() { 36 | return type().allocSize(); 37 | } 38 | 39 | public long alignment() { 40 | return type().alignment(); 41 | } 42 | 43 | public long offset() { 44 | return offset; 45 | } 46 | 47 | public void setOffset(long offset) { 48 | this.offset = offset; 49 | } 50 | 51 | public Location location() { 52 | return typeNode.location(); 53 | } 54 | 55 | protected void _dump(Dumper d) { 56 | d.printMember("name", name); 57 | d.printMember("typeNode", typeNode); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ast/StmtNode.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ast; 2 | 3 | abstract public class StmtNode extends Node { 4 | protected Location location; 5 | 6 | public StmtNode(Location loc) { 7 | this.location = loc; 8 | } 9 | 10 | public Location location() { 11 | return location; 12 | } 13 | 14 | abstract public S accept(ASTVisitor visitor); 15 | } 16 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ast/StringLiteralNode.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ast; 2 | import net.loveruby.cflat.type.TypeRef; 3 | import net.loveruby.cflat.entity.ConstantEntry; 4 | 5 | public class StringLiteralNode extends LiteralNode { 6 | protected String value; 7 | protected ConstantEntry entry; 8 | 9 | public StringLiteralNode(Location loc, TypeRef ref, String value) { 10 | super(loc, ref); 11 | this.value = value; 12 | } 13 | 14 | public String value() { 15 | return value; 16 | } 17 | 18 | public ConstantEntry entry() { 19 | return entry; 20 | } 21 | 22 | public void setEntry(ConstantEntry ent) { 23 | entry = ent; 24 | } 25 | 26 | protected void _dump(Dumper d) { 27 | d.printMember("value", value); 28 | } 29 | 30 | public E accept(ASTVisitor visitor) { 31 | return visitor.visit(this); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ast/StructNode.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ast; 2 | import net.loveruby.cflat.type.*; 3 | import java.util.*; 4 | 5 | public class StructNode extends CompositeTypeDefinition { 6 | public StructNode(Location loc, TypeRef ref, String name, List membs) { 7 | super(loc, ref, name, membs); 8 | } 9 | 10 | public String kind() { 11 | return "struct"; 12 | } 13 | 14 | public boolean isStruct() { 15 | return true; 16 | } 17 | 18 | // #@@range/definingType{ 19 | public Type definingType() { 20 | return new StructType(name(), members(), location()); 21 | } 22 | // #@@} 23 | 24 | public T accept(DeclarationVisitor visitor) { 25 | return visitor.visit(this); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ast/SuffixOpNode.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ast; 2 | 3 | public class SuffixOpNode extends UnaryArithmeticOpNode { 4 | public SuffixOpNode(String op, ExprNode expr) { 5 | super(op, expr); 6 | } 7 | 8 | public E accept(ASTVisitor visitor) { 9 | return visitor.visit(this); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ast/SwitchNode.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ast; 2 | import java.util.List; 3 | 4 | public class SwitchNode extends StmtNode { 5 | protected ExprNode cond; 6 | protected List cases; 7 | 8 | public SwitchNode(Location loc, ExprNode cond, List cases) { 9 | super(loc); 10 | this.cond = cond; 11 | this.cases = cases; 12 | } 13 | 14 | public ExprNode cond() { 15 | return cond; 16 | } 17 | 18 | public List cases() { 19 | return cases; 20 | } 21 | 22 | protected void _dump(Dumper d) { 23 | d.printMember("cond", cond); 24 | d.printNodeList("cases", cases); 25 | } 26 | 27 | public S accept(ASTVisitor visitor) { 28 | return visitor.visit(this); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ast/TypeDefinition.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ast; 2 | import net.loveruby.cflat.type.*; 3 | 4 | abstract public class TypeDefinition extends Node { 5 | protected String name; 6 | protected Location location; 7 | protected TypeNode typeNode; 8 | 9 | public TypeDefinition(Location loc, TypeRef ref, String name) { 10 | this.name = name; 11 | this.location = loc; 12 | this.typeNode = new TypeNode(ref); 13 | } 14 | 15 | public String name() { 16 | return name; 17 | } 18 | 19 | public Location location() { 20 | return location; 21 | } 22 | 23 | public TypeNode typeNode() { 24 | return typeNode; 25 | } 26 | 27 | public TypeRef typeRef() { 28 | return typeNode.typeRef(); 29 | } 30 | 31 | public Type type() { 32 | return typeNode.type(); 33 | } 34 | 35 | abstract public Type definingType(); 36 | abstract public T accept(DeclarationVisitor visitor); 37 | } 38 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ast/TypeNode.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ast; 2 | import net.loveruby.cflat.type.*; 3 | 4 | public class TypeNode extends Node { 5 | TypeRef typeRef; 6 | Type type; 7 | 8 | public TypeNode(TypeRef ref) { 9 | super(); 10 | this.typeRef = ref; 11 | } 12 | 13 | public TypeNode(Type type) { 14 | super(); 15 | this.type = type; 16 | } 17 | 18 | public TypeRef typeRef() { 19 | return typeRef; 20 | } 21 | 22 | public boolean isResolved() { 23 | return (type != null); 24 | } 25 | 26 | public void setType(Type t) { 27 | if (type != null) { 28 | throw new Error("TypeNode#setType called twice"); 29 | } 30 | type = t; 31 | } 32 | 33 | public Type type() { 34 | if (type == null) { 35 | throw new Error("TypeNode not resolved: " + typeRef); 36 | } 37 | return type; 38 | } 39 | 40 | public Location location() { 41 | return typeRef == null ? null : typeRef.location(); 42 | } 43 | 44 | protected void _dump(Dumper d) { 45 | d.printMember("typeref", typeRef); 46 | d.printMember("type", type); 47 | } 48 | 49 | public TypeNode accept(ASTVisitor visitor) { 50 | throw new Error("do not call TypeNode#accept"); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ast/TypedefNode.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ast; 2 | import net.loveruby.cflat.type.*; 3 | 4 | public class TypedefNode extends TypeDefinition { 5 | protected TypeNode real; 6 | 7 | public TypedefNode(Location loc, TypeRef real, String name) { 8 | super(loc, new UserTypeRef(name), name); 9 | this.real = new TypeNode(real); 10 | } 11 | 12 | public boolean isUserType() { 13 | return true; 14 | } 15 | 16 | public TypeNode realTypeNode() { 17 | return real; 18 | } 19 | 20 | public Type realType() { 21 | return real.type(); 22 | } 23 | 24 | public TypeRef realTypeRef() { 25 | return real.typeRef(); 26 | } 27 | 28 | // #@@range/definingType{ 29 | public Type definingType() { 30 | return new UserType(name(), realTypeNode(), location()); 31 | } 32 | // #@@} 33 | 34 | protected void _dump(Dumper d) { 35 | d.printMember("name", name); 36 | d.printMember("typeNode", typeNode); 37 | } 38 | 39 | public T accept(DeclarationVisitor visitor) { 40 | return visitor.visit(this); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ast/UnaryArithmeticOpNode.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ast; 2 | 3 | public class UnaryArithmeticOpNode extends UnaryOpNode { 4 | protected long amount; 5 | 6 | public UnaryArithmeticOpNode(String op, ExprNode expr) { 7 | super(op, expr); 8 | amount = 1; 9 | } 10 | 11 | public void setExpr(ExprNode expr) { 12 | this.expr = expr; 13 | } 14 | 15 | public long amount() { 16 | return this.amount; 17 | } 18 | 19 | public void setAmount(long amount) { 20 | this.amount = amount; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ast/UnaryOpNode.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ast; 2 | import net.loveruby.cflat.type.Type; 3 | 4 | public class UnaryOpNode extends ExprNode { 5 | protected String operator; 6 | protected ExprNode expr; 7 | protected Type opType; 8 | 9 | public UnaryOpNode(String op, ExprNode expr) { 10 | this.operator = op; 11 | this.expr = expr; 12 | } 13 | 14 | public String operator() { 15 | return operator; 16 | } 17 | 18 | public Type type() { 19 | return expr.type(); 20 | } 21 | 22 | public void setOpType(Type t) { 23 | this.opType = t; 24 | } 25 | 26 | public Type opType() { 27 | return opType; 28 | } 29 | 30 | public ExprNode expr() { 31 | return expr; 32 | } 33 | 34 | public void setExpr(ExprNode expr) { 35 | this.expr = expr; 36 | } 37 | 38 | public Location location() { 39 | return expr.location(); 40 | } 41 | 42 | protected void _dump(Dumper d) { 43 | d.printMember("operator", operator); 44 | d.printMember("expr", expr); 45 | } 46 | 47 | public E accept(ASTVisitor visitor) { 48 | return visitor.visit(this); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ast/UnionNode.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ast; 2 | import net.loveruby.cflat.type.*; 3 | import java.util.*; 4 | 5 | public class UnionNode extends CompositeTypeDefinition { 6 | public UnionNode(Location loc, TypeRef ref, String name, List membs) { 7 | super(loc, ref, name, membs); 8 | } 9 | 10 | public String kind() { 11 | return "union"; 12 | } 13 | 14 | public boolean isUnion() { 15 | return true; 16 | } 17 | 18 | // #@@range/definingType{ 19 | public Type definingType() { 20 | return new UnionType(name(), members(), location()); 21 | } 22 | // #@@} 23 | 24 | public T accept(DeclarationVisitor visitor) { 25 | return visitor.visit(this); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ast/WhileNode.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ast; 2 | 3 | public class WhileNode extends StmtNode { 4 | protected StmtNode body; 5 | protected ExprNode cond; 6 | 7 | public WhileNode(Location loc, ExprNode cond, StmtNode body) { 8 | super(loc); 9 | this.cond = cond; 10 | this.body = body; 11 | } 12 | 13 | public ExprNode cond() { 14 | return cond; 15 | } 16 | 17 | public StmtNode body() { 18 | return body; 19 | } 20 | 21 | protected void _dump(Dumper d) { 22 | d.printMember("cond", cond); 23 | d.printMember("body", body); 24 | } 25 | 26 | public S accept(ASTVisitor visitor) { 27 | return visitor.visit(this); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /net/loveruby/cflat/compiler/LdArg.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.compiler; 2 | 3 | interface LdArg { 4 | String toString(); 5 | boolean isSourceFile(); 6 | } 7 | -------------------------------------------------------------------------------- /net/loveruby/cflat/compiler/LdOption.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.compiler; 2 | 3 | class LdOption implements LdArg { 4 | private final String arg; 5 | 6 | LdOption(String arg) { 7 | this.arg = arg; 8 | } 9 | 10 | public boolean isSourceFile() { 11 | return false; 12 | } 13 | 14 | public String toString() { 15 | return arg; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /net/loveruby/cflat/entity/CBCParameter.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.entity; 2 | import net.loveruby.cflat.ast.TypeNode; 3 | 4 | public class CBCParameter extends DefinedVariable { 5 | public CBCParameter(TypeNode type, String name) { 6 | super(false, type, name, null); 7 | } 8 | 9 | public boolean isParameter() { 10 | return true; 11 | } 12 | 13 | protected void _dump(net.loveruby.cflat.ast.Dumper d) { 14 | d.printMember("name", name); 15 | d.printMember("typeNode", typeNode); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /net/loveruby/cflat/entity/Constant.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.entity; 2 | import net.loveruby.cflat.ast.TypeNode; 3 | import net.loveruby.cflat.ast.ExprNode; 4 | 5 | public class Constant extends Entity { 6 | private TypeNode type; 7 | private String name; 8 | private ExprNode value; 9 | 10 | public Constant(TypeNode type, String name, ExprNode value) { 11 | super(true, type, name); 12 | this.value = value; 13 | } 14 | 15 | public boolean isAssignable() { return false; } 16 | public boolean isDefined() { return true; } 17 | public boolean isInitialized() { return true; } 18 | public boolean isConstant() { return true; } 19 | 20 | public ExprNode value() { return value; } 21 | 22 | protected void _dump(net.loveruby.cflat.ast.Dumper d) { 23 | d.printMember("name", name); 24 | d.printMember("typeNode", typeNode); 25 | d.printMember("value", value); 26 | } 27 | 28 | public T accept(EntityVisitor visitor) { 29 | return visitor.visit(this); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /net/loveruby/cflat/entity/ConstantEntry.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.entity; 2 | import net.loveruby.cflat.asm.Symbol; 3 | import net.loveruby.cflat.asm.ImmediateValue; 4 | import net.loveruby.cflat.asm.MemoryReference; 5 | 6 | public class ConstantEntry { 7 | protected String value; 8 | protected Symbol symbol; 9 | protected MemoryReference memref; 10 | protected ImmediateValue address; 11 | 12 | public ConstantEntry(String val) { 13 | value = val; 14 | } 15 | 16 | public String value() { 17 | return value; 18 | } 19 | 20 | public void setSymbol(Symbol sym) { 21 | this.symbol = sym; 22 | } 23 | 24 | public Symbol symbol() { 25 | if (symbol == null) { 26 | throw new Error("must not happen: symbol == null"); 27 | } 28 | return symbol; 29 | } 30 | 31 | public void setMemref(MemoryReference mem) { 32 | this.memref = mem; 33 | } 34 | 35 | public MemoryReference memref() { 36 | if (this.memref == null) { 37 | throw new Error("must not happen: memref == null"); 38 | } 39 | return this.memref; 40 | } 41 | 42 | public void setAddress(ImmediateValue imm) { 43 | this.address = imm; 44 | } 45 | 46 | public ImmediateValue address() { 47 | return this.address; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /net/loveruby/cflat/entity/ConstantTable.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.entity; 2 | import java.util.*; 3 | 4 | public class ConstantTable implements Iterable { 5 | protected Map table; 6 | 7 | public ConstantTable() { 8 | table = new LinkedHashMap(); 9 | } 10 | 11 | public boolean isEmpty() { 12 | return table.isEmpty(); 13 | } 14 | 15 | public ConstantEntry intern(String s) { 16 | ConstantEntry ent = table.get(s); 17 | if (ent == null) { 18 | ent = new ConstantEntry(s); 19 | table.put(s, ent); 20 | } 21 | return ent; 22 | } 23 | 24 | public Collection entries() { 25 | return table.values(); 26 | } 27 | 28 | public Iterator iterator() { 29 | return table.values().iterator(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /net/loveruby/cflat/entity/EntityVisitor.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.entity; 2 | 3 | public interface EntityVisitor { 4 | public T visit(DefinedVariable var); 5 | public T visit(UndefinedVariable var); 6 | public T visit(DefinedFunction func); 7 | public T visit(UndefinedFunction func); 8 | public T visit(Constant c); 9 | } 10 | -------------------------------------------------------------------------------- /net/loveruby/cflat/entity/Function.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.entity; 2 | import net.loveruby.cflat.type.Type; 3 | import net.loveruby.cflat.type.FunctionType; 4 | import net.loveruby.cflat.ast.TypeNode; 5 | import net.loveruby.cflat.asm.Symbol; 6 | import net.loveruby.cflat.asm.Label; 7 | import java.util.List; 8 | 9 | abstract public class Function extends Entity { 10 | protected Symbol callingSymbol; 11 | protected Label label; 12 | 13 | public Function(boolean priv, TypeNode t, String name) { 14 | super(priv, t, name); 15 | } 16 | 17 | public boolean isInitialized() { return true; } 18 | 19 | abstract public boolean isDefined(); 20 | abstract public List parameters(); 21 | 22 | public Type returnType() { 23 | return type().getFunctionType().returnType(); 24 | } 25 | 26 | public boolean isVoid() { 27 | return returnType().isVoid(); 28 | } 29 | 30 | public void setCallingSymbol(Symbol sym) { 31 | if (this.callingSymbol != null) { 32 | throw new Error("must not happen: Function#callingSymbol was set again"); 33 | } 34 | this.callingSymbol = sym; 35 | } 36 | 37 | public Symbol callingSymbol() { 38 | if (this.callingSymbol == null) { 39 | throw new Error("must not happen: Function#callingSymbol called but null"); 40 | } 41 | return this.callingSymbol; 42 | } 43 | 44 | public Label label() { 45 | if (label != null) { 46 | return label; 47 | } 48 | else { 49 | return label = new Label(callingSymbol()); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /net/loveruby/cflat/entity/ParamSlots.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.entity; 2 | import net.loveruby.cflat.ast.Location; 3 | import java.util.*; 4 | 5 | abstract public class ParamSlots { 6 | protected Location location; 7 | protected List paramDescriptors; 8 | protected boolean vararg; 9 | 10 | public ParamSlots(List paramDescs) { 11 | this(null, paramDescs); 12 | } 13 | 14 | public ParamSlots(Location loc, List paramDescs) { 15 | this(loc, paramDescs, false); 16 | } 17 | 18 | protected ParamSlots(Location loc, List paramDescs, boolean vararg) { 19 | super(); 20 | this.location = loc; 21 | this.paramDescriptors = paramDescs; 22 | this.vararg = vararg; 23 | } 24 | 25 | public int argc() { 26 | if (vararg) { 27 | throw new Error("must not happen: Param#argc for vararg"); 28 | } 29 | return paramDescriptors.size(); 30 | } 31 | 32 | public int minArgc() { 33 | return paramDescriptors.size(); 34 | } 35 | 36 | public void acceptVarargs() { 37 | this.vararg = true; 38 | } 39 | 40 | public boolean isVararg() { 41 | return vararg; 42 | } 43 | 44 | public Location location() { 45 | return location; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /net/loveruby/cflat/entity/Params.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.entity; 2 | import net.loveruby.cflat.type.TypeRef; 3 | import net.loveruby.cflat.type.ParamTypeRefs; 4 | import net.loveruby.cflat.ast.Location; 5 | import java.util.List; 6 | import java.util.ArrayList; 7 | 8 | public class Params extends ParamSlots 9 | implements net.loveruby.cflat.ast.Dumpable { 10 | public Params(Location loc, List paramDescs) { 11 | super(loc, paramDescs, false); 12 | } 13 | 14 | public List parameters() { 15 | return paramDescriptors; 16 | } 17 | 18 | public ParamTypeRefs parametersTypeRef() { 19 | List typerefs = new ArrayList(); 20 | for (CBCParameter param : paramDescriptors) { 21 | typerefs.add(param.typeNode().typeRef()); 22 | } 23 | return new ParamTypeRefs(location, typerefs, vararg); 24 | } 25 | 26 | public boolean equals(Object other) { 27 | return (other instanceof Params) && equals((Params)other); 28 | } 29 | 30 | public boolean equals(Params other) { 31 | return other.vararg == vararg 32 | && other.paramDescriptors.equals(paramDescriptors); 33 | } 34 | 35 | public void dump(net.loveruby.cflat.ast.Dumper d) { 36 | d.printNodeList("parameters", parameters()); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /net/loveruby/cflat/entity/Scope.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.entity; 2 | import net.loveruby.cflat.exception.*; 3 | import java.util.List; 4 | import java.util.ArrayList; 5 | 6 | abstract public class Scope { 7 | protected List children; 8 | 9 | public Scope() { 10 | children = new ArrayList(); 11 | } 12 | 13 | abstract public boolean isToplevel(); 14 | abstract public ToplevelScope toplevel(); 15 | abstract public Scope parent(); 16 | 17 | protected void addChild(LocalScope s) { 18 | children.add(s); 19 | } 20 | 21 | abstract public Entity get(String name) throws SemanticException; 22 | } 23 | -------------------------------------------------------------------------------- /net/loveruby/cflat/entity/UndefinedFunction.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.entity; 2 | import net.loveruby.cflat.ast.TypeNode; 3 | import java.util.List; 4 | 5 | public class UndefinedFunction extends Function { 6 | protected Params params; 7 | 8 | public UndefinedFunction(TypeNode t, String name, Params params) { 9 | super(false, t, name); 10 | this.params = params; 11 | } 12 | 13 | public List parameters() { 14 | return params.parameters(); 15 | } 16 | 17 | public boolean isDefined() { 18 | return false; 19 | } 20 | 21 | protected void _dump(net.loveruby.cflat.ast.Dumper d) { 22 | d.printMember("name", name); 23 | d.printMember("isPrivate", isPrivate()); 24 | d.printMember("typeNode", typeNode); 25 | d.printMember("params", params); 26 | } 27 | 28 | public T accept(EntityVisitor visitor) { 29 | return visitor.visit(this); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /net/loveruby/cflat/entity/UndefinedVariable.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.entity; 2 | import net.loveruby.cflat.ast.TypeNode; 3 | 4 | public class UndefinedVariable extends Variable { 5 | public UndefinedVariable(TypeNode t, String name) { 6 | super(false, t, name); 7 | } 8 | 9 | public boolean isDefined() { return false; } 10 | public boolean isPrivate() { return false; } 11 | public boolean isInitialized() { return false; } 12 | 13 | protected void _dump(net.loveruby.cflat.ast.Dumper d) { 14 | d.printMember("name", name); 15 | d.printMember("isPrivate", isPrivate()); 16 | d.printMember("typeNode", typeNode); 17 | } 18 | 19 | public T accept(EntityVisitor visitor) { 20 | return visitor.visit(this); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /net/loveruby/cflat/entity/Variable.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.entity; 2 | import net.loveruby.cflat.ast.TypeNode; 3 | import net.loveruby.cflat.type.*; 4 | 5 | abstract public class Variable extends Entity { 6 | public Variable(boolean priv, TypeNode type, String name) { 7 | super(priv, type, name); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /net/loveruby/cflat/exception/CompileException.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.exception; 2 | 3 | public class CompileException extends Exception { 4 | public CompileException(String msg) { 5 | super(msg); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /net/loveruby/cflat/exception/FileException.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.exception; 2 | 3 | public class FileException extends CompileException { 4 | public FileException(String msg) { 5 | super(msg); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /net/loveruby/cflat/exception/IPCException.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.exception; 2 | 3 | public class IPCException extends CompileException { 4 | public IPCException(String msg) { 5 | super(msg); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /net/loveruby/cflat/exception/JumpError.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.exception; 2 | 3 | public class JumpError extends SemanticError { 4 | public JumpError(String msg) { 5 | super(msg); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /net/loveruby/cflat/exception/OptionParseError.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.exception; 2 | 3 | public class OptionParseError extends Error { 4 | public OptionParseError(String msg) { 5 | super(msg); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /net/loveruby/cflat/exception/SemanticError.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.exception; 2 | 3 | public class SemanticError extends Error { 4 | public SemanticError(String msg) { 5 | super(msg); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /net/loveruby/cflat/exception/SemanticException.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.exception; 2 | 3 | public class SemanticException extends CompileException { 4 | public SemanticException(String msg) { 5 | super(msg); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /net/loveruby/cflat/exception/SyntaxException.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.exception; 2 | 3 | public class SyntaxException extends CompileException { 4 | public SyntaxException(String msg) { 5 | super(msg); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ir/Addr.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ir; 2 | import net.loveruby.cflat.asm.Type; 3 | import net.loveruby.cflat.asm.Operand; 4 | import net.loveruby.cflat.asm.MemoryReference; 5 | import net.loveruby.cflat.entity.Entity; 6 | 7 | public class Addr extends Expr { 8 | Entity entity; 9 | 10 | public Addr(Type type, Entity entity) { 11 | super(type); 12 | this.entity = entity; 13 | } 14 | 15 | public boolean isAddr() { return true; } 16 | 17 | public Entity entity() { return entity; } 18 | 19 | public Operand address() { 20 | return entity.address(); 21 | } 22 | 23 | public MemoryReference memref() { 24 | return entity.memref(); 25 | } 26 | 27 | public Entity getEntityForce() { 28 | return entity; 29 | } 30 | 31 | public E accept(IRVisitor visitor) { 32 | return visitor.visit(this); 33 | } 34 | 35 | protected void _dump(Dumper d) { 36 | d.printMember("entity", entity.name()); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ir/Assign.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ir; 2 | import net.loveruby.cflat.ast.Location; 3 | 4 | public class Assign extends Stmt { 5 | protected Expr lhs, rhs; 6 | 7 | public Assign(Location loc, Expr lhs, Expr rhs) { 8 | super(loc); 9 | this.lhs = lhs; 10 | this.rhs = rhs; 11 | } 12 | 13 | public Expr lhs() { 14 | return lhs; 15 | } 16 | 17 | public Expr rhs() { 18 | return rhs; 19 | } 20 | 21 | public S accept(IRVisitor visitor) { 22 | return visitor.visit(this); 23 | } 24 | 25 | protected void _dump(Dumper d) { 26 | d.printMember("lhs", lhs); 27 | d.printMember("rhs", rhs); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ir/Bin.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ir; 2 | import net.loveruby.cflat.asm.Type; 3 | 4 | public class Bin extends Expr { 5 | protected Op op; 6 | protected Expr left, right; 7 | 8 | public Bin(Type type, Op op, Expr left, Expr right) { 9 | super(type); 10 | this.op = op; 11 | this.left = left; 12 | this.right = right; 13 | } 14 | 15 | public Expr left() { return left; } 16 | public Expr right() { return right; } 17 | public Op op() { return op; } 18 | 19 | public E accept(IRVisitor visitor) { 20 | return visitor.visit(this); 21 | } 22 | 23 | protected void _dump(Dumper d) { 24 | d.printMember("op", op.toString()); 25 | d.printMember("left", left); 26 | d.printMember("right", right); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ir/CJump.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ir; 2 | import net.loveruby.cflat.ast.Location; 3 | import net.loveruby.cflat.asm.Label; 4 | 5 | public class CJump extends Stmt { 6 | protected Expr cond; 7 | protected Label thenLabel; 8 | protected Label elseLabel; 9 | 10 | public CJump(Location loc, Expr cond, Label thenLabel, Label elseLabel) { 11 | super(loc); 12 | this.cond = cond; 13 | this.thenLabel = thenLabel; 14 | this.elseLabel = elseLabel; 15 | } 16 | 17 | public Expr cond() { 18 | return cond; 19 | } 20 | 21 | public Label thenLabel() { 22 | return thenLabel; 23 | } 24 | 25 | public Label elseLabel() { 26 | return elseLabel; 27 | } 28 | 29 | public S accept(IRVisitor visitor) { 30 | return visitor.visit(this); 31 | } 32 | 33 | protected void _dump(Dumper d) { 34 | d.printMember("cond", cond); 35 | d.printMember("thenLabel", thenLabel); 36 | d.printMember("elseLabel", elseLabel); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ir/Call.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ir; 2 | import net.loveruby.cflat.entity.Function; 3 | import net.loveruby.cflat.entity.Entity; 4 | import net.loveruby.cflat.asm.Type; 5 | import java.util.List; 6 | 7 | public class Call extends Expr { 8 | private Expr expr; 9 | private List args; 10 | 11 | public Call(Type type, Expr expr, List args) { 12 | super(type); 13 | this.expr = expr; 14 | this.args = args; 15 | } 16 | 17 | public Expr expr() { return expr; } 18 | public List args() { return args; } 19 | 20 | public long numArgs() { 21 | return args.size(); 22 | } 23 | 24 | /** Returns true if this funcall is NOT a function pointer call. */ 25 | public boolean isStaticCall() { 26 | return (expr.getEntityForce() instanceof Function); 27 | } 28 | 29 | /** 30 | * Returns a function object which is refered by expression. 31 | * This method expects this is static function call (isStaticCall()). 32 | */ 33 | public Function function() { 34 | Entity ent = expr.getEntityForce(); 35 | if (ent == null) { 36 | throw new Error("not a static funcall"); 37 | } 38 | return (Function)ent; 39 | } 40 | 41 | public E accept(IRVisitor visitor) { 42 | return visitor.visit(this); 43 | } 44 | 45 | protected void _dump(Dumper d) { 46 | d.printMember("expr", expr); 47 | d.printMembers("args", args); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ir/Case.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ir; 2 | import net.loveruby.cflat.asm.Label; 3 | 4 | public class Case implements Dumpable { 5 | public long value; 6 | public Label label; 7 | 8 | public Case(long value, Label label) { 9 | this.value = value; 10 | this.label = label; 11 | } 12 | 13 | public void dump(Dumper d) { 14 | d.printClass(this); 15 | d.printMember("value", value); 16 | d.printMember("label", label); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ir/Dumpable.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ir; 2 | 3 | public interface Dumpable { 4 | void dump(Dumper d); 5 | } 6 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ir/Expr.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ir; 2 | import net.loveruby.cflat.asm.Type; 3 | import net.loveruby.cflat.asm.Operand; 4 | import net.loveruby.cflat.asm.ImmediateValue; 5 | import net.loveruby.cflat.asm.MemoryReference; 6 | import net.loveruby.cflat.entity.Entity; 7 | 8 | abstract public class Expr implements Dumpable { 9 | final Type type; 10 | 11 | Expr(Type type) { 12 | this.type = type; 13 | } 14 | 15 | public Type type() { return type; } 16 | 17 | public boolean isVar() { return false; } 18 | public boolean isAddr() { return false; } 19 | 20 | public boolean isConstant() { return false; } 21 | 22 | public ImmediateValue asmValue() { 23 | throw new Error("Expr#asmValue called"); 24 | } 25 | 26 | public Operand address() { 27 | throw new Error("Expr#address called"); 28 | } 29 | 30 | public MemoryReference memref() { 31 | throw new Error("Expr#memref called"); 32 | } 33 | 34 | // #@@range/addressNode{ 35 | public Expr addressNode(Type type) { 36 | throw new Error("unexpected node for LHS: " + getClass()); 37 | } 38 | // #@@} 39 | 40 | public Entity getEntityForce() { 41 | return null; 42 | } 43 | 44 | abstract public E accept(IRVisitor visitor); 45 | 46 | public void dump(Dumper d) { 47 | d.printClass(this); 48 | d.printMember("type", type); 49 | _dump(d); 50 | } 51 | 52 | abstract protected void _dump(Dumper d); 53 | } 54 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ir/ExprStmt.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ir; 2 | import net.loveruby.cflat.ast.Location; 3 | 4 | public class ExprStmt extends Stmt { 5 | protected Expr expr; 6 | 7 | public ExprStmt(Location loc, Expr expr) { 8 | super(loc); 9 | this.expr = expr; 10 | } 11 | 12 | public Expr expr() { 13 | return expr; 14 | } 15 | 16 | public S accept(IRVisitor visitor) { 17 | return visitor.visit(this); 18 | } 19 | 20 | protected void _dump(Dumper d) { 21 | d.printMember("expr", expr); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ir/IRVisitor.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ir; 2 | 3 | public interface IRVisitor { 4 | public S visit(ExprStmt s); 5 | public S visit(Assign s); 6 | public S visit(CJump s); 7 | public S visit(Jump s); 8 | public S visit(Switch s); 9 | public S visit(LabelStmt s); 10 | public S visit(Return s); 11 | 12 | public E visit(Uni s); 13 | public E visit(Bin s); 14 | public E visit(Call s); 15 | public E visit(Addr s); 16 | public E visit(Mem s); 17 | public E visit(Var s); 18 | public E visit(Int s); 19 | public E visit(Str s); 20 | } 21 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ir/Int.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ir; 2 | import net.loveruby.cflat.asm.*; 3 | 4 | public class Int extends Expr { 5 | protected long value; 6 | 7 | public Int(Type type, long value) { 8 | super(type); 9 | this.value = value; 10 | } 11 | 12 | public long value() { return value; } 13 | 14 | public boolean isConstant() { return true; } 15 | 16 | public ImmediateValue asmValue() { 17 | return new ImmediateValue(new IntegerLiteral(value)); 18 | } 19 | 20 | public MemoryReference memref() { 21 | throw new Error("must not happen: IntValue#memref"); 22 | } 23 | 24 | public E accept(IRVisitor visitor) { 25 | return visitor.visit(this); 26 | } 27 | 28 | protected void _dump(Dumper d) { 29 | d.printMember("value", value); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ir/Jump.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ir; 2 | import net.loveruby.cflat.ast.Location; 3 | import net.loveruby.cflat.asm.Label; 4 | 5 | public class Jump extends Stmt { 6 | protected Label label; 7 | 8 | public Jump(Location loc, Label label) { 9 | super(loc); 10 | this.label = label; 11 | } 12 | 13 | public Label label() { 14 | return label; 15 | } 16 | 17 | public S accept(IRVisitor visitor) { 18 | return visitor.visit(this); 19 | } 20 | 21 | protected void _dump(Dumper d) { 22 | d.printMember("label", label); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ir/LabelStmt.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ir; 2 | import net.loveruby.cflat.ast.Location; 3 | import net.loveruby.cflat.asm.Label; 4 | 5 | public class LabelStmt extends Stmt { 6 | protected Label label; 7 | 8 | public LabelStmt(Location loc, Label label) { 9 | super(loc); 10 | this.label = label; 11 | } 12 | 13 | public Label label() { 14 | return label; 15 | } 16 | 17 | public S accept(IRVisitor visitor) { 18 | return visitor.visit(this); 19 | } 20 | 21 | protected void _dump(Dumper d) { 22 | d.printMember("label", label); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ir/Mem.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ir; 2 | import net.loveruby.cflat.asm.Type; 3 | 4 | public class Mem extends Expr { 5 | protected Expr expr; 6 | 7 | public Mem(Type type, Expr expr) { 8 | super(type); 9 | this.expr = expr; 10 | } 11 | 12 | public Expr expr() { return expr; } 13 | 14 | public Expr addressNode(Type type) { 15 | return expr; 16 | } 17 | 18 | public E accept(IRVisitor visitor) { 19 | return visitor.visit(this); 20 | } 21 | 22 | protected void _dump(Dumper d) { 23 | d.printMember("expr", expr); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ir/Return.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ir; 2 | import net.loveruby.cflat.ast.Location; 3 | 4 | public class Return extends Stmt { 5 | protected Expr expr; 6 | 7 | public Return(Location loc, Expr expr) { 8 | super(loc); 9 | this.expr = expr; 10 | } 11 | 12 | public Expr expr() { return expr; } 13 | 14 | public S accept(IRVisitor visitor) { 15 | return visitor.visit(this); 16 | } 17 | 18 | protected void _dump(Dumper d) { 19 | d.printMember("expr", expr); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ir/Stmt.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ir; 2 | import net.loveruby.cflat.ast.Location; 3 | 4 | abstract public class Stmt implements Dumpable { 5 | protected Location location; 6 | 7 | public Stmt(Location loc) { 8 | this.location = loc; 9 | } 10 | 11 | abstract public S accept(IRVisitor visitor); 12 | 13 | public Location location() { 14 | return location; 15 | } 16 | 17 | public void dump(Dumper d) { 18 | d.printClass(this, location); 19 | _dump(d); 20 | } 21 | 22 | abstract protected void _dump(Dumper d); 23 | } 24 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ir/Str.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ir; 2 | import net.loveruby.cflat.entity.ConstantEntry; 3 | import net.loveruby.cflat.asm.Type; 4 | import net.loveruby.cflat.asm.Operand; 5 | import net.loveruby.cflat.asm.ImmediateValue; 6 | import net.loveruby.cflat.asm.MemoryReference; 7 | import net.loveruby.cflat.asm.Symbol; 8 | 9 | public class Str extends Expr { 10 | protected ConstantEntry entry; 11 | 12 | public Str(Type type, ConstantEntry entry) { 13 | super(type); 14 | this.entry = entry; 15 | } 16 | 17 | public ConstantEntry entry() { return entry; } 18 | 19 | public Symbol symbol() { 20 | return entry.symbol(); 21 | } 22 | 23 | public boolean isConstant() { return true; } 24 | 25 | public MemoryReference memref() { 26 | return entry.memref(); 27 | } 28 | 29 | public Operand address() { 30 | return entry.address(); 31 | } 32 | 33 | public ImmediateValue asmValue() { 34 | return entry.address(); 35 | } 36 | 37 | public E accept(IRVisitor visitor) { 38 | return visitor.visit(this); 39 | } 40 | 41 | protected void _dump(Dumper d) { 42 | d.printMember("entry", entry.toString()); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ir/Switch.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ir; 2 | import net.loveruby.cflat.ast.Location; 3 | import net.loveruby.cflat.asm.Label; 4 | import java.util.*; 5 | 6 | public class Switch extends Stmt { 7 | protected Expr cond; 8 | protected List cases; 9 | protected Label defaultLabel, endLabel; 10 | 11 | public Switch(Location loc, Expr cond, 12 | List cases, Label defaultLabel, Label endLabel) { 13 | super(loc); 14 | this.cond = cond; 15 | this.cases = cases; 16 | this.defaultLabel = defaultLabel; 17 | this.endLabel = endLabel; 18 | } 19 | 20 | public Expr cond() { 21 | return cond; 22 | } 23 | 24 | public List cases() { 25 | return cases; 26 | } 27 | 28 | public Label defaultLabel() { 29 | return defaultLabel; 30 | } 31 | 32 | public Label endLabel() { 33 | return endLabel; 34 | } 35 | 36 | public S accept(IRVisitor visitor) { 37 | return visitor.visit(this); 38 | } 39 | 40 | protected void _dump(Dumper d) { 41 | d.printMember("cond", cond); 42 | d.printMembers("cases", cases); 43 | d.printMember("defaultLabel", defaultLabel); 44 | d.printMember("endLabel", endLabel); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ir/Uni.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ir; 2 | import net.loveruby.cflat.asm.Type; 3 | 4 | public class Uni extends Expr { 5 | protected Op op; 6 | protected Expr expr; 7 | 8 | public Uni(Type type, Op op, Expr expr) { 9 | super(type); 10 | this.op = op; 11 | this.expr = expr; 12 | } 13 | 14 | public Op op() { return op; } 15 | public Expr expr() { return expr; } 16 | 17 | public E accept(IRVisitor visitor) { 18 | return visitor.visit(this); 19 | } 20 | 21 | protected void _dump(Dumper d) { 22 | d.printMember("op", op.toString()); 23 | d.printMember("expr", expr); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /net/loveruby/cflat/ir/Var.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.ir; 2 | import net.loveruby.cflat.entity.Entity; 3 | import net.loveruby.cflat.asm.Type; 4 | import net.loveruby.cflat.asm.Operand; 5 | import net.loveruby.cflat.asm.MemoryReference; 6 | 7 | public class Var extends Expr { 8 | protected Entity entity; 9 | 10 | public Var(Type type, Entity entity) { 11 | super(type); 12 | this.entity = entity; 13 | } 14 | 15 | public boolean isVar() { return true; } 16 | 17 | public Type type() { 18 | if (super.type() == null) { 19 | throw new Error("Var is too big to load by 1 insn"); 20 | } 21 | return super.type(); 22 | } 23 | 24 | public String name() { return entity.name(); } 25 | public Entity entity() { return entity; } 26 | 27 | public Operand address() { 28 | return entity.address(); 29 | } 30 | 31 | public MemoryReference memref() { 32 | return entity.memref(); 33 | } 34 | 35 | // #@@range/addressNode{ 36 | public Addr addressNode(Type type) { 37 | return new Addr(type, entity); 38 | } 39 | // #@@} 40 | 41 | public Entity getEntityForce() { 42 | return entity; 43 | } 44 | 45 | public E accept(IRVisitor visitor) { 46 | return visitor.visit(this); 47 | } 48 | 49 | protected void _dump(Dumper d) { 50 | d.printMember("entity", entity.name()); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /net/loveruby/cflat/sysdep/Assembler.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.sysdep; 2 | import net.loveruby.cflat.exception.IPCException; 3 | 4 | public interface Assembler { 5 | void assemble(String srcPath, String destPath, 6 | AssemblerOptions opts) throws IPCException; 7 | } 8 | -------------------------------------------------------------------------------- /net/loveruby/cflat/sysdep/AssemblerOptions.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.sysdep; 2 | import java.util.List; 3 | import java.util.ArrayList; 4 | 5 | public class AssemblerOptions { 6 | public boolean verbose = false; 7 | List args = new ArrayList(); 8 | 9 | public void addArg(String a) { 10 | args.add(a); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /net/loveruby/cflat/sysdep/AssemblyCode.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.sysdep; 2 | import java.io.PrintStream; 3 | 4 | public interface AssemblyCode { 5 | String toSource(); 6 | void dump(); 7 | void dump(PrintStream s); 8 | } 9 | -------------------------------------------------------------------------------- /net/loveruby/cflat/sysdep/CodeGenerator.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.sysdep; 2 | 3 | public interface CodeGenerator { 4 | AssemblyCode generate(net.loveruby.cflat.ir.IR ir); 5 | } 6 | -------------------------------------------------------------------------------- /net/loveruby/cflat/sysdep/CodeGeneratorOptions.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.sysdep; 2 | 3 | public class CodeGeneratorOptions { 4 | protected int optimizeLevel; 5 | protected boolean generatePIC; 6 | protected boolean generatePIE; 7 | protected boolean verboseAsm; 8 | 9 | public CodeGeneratorOptions() { 10 | optimizeLevel = 0; 11 | generatePIC = false; 12 | generatePIE = false; 13 | verboseAsm = false; 14 | } 15 | 16 | public void setOptimizationLevel(int level) { 17 | this.optimizeLevel = level; 18 | } 19 | 20 | public int optimizeLevel() { 21 | return optimizeLevel; 22 | } 23 | 24 | public void generateVerboseAsm() { 25 | this.verboseAsm = true; 26 | } 27 | 28 | public boolean isVerboseAsm() { 29 | return verboseAsm; 30 | } 31 | 32 | public boolean isPositionIndependent() { 33 | return generatePIC || generatePIE; 34 | } 35 | 36 | public void generatePIC() { 37 | this.generatePIC = true; 38 | } 39 | 40 | public boolean isPICRequired() { 41 | return generatePIC; 42 | } 43 | 44 | public void generatePIE() { 45 | this.generatePIE = true; 46 | } 47 | 48 | public boolean isPIERequired() { 49 | return generatePIE; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /net/loveruby/cflat/sysdep/GNUAssembler.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.sysdep; 2 | import net.loveruby.cflat.utils.CommandUtils; 3 | import net.loveruby.cflat.utils.ErrorHandler; 4 | import net.loveruby.cflat.exception.IPCException; 5 | import java.util.List; 6 | import java.util.ArrayList; 7 | 8 | class GNUAssembler implements Assembler { 9 | ErrorHandler errorHandler; 10 | 11 | GNUAssembler(ErrorHandler h) { 12 | this.errorHandler = h; 13 | } 14 | 15 | // #@@range/assemble{ 16 | public void assemble(String srcPath, String destPath, 17 | AssemblerOptions opts) throws IPCException { 18 | List cmd = new ArrayList(); 19 | cmd.add("as"); 20 | cmd.addAll(opts.args); 21 | cmd.add("-o"); 22 | cmd.add(destPath); 23 | cmd.add(srcPath); 24 | CommandUtils.invoke(cmd, errorHandler, opts.verbose); 25 | } 26 | // #@@} 27 | } 28 | -------------------------------------------------------------------------------- /net/loveruby/cflat/sysdep/Linker.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.sysdep; 2 | import net.loveruby.cflat.exception.IPCException; 3 | import java.util.List; 4 | 5 | public interface Linker { 6 | void generateExecutable(List args, String destPath, 7 | LinkerOptions opts) throws IPCException; 8 | void generateSharedLibrary(List args, String destPath, 9 | LinkerOptions opts) throws IPCException; 10 | } 11 | -------------------------------------------------------------------------------- /net/loveruby/cflat/sysdep/LinkerOptions.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.sysdep; 2 | 3 | public class LinkerOptions { 4 | public boolean generatingSharedLibrary = false; 5 | public boolean generatingPIE = false; 6 | public boolean noStartFiles = false; 7 | public boolean noDefaultLibs = false; 8 | public boolean verbose = false; 9 | } 10 | -------------------------------------------------------------------------------- /net/loveruby/cflat/sysdep/Platform.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.sysdep; 2 | import net.loveruby.cflat.type.TypeTable; 3 | import net.loveruby.cflat.utils.ErrorHandler; 4 | 5 | public interface Platform { 6 | TypeTable typeTable(); 7 | CodeGenerator codeGenerator(CodeGeneratorOptions opts, ErrorHandler h); 8 | Assembler assembler(ErrorHandler h); 9 | Linker linker(ErrorHandler h); 10 | } 11 | -------------------------------------------------------------------------------- /net/loveruby/cflat/sysdep/X86Linux.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.sysdep; 2 | import net.loveruby.cflat.utils.ErrorHandler; 3 | import net.loveruby.cflat.type.TypeTable; 4 | import net.loveruby.cflat.asm.Type; 5 | 6 | public class X86Linux implements Platform { 7 | public TypeTable typeTable() { 8 | return TypeTable.ilp32(); 9 | } 10 | 11 | public CodeGenerator codeGenerator( 12 | CodeGeneratorOptions opts, ErrorHandler h) { 13 | return new net.loveruby.cflat.sysdep.x86.CodeGenerator( 14 | opts, naturalType(), h); 15 | } 16 | 17 | private Type naturalType() { 18 | return Type.INT32; 19 | } 20 | 21 | public Assembler assembler(ErrorHandler h) { 22 | return new GNUAssembler(h); 23 | } 24 | 25 | public Linker linker(ErrorHandler h) { 26 | return new GNULinker(h); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /net/loveruby/cflat/sysdep/x86/ELFConstants.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.sysdep.x86; 2 | 3 | public interface ELFConstants { 4 | // Flags 5 | static public final String SectionFlag_allocatable = "a"; 6 | static public final String SectionFlag_writable = "w"; 7 | static public final String SectionFlag_executable = "x"; 8 | static public final String SectionFlag_sectiongroup = "G"; 9 | static public final String SectionFlag_strings = "S"; 10 | static public final String SectionFlag_threadlocalstorage = "T"; 11 | 12 | // argument of "G" flag 13 | static public final String Linkage_linkonce = "comdat"; 14 | 15 | // Types 16 | static public final String SectionType_bits = "@progbits"; 17 | static public final String SectionType_nobits = "@nobits"; 18 | static public final String SectionType_note = "@note"; 19 | 20 | static public final String SymbolType_function = "@function"; 21 | } 22 | -------------------------------------------------------------------------------- /net/loveruby/cflat/sysdep/x86/RegisterClass.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.sysdep.x86; 2 | 3 | enum RegisterClass { 4 | AX, BX, CX, DX, SI, DI, SP, BP; 5 | } 6 | -------------------------------------------------------------------------------- /net/loveruby/cflat/type/ArrayTypeRef.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.type; 2 | 3 | public class ArrayTypeRef extends TypeRef { 4 | protected TypeRef baseType; 5 | protected long length; 6 | static final protected long undefined = -1; 7 | 8 | public ArrayTypeRef(TypeRef baseType) { 9 | super(baseType.location()); 10 | this.baseType = baseType; 11 | this.length = undefined; 12 | } 13 | 14 | public ArrayTypeRef(TypeRef baseType, long length) { 15 | super(baseType.location()); 16 | if (length < 0) throw new Error("negative array length"); 17 | this.baseType = baseType; 18 | this.length = length; 19 | } 20 | 21 | public boolean isArray() { 22 | return true; 23 | } 24 | 25 | public boolean equals(Object other) { 26 | return (other instanceof ArrayTypeRef) && 27 | (length == ((ArrayTypeRef)other).length); 28 | } 29 | 30 | public TypeRef baseType() { 31 | return baseType; 32 | } 33 | 34 | public long length() { 35 | return length; 36 | } 37 | 38 | public boolean isLengthUndefined() { 39 | return (length == undefined); 40 | } 41 | 42 | public String toString() { 43 | return baseType.toString() 44 | + "[" 45 | + (length == undefined ? "" : "" + length) 46 | + "]"; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /net/loveruby/cflat/type/FunctionTypeRef.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.type; 2 | import net.loveruby.cflat.ast.*; 3 | import java.util.*; 4 | 5 | public class FunctionTypeRef extends TypeRef { 6 | protected TypeRef returnType; 7 | protected ParamTypeRefs params; 8 | 9 | public FunctionTypeRef(TypeRef returnType, ParamTypeRefs params) { 10 | super(returnType.location()); 11 | this.returnType = returnType; 12 | this.params = params; 13 | } 14 | 15 | public boolean isFunction() { 16 | return true; 17 | } 18 | 19 | public boolean equals(Object other) { 20 | return (other instanceof FunctionTypeRef) 21 | && equals((FunctionTypeRef)other); 22 | } 23 | 24 | public boolean equals(FunctionTypeRef other) { 25 | return returnType.equals(other.returnType()) 26 | && params.equals(other.params()); 27 | } 28 | 29 | public TypeRef returnType() { 30 | return returnType; 31 | } 32 | 33 | public ParamTypeRefs params() { 34 | return params; 35 | } 36 | 37 | public String toString() { 38 | StringBuffer buf = new StringBuffer(); 39 | buf.append(returnType.toString()); 40 | buf.append(" ("); 41 | String sep = ""; 42 | for (TypeRef ref : this.params.typerefs()) { 43 | buf.append(sep); 44 | buf.append(ref.toString()); 45 | sep = ", "; 46 | } 47 | buf.append(")"); 48 | return buf.toString(); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /net/loveruby/cflat/type/IntegerType.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.type; 2 | 3 | public class IntegerType extends Type { 4 | protected long size; 5 | protected boolean isSigned; 6 | protected String name; 7 | 8 | public IntegerType(long size, boolean isSigned, String name) { 9 | super(); 10 | this.size = size; 11 | this.isSigned = isSigned; 12 | this.name = name; 13 | } 14 | 15 | public boolean isInteger() { return true; } 16 | public boolean isSigned() { return isSigned; } 17 | public boolean isScalar() { return true; } 18 | 19 | public long minValue() { 20 | return isSigned ? (long)-Math.pow(2, size * 8 - 1) : 0; 21 | } 22 | 23 | public long maxValue() { 24 | return isSigned ? (long)Math.pow(2, size * 8 - 1) - 1 25 | : (long)Math.pow(2, size * 8) - 1; 26 | } 27 | 28 | public boolean isInDomain(long i) { 29 | return (minValue() <= i && i <= maxValue()); 30 | } 31 | 32 | // Use default #equals 33 | //public boolean equals(Object other) 34 | 35 | public boolean isSameType(Type other) { 36 | if (! other.isInteger()) return false; 37 | return equals(other.getIntegerType()); 38 | } 39 | 40 | public boolean isCompatible(Type other) { 41 | return (other.isInteger() && size <= other.size()); 42 | } 43 | 44 | public boolean isCastableTo(Type target) { 45 | return (target.isInteger() || target.isPointer()); 46 | } 47 | 48 | public long size() { 49 | return size; 50 | } 51 | 52 | public String toString() { 53 | return name; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /net/loveruby/cflat/type/NamedType.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.type; 2 | import net.loveruby.cflat.ast.Location; 3 | import net.loveruby.cflat.exception.*; 4 | import java.util.*; 5 | 6 | abstract public class NamedType extends Type { 7 | protected String name; 8 | protected Location location; 9 | 10 | public NamedType(String name, Location loc) { 11 | this.name = name; 12 | this.location = loc; 13 | } 14 | 15 | public String name() { 16 | return name; 17 | } 18 | 19 | public Location location() { 20 | return location; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /net/loveruby/cflat/type/ParamTypeRefs.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.type; 2 | import net.loveruby.cflat.entity.ParamSlots; 3 | import net.loveruby.cflat.ast.Location; 4 | import java.util.*; 5 | 6 | public class ParamTypeRefs extends ParamSlots { 7 | public ParamTypeRefs(List paramDescs) { 8 | super(paramDescs); 9 | } 10 | 11 | public ParamTypeRefs(Location loc, List paramDescs, boolean vararg) { 12 | super(loc, paramDescs, vararg); 13 | } 14 | 15 | public List typerefs() { 16 | return paramDescriptors; 17 | } 18 | 19 | public ParamTypes internTypes(TypeTable table) { 20 | List types = new ArrayList(); 21 | for (TypeRef ref : paramDescriptors) { 22 | types.add(table.getParamType(ref)); 23 | } 24 | return new ParamTypes(location, types, vararg); 25 | } 26 | 27 | public boolean equals(Object other) { 28 | return (other instanceof ParamTypeRefs) 29 | && equals((ParamTypeRefs)other); 30 | } 31 | 32 | public boolean equals(ParamTypeRefs other) { 33 | return vararg == other.vararg 34 | && paramDescriptors.equals(other.paramDescriptors); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /net/loveruby/cflat/type/ParamTypes.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.type; 2 | import net.loveruby.cflat.ast.Location; 3 | import net.loveruby.cflat.entity.ParamSlots; 4 | import java.util.*; 5 | 6 | public class ParamTypes extends ParamSlots { 7 | protected ParamTypes(Location loc, List paramDescs, boolean vararg) { 8 | super(loc, paramDescs, vararg); 9 | } 10 | 11 | public List types() { 12 | return paramDescriptors; 13 | } 14 | 15 | public boolean isSameType(ParamTypes other) { 16 | if (vararg != other.vararg) return false; 17 | if (minArgc() != other.minArgc()) return false; 18 | Iterator otherTypes = other.types().iterator(); 19 | for (Type t : paramDescriptors) { 20 | if (! t.isSameType(otherTypes.next())) { 21 | return false; 22 | } 23 | } 24 | return true; 25 | } 26 | 27 | public boolean equals(Object other) { 28 | return (other instanceof ParamTypes) && equals((ParamTypes)other); 29 | } 30 | 31 | public boolean equals(ParamTypes other) { 32 | return vararg == other.vararg 33 | && paramDescriptors.equals(other.paramDescriptors); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /net/loveruby/cflat/type/PointerType.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.type; 2 | 3 | public class PointerType extends Type { 4 | protected long size; 5 | protected Type baseType; 6 | 7 | public PointerType(long size, Type baseType) { 8 | this.size = size; 9 | this.baseType = baseType; 10 | } 11 | 12 | public boolean isPointer() { return true; } 13 | public boolean isScalar() { return true; } 14 | public boolean isSigned() { return false; } 15 | public boolean isCallable() { return baseType.isFunction(); } 16 | 17 | public long size() { 18 | return size; 19 | } 20 | 21 | public Type baseType() { 22 | return baseType; 23 | } 24 | 25 | public boolean equals(Object other) { 26 | if (! (other instanceof PointerType)) return false; 27 | return baseType.equals(((Type)other).getPointerType().baseType); 28 | } 29 | 30 | public boolean isSameType(Type other) { 31 | if (!other.isPointer()) return false; 32 | return baseType.isSameType(other.baseType()); 33 | } 34 | 35 | public boolean isCompatible(Type other) { 36 | if (!other.isPointer()) return false; 37 | if (baseType.isVoid()) { 38 | return true; 39 | } 40 | if (other.baseType().isVoid()) { 41 | return true; 42 | } 43 | return baseType.isCompatible(other.baseType()); 44 | } 45 | 46 | public boolean isCastableTo(Type other) { 47 | return other.isPointer() || other.isInteger(); 48 | } 49 | 50 | public String toString() { 51 | return baseType.toString() + "*"; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /net/loveruby/cflat/type/PointerTypeRef.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.type; 2 | 3 | public class PointerTypeRef extends TypeRef { 4 | protected TypeRef baseType; 5 | 6 | public PointerTypeRef(TypeRef baseType) { 7 | super(baseType.location()); 8 | this.baseType = baseType; 9 | } 10 | 11 | public boolean isPointer() { 12 | return true; 13 | } 14 | 15 | public TypeRef baseType() { 16 | return baseType; 17 | } 18 | 19 | public boolean equals(Object other) { 20 | if (! (other instanceof PointerTypeRef)) return false; 21 | return baseType.equals(((PointerTypeRef)other).baseType); 22 | } 23 | 24 | public String toString() { 25 | return baseType.toString() + "*"; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /net/loveruby/cflat/type/StructType.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.type; 2 | import net.loveruby.cflat.ast.Slot; 3 | import net.loveruby.cflat.ast.Location; 4 | import net.loveruby.cflat.utils.AsmUtils; 5 | import java.util.*; 6 | 7 | public class StructType extends CompositeType { 8 | public StructType(String name, List membs, Location loc) { 9 | super(name, membs, loc); 10 | } 11 | 12 | public boolean isStruct() { return true; } 13 | 14 | public boolean isSameType(Type other) { 15 | if (! other.isStruct()) return false; 16 | return equals(other.getStructType()); 17 | } 18 | 19 | protected void computeOffsets() { 20 | long offset = 0; 21 | long maxAlign = 1; 22 | for (Slot s : members()) { 23 | offset = AsmUtils.align(offset, s.allocSize()); 24 | s.setOffset(offset); 25 | offset += s.allocSize(); 26 | maxAlign = Math.max(maxAlign, s.alignment()); 27 | } 28 | cachedSize = AsmUtils.align(offset, maxAlign); 29 | cachedAlign = maxAlign; 30 | } 31 | 32 | public String toString() { 33 | return "struct " + name; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /net/loveruby/cflat/type/StructTypeRef.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.type; 2 | import net.loveruby.cflat.ast.Location; 3 | 4 | public class StructTypeRef extends TypeRef { 5 | protected String name; 6 | 7 | public StructTypeRef(String name) { 8 | this(null, name); 9 | } 10 | 11 | public StructTypeRef(Location loc, String name) { 12 | super(loc); 13 | this.name = name; 14 | } 15 | 16 | public boolean isStruct() { 17 | return true; 18 | } 19 | 20 | public boolean equals(Object other) { 21 | if (!(other instanceof StructTypeRef)) return false; 22 | return name.equals(((StructTypeRef)other).name); 23 | } 24 | 25 | public String name() { 26 | return name; 27 | } 28 | 29 | public String toString() { 30 | return "struct " + name; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /net/loveruby/cflat/type/TypeRef.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.type; 2 | import net.loveruby.cflat.ast.Location; 3 | 4 | public abstract class TypeRef { 5 | protected Location location; 6 | 7 | public TypeRef(Location loc) { 8 | this.location = loc; 9 | } 10 | 11 | public Location location() { 12 | return location; 13 | } 14 | 15 | public int hashCode() { 16 | return toString().hashCode(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /net/loveruby/cflat/type/UnionType.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.type; 2 | import net.loveruby.cflat.ast.Slot; 3 | import net.loveruby.cflat.ast.Location; 4 | import net.loveruby.cflat.utils.AsmUtils; 5 | import java.util.*; 6 | 7 | public class UnionType extends CompositeType { 8 | public UnionType(String name, List membs, Location loc) { 9 | super(name, membs, loc); 10 | } 11 | 12 | public boolean isUnion() { return true; } 13 | 14 | public boolean isSameType(Type other) { 15 | if (! other.isUnion()) return false; 16 | return equals(other.getUnionType()); 17 | } 18 | 19 | protected void computeOffsets() { 20 | long maxSize = 0; 21 | long maxAlign = 1; 22 | for (Slot s : members) { 23 | s.setOffset(0); 24 | maxSize = Math.max(maxSize, s.allocSize()); 25 | maxAlign = Math.max(maxAlign, s.alignment()); 26 | } 27 | cachedSize = AsmUtils.align(maxSize, maxAlign); 28 | cachedAlign = maxAlign; 29 | } 30 | 31 | public String toString() { 32 | return "union " + name; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /net/loveruby/cflat/type/UnionTypeRef.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.type; 2 | import net.loveruby.cflat.ast.Location; 3 | 4 | public class UnionTypeRef extends TypeRef { 5 | protected String name; 6 | 7 | public UnionTypeRef(String name) { 8 | this(null, name); 9 | } 10 | 11 | public UnionTypeRef(Location loc, String name) { 12 | super(loc); 13 | this.name = name; 14 | } 15 | 16 | public boolean isUnion() { 17 | return true; 18 | } 19 | 20 | public boolean equals(Object other) { 21 | if (!(other instanceof UnionTypeRef)) return false; 22 | return name.equals(((UnionTypeRef)other).name); 23 | } 24 | 25 | public String name() { 26 | return name; 27 | } 28 | 29 | public String toString() { 30 | return "union " + name; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /net/loveruby/cflat/type/UserTypeRef.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.type; 2 | import net.loveruby.cflat.ast.Location; 3 | 4 | public class UserTypeRef extends TypeRef { 5 | protected String name; 6 | 7 | public UserTypeRef(String name) { 8 | this(null, name); 9 | } 10 | 11 | public UserTypeRef(Location loc, String name) { 12 | super(loc); 13 | this.name = name; 14 | } 15 | 16 | public boolean isUserType() { 17 | return true; 18 | } 19 | 20 | public String name() { 21 | return name; 22 | } 23 | 24 | public boolean equals(Object other) { 25 | if (!(other instanceof UserTypeRef)) return false; 26 | return name.equals(((UserTypeRef)other).name); 27 | } 28 | 29 | public String toString() { 30 | return name; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /net/loveruby/cflat/type/VoidType.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.type; 2 | 3 | public class VoidType extends Type { 4 | public VoidType() { 5 | } 6 | 7 | public boolean isVoid() { return true; } 8 | 9 | public long size() { 10 | return 1; 11 | } 12 | 13 | public boolean equals(Object other) { 14 | return (other instanceof VoidType); 15 | } 16 | 17 | public boolean isSameType(Type other) { 18 | return other.isVoid(); 19 | } 20 | 21 | public boolean isCompatible(Type other) { 22 | return other.isVoid(); 23 | } 24 | 25 | public boolean isCastableTo(Type other) { 26 | return other.isVoid(); 27 | } 28 | 29 | public String toString() { 30 | return "void"; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /net/loveruby/cflat/type/VoidTypeRef.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.type; 2 | import net.loveruby.cflat.ast.Location; 3 | 4 | public class VoidTypeRef extends TypeRef { 5 | public VoidTypeRef() { 6 | super(null); 7 | } 8 | 9 | public VoidTypeRef(Location loc) { 10 | super(loc); 11 | } 12 | 13 | public boolean isVoid() { 14 | return true; 15 | } 16 | 17 | public boolean equals(Object other) { 18 | return (other instanceof VoidTypeRef); 19 | } 20 | 21 | public String toString() { 22 | return "void"; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /net/loveruby/cflat/utils/AsmUtils.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.utils; 2 | 3 | public final class AsmUtils { 4 | private AsmUtils() {} 5 | 6 | // #@@range/align{ 7 | static public long align(long n, long alignment) { 8 | return (n + alignment - 1) / alignment * alignment; 9 | } 10 | // #@@} 11 | } 12 | -------------------------------------------------------------------------------- /net/loveruby/cflat/utils/Cursor.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.utils; 2 | import java.util.*; 3 | 4 | public class Cursor implements Iterator { 5 | protected List list; 6 | protected int index; 7 | 8 | public Cursor(List list) { 9 | this(list, 0); 10 | } 11 | 12 | protected Cursor(List list, int index) { 13 | this.list = list; 14 | this.index = index; 15 | } 16 | 17 | public Cursor clone() { 18 | return new Cursor(list, index); 19 | } 20 | 21 | public boolean hasNext() { 22 | return index < list.size(); 23 | } 24 | 25 | public T next() { 26 | return list.get(index++); 27 | } 28 | 29 | public T current() { 30 | if (index == 0) { 31 | throw new Error("must not happen: Cursor#current"); 32 | } 33 | return list.get(index - 1); 34 | } 35 | 36 | public void remove() { 37 | list.remove(index); 38 | } 39 | 40 | public String toString() { 41 | return "#"; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /net/loveruby/cflat/utils/ErrorHandler.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.utils; 2 | import net.loveruby.cflat.ast.Location; 3 | import java.io.*; 4 | 5 | public class ErrorHandler { 6 | protected String programId; 7 | protected PrintStream stream; 8 | protected long nError; 9 | protected long nWarning; 10 | 11 | public ErrorHandler(String progid) { 12 | programId = progid; 13 | stream = System.err; 14 | } 15 | 16 | public ErrorHandler(String progid, OutputStream stream) { 17 | programId = progid; 18 | this.stream = new PrintStream(stream); 19 | } 20 | 21 | public void error(Location loc, String msg) { 22 | error(loc.toString() + ": " + msg); 23 | } 24 | 25 | public void error(String msg) { 26 | stream.println(programId + ": error: " + msg); 27 | nError++; 28 | } 29 | 30 | public void warn(Location loc, String msg) { 31 | warn(loc.toString() + ": " + msg); 32 | } 33 | 34 | public void warn(String msg) { 35 | stream.println(programId + ": warning: " + msg); 36 | nWarning++; 37 | } 38 | 39 | public boolean errorOccured() { 40 | return (nError > 0); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /net/loveruby/cflat/utils/ListUtils.java: -------------------------------------------------------------------------------- 1 | package net.loveruby.cflat.utils; 2 | import java.util.List; 3 | import java.util.ListIterator; 4 | import java.util.ArrayList; 5 | 6 | public abstract class ListUtils { 7 | static public List reverse(List list) { 8 | List result = new ArrayList(list.size()); 9 | ListIterator it = list.listIterator(list.size()); 10 | while (it.hasPrevious()) { 11 | result.add(it.previous()); 12 | } 13 | return result; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /test/Makefile: -------------------------------------------------------------------------------- 1 | ANT = ant 2 | CBC = ../bin/cbc 3 | CBFLAGS = 4 | 5 | .SUFFIXES: 6 | .SUFFIXES: .cb . 7 | 8 | .cb: 9 | $(CBC) $(CBFLAGS) $< 10 | 11 | default: compile 12 | 13 | test: 14 | ./run.sh 15 | 16 | compile: 17 | cd .. && $(ANT) compile 18 | 19 | recompile: 20 | cd .. && $(ANT) recompile 21 | 22 | comptest: recompile test 23 | 24 | clean: 25 | rm -f a.out *.s *.o tc.* `cat TARGETS` 26 | -------------------------------------------------------------------------------- /test/add.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | static int g = 3; 4 | static int c; 5 | 6 | int 7 | main(int argc, char **argv) 8 | { 9 | int i; 10 | int j = 0; 11 | 12 | printf("%d", 1 + 0); 13 | printf(";%d", 2 + j); 14 | i = 2; 15 | j = 1; 16 | printf(";%d", i + j); 17 | printf(";%d", j + g); 18 | printf(";%d", i + g); 19 | printf(";%d", f(5)); // 6 20 | printf(";%d", f(5) + 1); 21 | printf(";%d", f(5) + i); // 8 22 | c = 5; 23 | printf(";%d", f(3) + c); 24 | i = 9; 25 | printf(";%d", f(i)); 26 | j = 1; 27 | printf(";%d", f(i) + j); 28 | puts(""); 29 | return 0; 30 | } 31 | 32 | int 33 | f(int i) 34 | { 35 | return i + 1; 36 | } 37 | -------------------------------------------------------------------------------- /test/addressof.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | import string; 3 | 4 | struct s { 5 | char[8] str; 6 | }; 7 | 8 | int 9 | main(int argc, char** argv) 10 | { 11 | struct s s; 12 | struct s * sp; 13 | char *str; 14 | 15 | str = s.str; 16 | strcpy(str, "OK"); 17 | printf("%s", str); 18 | 19 | str = &s.str; 20 | strcpy(str, "OK"); 21 | printf(";%s", str); 22 | 23 | sp = &s; 24 | str = sp->str; 25 | strcpy(str, "OK"); 26 | printf(";%s", str); 27 | 28 | sp = &s; 29 | str = &sp->str; 30 | strcpy(str, "OK"); 31 | printf(";%s", str); 32 | 33 | puts(""); 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /test/alloca.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | import string; 3 | import alloca; 4 | 5 | int 6 | main(void) 7 | { 8 | char* p = alloca(32); 9 | strcpy(p, "Hello"); 10 | printf("<<%s>>\n", p); 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /test/alloca2.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | import string; 3 | import alloca; 4 | 5 | int 6 | main(int argc, char **argv) 7 | { 8 | fa(); 9 | puts(""); 10 | return 0; 11 | } 12 | 13 | static int 14 | fa(void) 15 | { 16 | int[10] junk; 17 | int x = 4 * 4 - 13; 18 | char* s = alloca(10); 19 | 20 | fb(); 21 | strcpy(s, ";%d"); 22 | printf(s, 14 + x); 23 | } 24 | 25 | static int 26 | fb(void) 27 | { 28 | int[10] junk; 29 | int x = (61 - 1) / 4; 30 | char* s = alloca(15); 31 | x += 4; 32 | 33 | fc(); 34 | strcpy(s, ";%d"); 35 | printf(s, x - 2); 36 | } 37 | 38 | static int 39 | fc(void) 40 | { 41 | int[10] junk; 42 | int x = 4 * 4; 43 | char* s = alloca(20); 44 | x--; 45 | 46 | fd(); 47 | strcpy(s, ";%d"); 48 | printf(s, x + 2); 49 | } 50 | 51 | static int 52 | fd(void) 53 | { 54 | int[10] junk; 55 | int x = 88 / 4; 56 | char* s = alloca(25); 57 | 58 | strcpy(s, "%d"); 59 | printf(s, -5 + x); 60 | } 61 | -------------------------------------------------------------------------------- /test/aref-semcheck.cb: -------------------------------------------------------------------------------- 1 | int main(int argc, char **argv) { return 1[0]; } 2 | -------------------------------------------------------------------------------- /test/aref-semcheck2.cb: -------------------------------------------------------------------------------- 1 | void f(void) { 2 | 1[0][0]; 3 | 1[0].memb; 4 | 1[0]->memb; 5 | *(1[0]); 6 | 1[0](); 7 | &(1[0]); 8 | } 9 | -------------------------------------------------------------------------------- /test/array-semcheck1.cb: -------------------------------------------------------------------------------- 1 | int main(int argc, char **argv) { void[1] ary; return 0; } 2 | -------------------------------------------------------------------------------- /test/array.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int[5] a; 7 | 8 | a[0] = 1; 9 | a[1] = 3; 10 | a[2] = 5; 11 | a[3] = 7; 12 | a[4] = 9; 13 | printf("%d;%d;%d\n", a[0], a[2], a[4]); 14 | //printf("%d\n", a[0]); 15 | //printf("%d\n", a[2]); 16 | //printf("%d\n", a[4]); 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /test/array2.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int[1] a; 7 | a[0] = 0; 8 | f(a); 9 | return 0; 10 | } 11 | 12 | void 13 | f(int[] x) 14 | { 15 | int save = *x; 16 | int i = 0; 17 | x = &i; 18 | printf("%d;%d;%d\n", save, x[0], *x); 19 | } 20 | -------------------------------------------------------------------------------- /test/assoc.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | printf("%d\n", 5 - 1 - 1); 7 | return 0; 8 | } 9 | -------------------------------------------------------------------------------- /test/bitand.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | printf("%d;%d;%d;%d;%d", 7 & 0, 7 & 1, 7 & 2, 7 & 3, 7 & 4); 7 | puts(""); 8 | return 0; 9 | } 10 | -------------------------------------------------------------------------------- /test/bitnot.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | printf("%d;%d;%d", ~0, ~1, ~(-1)); 7 | puts(""); 8 | return 0; 9 | } 10 | -------------------------------------------------------------------------------- /test/bitor.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | printf("%d;%d;%d;%d;%d;%d", 0|0, 0|1, 0|2, 1|2, 2|2, 2|4); 7 | printf(";%d", (0 | 2) * 4); 8 | printf(";%d", 5 * (0 | 2)); 9 | puts(""); 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /test/bitxor.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | printf("%d;%d;%d;%d;%d", 0 ^ 1, 0 ^ 2, 1 ^ 1, 2 ^ 2, 3 ^ 1); 7 | puts(""); 8 | return 0; 9 | } 10 | -------------------------------------------------------------------------------- /test/block.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int *addr1; 7 | int *addr2; 8 | 9 | int i = 1; 10 | printf("%d", i); 11 | { 12 | int i = 2; 13 | printf(";%d", i); 14 | addr1 = &i; 15 | } 16 | { 17 | int i = 3; 18 | printf(";%d", i); 19 | addr2 = &i; 20 | } 21 | printf(";%d", i); 22 | printf(";%s", addr1 == addr2 ? "OK" : "NG"); 23 | 24 | puts(""); 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /test/break-semcheck.cb: -------------------------------------------------------------------------------- 1 | int 2 | main(int argc, char **argv) { 3 | break; 4 | return 0; 5 | } 6 | -------------------------------------------------------------------------------- /test/cast.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | short n = 5000; 7 | char a = 1; 8 | char b = -1; 9 | short c = 1; 10 | short d = -1; 11 | 12 | printf("%ld", ((long)n * (long)n)); 13 | printf(";%d", (int)a); 14 | printf(";%ld", (long)a); 15 | printf(";%d", (int)b); 16 | printf(";%ld", (long)b); 17 | printf(";%d", (int)c); 18 | printf(";%ld", (long)c); 19 | printf(";%d", (int)d); 20 | printf(";%ld", (long)d); 21 | 22 | puts(""); 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /test/cast2.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int i = 777; 7 | int* ptr = &i; 8 | 9 | long x = 666; 10 | long* lp = &x; 11 | 12 | printf("%d;%d\n", *(int*)ptr, *(int*)lp); 13 | 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /test/charops.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | char i = 1; 7 | 8 | i <<= 1; 9 | printf("%hhd", i); 10 | i <<= 5; 11 | printf(";%hhd", i); 12 | i <<= 1; 13 | printf(";%hhd", i); 14 | i <<= 1; 15 | printf(";%hhd", i); 16 | puts(""); 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /test/charops2.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | char i = -1; 7 | 8 | i <<= 1; 9 | printf("%hhd", i); 10 | i <<= 5; 11 | printf(";%hhd", i); 12 | i <<= 1; 13 | printf(";%hhd", i); 14 | i <<= 1; 15 | printf(";%hhd", i); 16 | puts(""); 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /test/comm.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int global_int; 4 | char *global_string; 5 | 6 | int 7 | main(int argc, char **argv) 8 | { 9 | global_int = 1; 10 | printf("%d", global_int); 11 | global_int = 2; 12 | printf(";%d", global_int); 13 | 14 | global_string = "OK"; 15 | printf(";%s", global_string); 16 | global_string = "NEW"; 17 | printf(";%s", global_string); 18 | 19 | puts(""); 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /test/condexpr.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | printf("%s", 1 ? "OK" : "NG"); 7 | printf(";%s", 0 ? "NG" : "OK"); 8 | printf(";%s", 0==0 ? "OK" : "NG"); 9 | printf(";%s", 0==1 ? "NG" : "OK"); 10 | printf(";%s", 0==1 ? NULL : "OK"); 11 | puts(""); 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /test/const.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | const int RTLD_LAZY = 0x10; 4 | const char* MSG = "msgstring"; 5 | 6 | int main(int argc, char** argv) 7 | { 8 | printf("%d", RTLD_LAZY); 9 | printf(";%d", RTLD_LAZY); 10 | printf(";%d", RTLD_LAZY); 11 | printf(";%s", MSG); 12 | puts(""); 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /test/continue-semcheck.cb: -------------------------------------------------------------------------------- 1 | int 2 | main(int argc, char **argv) { 3 | continue; 4 | return 0; 5 | } 6 | -------------------------------------------------------------------------------- /test/dec.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int i = 4; 7 | int j; 8 | 9 | printf("%d", i); // 4 10 | --i; 11 | printf(";%d", i); // 3 12 | j = --i; 13 | printf(";%d", j); // 2 14 | printf(";%d", i); // 2 15 | i--; 16 | printf(";%d", i); // 1 17 | j = i--; 18 | printf(";%d", j); // 1 19 | printf(";%d", i); // 0 20 | puts(""); 21 | 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /test/decloverride.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | import decloverride; 3 | 4 | int f(void) { return 77; } 5 | 6 | int 7 | main(void) 8 | { 9 | printf("%d\n", f()); 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /test/decloverride.hb: -------------------------------------------------------------------------------- 1 | extern int f(void); 2 | -------------------------------------------------------------------------------- /test/decloverride2.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | import decloverride2; 3 | 4 | int f(void) { return 77; } 5 | 6 | int 7 | main(void) 8 | { 9 | printf("%d\n", f()); 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /test/decloverride2.hb: -------------------------------------------------------------------------------- 1 | extern int f(void); 2 | extern int f(void); 3 | -------------------------------------------------------------------------------- /test/defun-semcheck.cb: -------------------------------------------------------------------------------- 1 | void f(int a, int a) {} 2 | -------------------------------------------------------------------------------- /test/defun-semcheck2.cb: -------------------------------------------------------------------------------- 1 | void f(void) { return 1; } 2 | -------------------------------------------------------------------------------- /test/defun-semcheck3.cb: -------------------------------------------------------------------------------- 1 | int f(void) { return; } 2 | -------------------------------------------------------------------------------- /test/defun-semcheck4.cb: -------------------------------------------------------------------------------- 1 | struct st { int x; }; 2 | struct st f(void) { return; } 3 | -------------------------------------------------------------------------------- /test/defun-semcheck5.cb: -------------------------------------------------------------------------------- 1 | union u { int x; }; 2 | union u f(void) { return 1; } 3 | -------------------------------------------------------------------------------- /test/defun-semcheck6.cb: -------------------------------------------------------------------------------- 1 | union u { int x; }; 2 | typedef union u mytype; 3 | mytype g(void) { return 1; } 4 | -------------------------------------------------------------------------------- /test/defun-semcheck7.cb: -------------------------------------------------------------------------------- 1 | struct s { int x; }; 2 | typedef struct s mytype; 3 | mytype f(void) { return 1; } 4 | -------------------------------------------------------------------------------- /test/defun-semcheck8.cb: -------------------------------------------------------------------------------- 1 | int[2] f(void) { return 1; } 2 | -------------------------------------------------------------------------------- /test/defvar.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int main(void) 4 | { 5 | int x = 7, y = 2, z; 6 | z = 3; 7 | x = 1; 8 | printf("%d;%d;%d\n", x, y, z); 9 | return 0; 10 | } 11 | -------------------------------------------------------------------------------- /test/deref-semcheck1.cb: -------------------------------------------------------------------------------- 1 | int main(int argc, char **argv) { return *1; } 2 | -------------------------------------------------------------------------------- /test/deref-semcheck2.cb: -------------------------------------------------------------------------------- 1 | int main(int argc, char **argv) { return *'c'; } 2 | -------------------------------------------------------------------------------- /test/deref-semcheck3.cb: -------------------------------------------------------------------------------- 1 | struct st { int x; }; 2 | 3 | int main(int argc, char **argv) { 4 | struct st s; 5 | return *s; 6 | } 7 | -------------------------------------------------------------------------------- /test/deref-semcheck4.cb: -------------------------------------------------------------------------------- 1 | int main(int argc, char **argv) { return 1->memb; } 2 | -------------------------------------------------------------------------------- /test/deref-semcheck5.cb: -------------------------------------------------------------------------------- 1 | struct st { int x; }; 2 | 3 | int main(int argc, char **argv) { 4 | struct st s; 5 | struct st *ptr = &s; 6 | ptr->x = 0; 7 | return ptr->y; 8 | } 9 | -------------------------------------------------------------------------------- /test/div.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int[4] a; 7 | 8 | printf("%d;%d;%d;%d", 1 / 1, 2 / 1, 4 / 2, 5 / 2); 9 | 10 | a[0] = 16; 11 | a[0] /= 1 + 1 * 1 + 1 + 1; 12 | printf(";%d", a[0]); 13 | 14 | puts(""); 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /test/dowhile-break.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | do { 7 | break; 8 | puts("NG"); 9 | } while (1); 10 | puts("OK"); 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /test/dowhile-continue.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int i = 3; 7 | 8 | do { 9 | i--; 10 | continue; 11 | puts("NG"); 12 | } while (i); 13 | puts("OK"); 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /test/dowhile1.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | do { 7 | puts("OK"); 8 | } 9 | while (0); 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /test/dowhile2.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | do { 7 | puts("OK"); 8 | return 0; 9 | } 10 | while (1); 11 | puts("NG"); 12 | return 1; 13 | } 14 | -------------------------------------------------------------------------------- /test/dowhile3.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int i = 3; 7 | 8 | printf("%d", i); 9 | do { 10 | printf(";%d", i); 11 | i--; 12 | } while (i); 13 | printf(";%d\n", i); 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /test/duplicated-import.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | import string; 3 | 4 | int 5 | main(int argc, char **argv) 6 | { 7 | puts("OK"); 8 | return 0; 9 | } 10 | -------------------------------------------------------------------------------- /test/empstruct.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | struct s {}; 4 | 5 | int 6 | main(int argc, char **argv) 7 | { 8 | struct s st; 9 | struct s* p = &st; 10 | 11 | printf("%p\n", p); 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /test/eq.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | char *s = "OK"; 7 | char *t = "??"; 8 | 9 | printf("%d;%d;%d", (5 == 3), (5 == 5), (3 == 5)); 10 | printf(";%d;%d;%d", (s == t), (s == s), (t == s)); 11 | puts(""); 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /test/for-break.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int i; 7 | 8 | for (i = 1; i; i--) { 9 | break; 10 | puts("NG"); 11 | } 12 | puts("OK"); 13 | 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /test/for-continue.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int i; 7 | 8 | for (i = 3; i; i--) { 9 | continue; 10 | puts("NG"); 11 | } 12 | puts("OK"); 13 | 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /test/for1.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int i = 3; 7 | 8 | printf("%d", i); 9 | for (i = 3; i; i--) { 10 | printf(";%d", i); 11 | } 12 | printf(";%d\n", i); 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /test/fork.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | import unistd; 3 | 4 | int 5 | main(int argc, char **argv) 6 | { 7 | if (fork()) { 8 | printf("parent: pid=%d ppid=%d\n", getpid(), getppid()); 9 | } 10 | else { 11 | printf("child : pid=%d ppid=%d\n", getpid(), getppid()); 12 | } 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /test/funcall-semcheck.cb: -------------------------------------------------------------------------------- 1 | int 2 | main(int argc, char **argv) 3 | { 4 | f(); 5 | return 0; 6 | } 7 | -------------------------------------------------------------------------------- /test/funcall-semcheck2.cb: -------------------------------------------------------------------------------- 1 | int main(int argc, char **argv) { return 1(); } 2 | -------------------------------------------------------------------------------- /test/funcall0.cb: -------------------------------------------------------------------------------- 1 | int 2 | main(int argc, char **argv) 3 | { 4 | return f(); 5 | } 6 | 7 | int 8 | f(void) 9 | { 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /test/funcall1.cb: -------------------------------------------------------------------------------- 1 | int 2 | main(int argc, char **argv) 3 | { 4 | return f(0); 5 | } 6 | 7 | int 8 | f(int i) 9 | { 10 | return i; 11 | } 12 | -------------------------------------------------------------------------------- /test/funcall2.cb: -------------------------------------------------------------------------------- 1 | int 2 | main(int argc, char **argv) 3 | { 4 | return f(999, 0); 5 | } 6 | 7 | int 8 | f(int i, int j) 9 | { 10 | return j; 11 | } 12 | -------------------------------------------------------------------------------- /test/funcall3.cb: -------------------------------------------------------------------------------- 1 | int 2 | main(int argc, char **argv) 3 | { 4 | return f(998, 999, 0); 5 | } 6 | 7 | int 8 | f(int i, int j, int k) 9 | { 10 | return k; 11 | } 12 | -------------------------------------------------------------------------------- /test/funcall4.cb: -------------------------------------------------------------------------------- 1 | int f(int i, int j) { return j; } 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | return f(2, 1) - 1; 7 | } 8 | -------------------------------------------------------------------------------- /test/funcall5.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | printf("%d", 7 | 1); 8 | printf(";%d;%d", 9 | 2, 3); 10 | printf(";%d;%d;%d", 11 | 4, 5, 6); 12 | printf(";%d;%d;%d;%d", 13 | 7, 8, 9, 10); // 4 14 | printf(";%d;%d;%d;%d;%d", 15 | 11, 12, 13, 14, 15); 16 | printf(";%d;%d;%d;%d;%d;%d", 17 | 16, 17, 18, 19, 20, 21); 18 | printf(";%d;%d;%d;%d;%d;%d;%d", 19 | 22, 23, 24, 25, 26, 27, 28); 20 | printf(";%d;%d;%d;%d;%d;%d;%d;%d", 21 | 29, 30, 31, 32, 33, 34, 35, 36); 22 | printf(";%d;%d;%d;%d;%d;%d;%d;%d;%d", 23 | 37, 38, 39, 40, 41, 42, 43, 44, 45); 24 | printf(";%d;%d;%d;%d;%d;%d;%d;%d;%d;%d", 25 | 46, 47, 48, 49, 50, 51, 52, 53, 54, 55); 26 | puts(""); 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /test/funcptr.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char** argv) 5 | { 6 | int (char*, ...)* f; 7 | 8 | f = printf; 9 | f("OK"); 10 | 11 | f = &printf; 12 | f(";OK"); 13 | 14 | f = myputs; 15 | f(";OK"); 16 | 17 | f = &myputs; 18 | f(";OK"); 19 | 20 | puts(""); 21 | return 0; 22 | } 23 | 24 | static int 25 | myputs(char *s, ...) 26 | { 27 | return printf("%s", s); 28 | } 29 | -------------------------------------------------------------------------------- /test/gt.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | printf("%d;%d;%d", (5 > 3), (5 > 5), (3 > 5)); 7 | puts(""); 8 | return 0; 9 | } 10 | -------------------------------------------------------------------------------- /test/gteq.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | printf("%d;%d;%d", (5 >= 3), (5 >= 5), (3 >= 5)); 7 | puts(""); 8 | return 0; 9 | } 10 | -------------------------------------------------------------------------------- /test/gvar.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int global_int = 1; 4 | char *global_string = "OK"; 5 | 6 | int 7 | main(int argc, char **argv) 8 | { 9 | printf("%d", global_int); 10 | global_int = 2; 11 | printf(";%d", global_int); 12 | 13 | printf(";%s", global_string); 14 | global_string = "NEW"; 15 | printf(";%s", global_string); 16 | 17 | puts(""); 18 | 19 | stdin = NULL; 20 | 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /test/hello.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | printf("Hello, World!\n"); 7 | return 0; 8 | } 9 | -------------------------------------------------------------------------------- /test/hello2.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | puts("Hello, World!"); 7 | return 0; 8 | } 9 | -------------------------------------------------------------------------------- /test/hello3.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | printf("%s\n", "Hello, World!"); 7 | return 0; 8 | } 9 | -------------------------------------------------------------------------------- /test/hello4.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | printf("Hell"); 7 | printf("o, Wor"); 8 | printf("ld!\n"); 9 | return 0; 10 | } 11 | -------------------------------------------------------------------------------- /test/if1.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | if (2) { 7 | puts("OK"); 8 | } 9 | else { 10 | puts("NG"); 11 | } 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /test/if2.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | if (2) { puts("OK"); } 7 | return 0; 8 | } 9 | -------------------------------------------------------------------------------- /test/implicitaddr.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char** argv) 5 | { 6 | void *p = &printf; 7 | 8 | check(printf, p); 9 | check(*printf, p); 10 | check(**printf, p); 11 | check(***printf, p); 12 | check(****printf, p); 13 | puts(""); 14 | return 0; 15 | } 16 | 17 | static void 18 | check(void* f, void* p) 19 | { 20 | if (f == p) { 21 | printf(";OK"); 22 | } 23 | else { 24 | printf(";NG"); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /test/inc.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int i = 0; 7 | int j; 8 | 9 | printf("%d", i); // 0 10 | ++i; 11 | printf(";%d", i); // 1 12 | j = ++i; 13 | printf(";%d", j); // 2 14 | printf(";%d", i); // 2 15 | i++; 16 | printf(";%d", i); // 3 17 | j = i++; 18 | printf(";%d", j); // 3 19 | printf(";%d", i); // 4 20 | printf(";%d", inc(i)); // 5 21 | printf(";%d", inc(i)); // 5 22 | puts(""); 23 | 24 | return 0; 25 | } 26 | 27 | static int 28 | inc(int i) 29 | { 30 | return ++i; 31 | } 32 | -------------------------------------------------------------------------------- /test/initializer.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int i = 4; 7 | int x = i * 5 * i; 8 | int y = (x - x) * x; 9 | int z = printf("%d;%d;%d", i, x, y); 10 | char *s = "local"; 11 | printf(";%s", s); 12 | puts(""); 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /test/integer.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | printf("%d;%d;%d", 0, 00, 0x0); 7 | printf(";%d;%d;%d", 1, 01, 0x1); 8 | printf(";%d;%d;%d", 9, 011, 0x9); 9 | printf(";%d;%d;%d", 17, 021, 0x11); 10 | puts(""); 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /test/intops.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int i = 1; 7 | 8 | i <<= 1; 9 | printf("%d", i); 10 | i <<= 29; 11 | printf(";%d", i); 12 | i <<= 1; 13 | printf(";%d", i); 14 | i <<= 1; 15 | printf(";%d", i); 16 | puts(""); 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /test/invalidstmt1.cb: -------------------------------------------------------------------------------- 1 | struct st { 2 | int x; 3 | }; 4 | 5 | int 6 | main(void) 7 | { 8 | struct st s; 9 | s; 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /test/invalidstmt2.cb: -------------------------------------------------------------------------------- 1 | union un { 2 | int x; 3 | }; 4 | 5 | int 6 | main(void) 7 | { 8 | union un u; 9 | u; 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /test/logicaland.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | printf("%d;%d;%d;%d", 0&&0, 1&&0, 0&&1, 1&&2); 7 | printf(";%s", ("NG" && "OK")); 8 | puts(""); 9 | return 0; 10 | } 11 | -------------------------------------------------------------------------------- /test/logicalnot.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | printf("%d;%d;%d", !0, !1, !2); 7 | printf(";%d", !"str"); 8 | printf(";%d", !NULL); 9 | puts(""); 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /test/logicalor.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | printf("%d;%d;%d;%d", 0||0, 1||0, 0||1, 1||2); 7 | printf(";%s", NULL || "OK"); 8 | puts(""); 9 | return 0; 10 | } 11 | -------------------------------------------------------------------------------- /test/longops.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | long i = 1; 7 | 8 | printf("%ld", i); 9 | i <<= 1; 10 | printf(";%ld", i); 11 | i <<= 61; 12 | printf(";%ld", i); 13 | i <<= 1; 14 | printf(";%ld", i); 15 | i <<= 1; 16 | printf(";%ld", i); 17 | puts(""); 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /test/lshift.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int i = 1; 7 | printf("%d;%d;%d;%d;%d", i << 0, i << 1, i << 2, i << 3, i << 4); 8 | puts(""); 9 | return 0; 10 | } 11 | -------------------------------------------------------------------------------- /test/lt.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | printf("%d;%d;%d", (5 < 3), (5 < 5), (3 < 5)); 7 | puts(""); 8 | return 0; 9 | } 10 | -------------------------------------------------------------------------------- /test/lteq.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | printf("%d;%d;%d", (5 <= 3), (5 <= 5), (3 <= 5)); 7 | puts(""); 8 | return 0; 9 | } 10 | -------------------------------------------------------------------------------- /test/lvar1.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int i; 7 | 8 | i = 1; printf("%d", i); 9 | i = 2; printf(";%d\n", i); 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /test/lvar2.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int i; 7 | int j = 3; 8 | 9 | i = 1; 10 | printf("%d", i); 11 | i = 2; 12 | printf(";%d", i); 13 | printf(";%d", j); 14 | j = 4; 15 | printf(";%d", j); 16 | i = 5; 17 | printf(";%d", i); 18 | puts(""); 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /test/mdarray.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int[3][3] p; 7 | 8 | p[0][0] = 3; 9 | p[0][1] = 4; 10 | p[0][2] = 5; 11 | p[1][0] = 6; 12 | p[1][1] = 7; 13 | p[1][2] = 8; 14 | p[2][0] = 9; 15 | p[2][1] = 10; 16 | p[2][2] = 11; 17 | 18 | printf("%d;", p[0][0]); 19 | printf("%d;", p[0][1]); 20 | printf("%d;", p[0][2]); 21 | printf("%d;", p[1][0]); 22 | printf("%d;", p[1][1]); 23 | printf("%d;", p[1][2]); 24 | printf("%d;", p[2][0]); 25 | printf("%d;", p[2][1]); 26 | printf("%d;", p[2][2]); 27 | puts(""); 28 | 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /test/mdarray2.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int[3][3] p; 7 | 8 | p[0][0] = 3; 9 | p[0][1] = 4; 10 | p[0][2] = 5; 11 | p[1][0] = 6; 12 | p[1][1] = 7; 13 | p[1][2] = 8; 14 | p[2][0] = 9; 15 | p[2][1] = 10; 16 | p[2][2] = 11; 17 | 18 | printf("%p\n", &p[0][0]); 19 | printf("%p\n", &p[0][1]); 20 | printf("%p\n", &p[0][2]); 21 | printf("%p\n", &p[1][0]); 22 | printf("%p\n", &p[1][1]); 23 | printf("%p\n", &p[1][2]); 24 | printf("%p\n", &p[2][0]); 25 | printf("%p\n", &p[2][1]); 26 | printf("%p\n", &p[2][2]); 27 | 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /test/mod.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | printf("%d;%d;%d;%d;%d\n", 1 % 1, 2 % 2, 3 % 2, 14 % 5, 7 % 8); 7 | return 0; 8 | } 9 | -------------------------------------------------------------------------------- /test/mul.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | printf("%d;%d;%d\n", 1 * 1, 2 * 2, 3 * 5); 7 | return 0; 8 | } 9 | -------------------------------------------------------------------------------- /test/neq.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | char *s = "OK"; 7 | char *t = "??"; 8 | 9 | printf("%d;%d;%d", (5 != 3), (5 != 5), (3 != 5)); 10 | printf(";%d;%d;%d", (s != t), (s != s), (t != s)); 11 | puts(""); 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /test/noreturn.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | f(); 7 | return 0; 8 | } 9 | 10 | static void 11 | f(void) 12 | { 13 | // has no return 14 | } 15 | -------------------------------------------------------------------------------- /test/one.cb: -------------------------------------------------------------------------------- 1 | int 2 | main(int argc, char **argv) 3 | { 4 | return 1; 5 | } 6 | -------------------------------------------------------------------------------- /test/param.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | return f(1); 7 | } 8 | 9 | int 10 | f(int i) 11 | { 12 | printf("%d", i); 13 | i = 2; 14 | printf(";%d\n", i); 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /test/pointer.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int i; 7 | int *ptr; 8 | 9 | ptr = &i; 10 | *ptr = 5; 11 | printf("%d;%d\n", i, *ptr); 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /test/pointer2.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int i = 777; 7 | int *p = &i; 8 | int** pp = &p; 9 | int*** ppp = &pp; 10 | int*** ppp2; 11 | 12 | ppp2 = ppp; 13 | printf("%d\n", ***ppp2); 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /test/pointer3.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int[4] ary; 7 | int* ptr = ary; 8 | 9 | *ptr = 1; 10 | ptr[1] = 777; 11 | ptr[2] = 3; 12 | ptr[3] = 4; 13 | printf("%d;%d;%d;%d", *ptr, ptr[1], ptr[2], ptr[3]); 14 | printf(";%d;%d;%d;%d", ary[0], ary[1], ary[2], ary[3]); 15 | puts(""); 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /test/pointer4.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char** argv) 5 | { 6 | int i = 777; 7 | printf("%d\n", *&i); 8 | return 0; 9 | } 10 | -------------------------------------------------------------------------------- /test/ptrarray.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int[4] ary; 7 | int* ptr = ary; 8 | 9 | ptr[0] = 775; 10 | ptr[1] = 776; 11 | ptr[2] = 777; 12 | ptr[3] = 778; 13 | printf("%d;%d;%d;%d;", ary[0], ary[1], ary[2], ary[3]); 14 | printf("%d;%d;%d;%d;", ptr[0], ptr[1], ptr[2], ptr[3]); 15 | 16 | ary[0] = 775; 17 | ary[1] = 776; 18 | ary[2] = 777; 19 | ary[3] = 778; 20 | printf("%d;%d;%d;%d;", ary[0], ary[1], ary[2], ary[3]); 21 | printf("%d;%d;%d;%d;", ptr[0], ptr[1], ptr[2], ptr[3]); 22 | 23 | puts(""); 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /test/ptrdiff.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char** argv) 5 | { 6 | int x, y; 7 | void *p = &x; 8 | void *q = &y; 9 | 10 | printf("%d", q - p); 11 | printf(";%d", q - (p + 1)); 12 | printf(";%d", q - (1 + p)); 13 | printf(";%d", q - (p - 1)); 14 | puts(""); 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /test/ptrmemb.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | struct s { 4 | int x; 5 | int y; 6 | }; 7 | 8 | union u { 9 | int x; 10 | int y; 11 | }; 12 | 13 | int 14 | main(int argc, char **argv) 15 | { 16 | struct s st; 17 | struct s* ptr = &st; 18 | union u uni; 19 | union u* uptr = &uni; 20 | 21 | ptr->x = 1; 22 | ptr->y = 2; 23 | printf("%d;%d", ptr->x, ptr->y); 24 | 25 | (*ptr).x = 3; 26 | (*ptr).y = 4; 27 | printf(";%d;%d", (*ptr).x, (*ptr).y); 28 | 29 | uptr->x = 5; 30 | printf(";%d", uptr->y); 31 | 32 | (*uptr).x = 6; 33 | printf(";%d", (*uptr).y); 34 | 35 | printf(";%d", f()->x); 36 | printf(";%d", f()->y); 37 | 38 | puts(""); 39 | 40 | return 0; 41 | } 42 | 43 | static struct s ss; 44 | 45 | struct s * 46 | f(void) 47 | { 48 | ss.x = 77; 49 | ss.y = 78; 50 | return &ss; 51 | } 52 | -------------------------------------------------------------------------------- /test/ptrmemb2.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | struct st { 4 | int[4] x; 5 | }; 6 | 7 | int 8 | main(void) 9 | { 10 | struct st s; 11 | struct st* p = &s; 12 | p->x[1] = 7; 13 | printf("%d\n", p->x[1]); 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /test/recursivetypedef.cb: -------------------------------------------------------------------------------- 1 | 2 | 3 | typedef int t; 4 | typedef t* t; 5 | -------------------------------------------------------------------------------- /test/rshift.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int i = 16; 7 | 8 | printf("%d;%d;%d;%d;%d", i >> 0, i >> 1, i >> 2, i >> 3, i >> 4); 9 | puts(""); 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /test/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | main() { 4 | local pattern="." 5 | 6 | cd "$(dirname "$0")" 7 | . ./shunit.sh 8 | 9 | while [ $# -gt 0 ] 10 | do 11 | case "$1" in 12 | -t) 13 | # run specified tests 14 | [ -n "$2" ] || error_exit "-t option requires argument" 15 | local pattern="$2" 16 | shift; shift 17 | ;; 18 | --help) 19 | print_usage 20 | exit 0 21 | ;; 22 | -*) 23 | print_usage 1>&2 24 | exit 1 25 | ;; 26 | *) 27 | break 28 | ;; 29 | esac 30 | done 31 | if [ $# -eq 0 ] 32 | then 33 | load_tests test_*.sh 34 | else 35 | load_tests "$@" 36 | fi 37 | if [ "$pattern" = "." ] 38 | then 39 | # run all defined tests 40 | defined_tests | sort | run_tests 41 | else 42 | # run only matched tests 43 | defined_tests | grep "$pattern" | sort | run_tests 44 | fi 45 | } 46 | 47 | print_usage() { 48 | echo "Usage: $0 [-t PATTERN] [--help] [...]" 49 | } 50 | 51 | load_tests() { 52 | local file 53 | for file in "$@" 54 | do 55 | . "./$file" || error_exit "load failed: $file" 56 | done 57 | } 58 | 59 | run_tests() { 60 | local pattern="$1" 61 | local f 62 | 63 | while read f 64 | do 65 | echo 1>&2 66 | print "$(echo $f | sed 's/^test_//')" 1>&2 67 | $f 68 | done 69 | shunit_report_result 70 | } 71 | 72 | defined_tests() { 73 | defined_functions | grep '^test_' 74 | } 75 | 76 | defined_functions() { 77 | typeset +f | awk '/^[^ ]+ \(\)/ { print $1 }' 78 | } 79 | 80 | main "$@" 81 | -------------------------------------------------------------------------------- /test/scomm.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | static int static_common_symbol; 4 | static char *static_common_string; 5 | 6 | int 7 | main(int argc, char **argv) 8 | { 9 | static_common_symbol = 1; 10 | printf("%d", static_common_symbol); 11 | static_common_symbol = 2; 12 | printf(";%d", static_common_symbol); 13 | 14 | static_common_string = "OK"; 15 | printf(";%s", static_common_string); 16 | static_common_string = "NEW"; 17 | printf(";%s", static_common_string); 18 | 19 | puts(""); 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /test/setjmptest.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | import setjmp; 3 | 4 | int 5 | main(void) 6 | { 7 | func1(); 8 | return 0; 9 | } 10 | 11 | static jmp_buf buf; 12 | 13 | void 14 | func1(void) 15 | { 16 | if (setjmp(buf) == 0) { 17 | func2(buf); 18 | } 19 | puts("OK"); 20 | } 21 | 22 | void 23 | func2(jmp_buf buf) 24 | { 25 | func3(buf); 26 | puts("func2: NG"); 27 | } 28 | 29 | void 30 | func3(jmp_buf buf) 31 | { 32 | longjmp(buf, 1); 33 | puts("func3: NG"); 34 | } 35 | -------------------------------------------------------------------------------- /test/sgvar.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | static int static_global_variable = 1; 4 | static char *static_global_string = "OK"; 5 | 6 | int 7 | main(int argc, char **argv) 8 | { 9 | printf("%d", static_global_variable); 10 | static_global_variable = 2; 11 | printf(";%d", static_global_variable); 12 | printf(";%s", static_global_string); 13 | static_global_string = "NEW"; 14 | printf(";%s", static_global_string); 15 | puts(""); 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /test/shortops.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | short i = 1; 7 | 8 | i <<= 1; 9 | printf("%hd", i); 10 | i <<= 13; 11 | printf(";%hd", i); 12 | i <<= 1; 13 | printf(";%hd", i); 14 | i <<= 1; 15 | printf(";%hd", i); 16 | puts(""); 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /test/shortops2.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | short i = -1; 7 | 8 | i <<= 1; 9 | printf("%hd", i); 10 | i <<= 13; 11 | printf(";%hd", i); 12 | i <<= 1; 13 | printf(";%hd", i); 14 | i <<= 1; 15 | printf(";%hd", i); 16 | puts(""); 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /test/sizeof-expr.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | struct s { 4 | int x; 5 | int y; 6 | int z; 7 | }; 8 | 9 | union u { 10 | char c; 11 | short s; 12 | int i; 13 | long l; 14 | int* p; 15 | int[4] a; 16 | }; 17 | 18 | typedef struct s mytype; 19 | 20 | int 21 | main(int argc, char **argv) 22 | { 23 | char c; 24 | short s; 25 | int i; 26 | long l; 27 | int *p; 28 | int[2] a; 29 | struct s st; 30 | union u u; 31 | mytype m; 32 | 33 | printf("%ld", sizeof c); 34 | printf(";%ld", sizeof s); 35 | printf(";%ld", sizeof i); 36 | printf(";%ld", sizeof l); 37 | printf(";%ld", sizeof p); 38 | printf(";%ld", sizeof a); 39 | printf(";%ld", sizeof st); 40 | printf(";%ld", sizeof u); 41 | printf(";%ld", sizeof m); 42 | 43 | puts(""); 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /test/sizeof-struct.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | struct s1 { 4 | char a; 5 | short b; 6 | short x; 7 | int c; 8 | }; 9 | 10 | struct s2 { 11 | int[4] x; 12 | char a; 13 | }; 14 | 15 | struct s3 { 16 | char x; 17 | }; 18 | 19 | struct s4 { 20 | char x; 21 | char y; 22 | }; 23 | 24 | struct s5 { 25 | char x; 26 | short y; 27 | char z; 28 | }; 29 | 30 | struct s6 { 31 | char x; 32 | char y; 33 | char z; 34 | }; 35 | 36 | int 37 | main(int argc, char **argv) 38 | { 39 | printf("%ld", sizeof(struct s1)); 40 | printf(";%ld", sizeof(struct s2)); 41 | printf(";%ld", sizeof(struct s3)); 42 | printf(";%ld", sizeof(struct s4)); 43 | printf(";%ld", sizeof(struct s5)); 44 | printf(";%ld", sizeof(struct s6)); 45 | 46 | puts(""); 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /test/sizeof-type.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | struct s { 4 | int x; 5 | int y; 6 | int z; 7 | }; 8 | 9 | union u { 10 | char c; 11 | short s; 12 | int i; 13 | long l; 14 | int* p; 15 | int[4] a; 16 | }; 17 | 18 | typedef struct s mytype; 19 | 20 | int 21 | main(int argc, char **argv) 22 | { 23 | printf("%ld", sizeof(char)); 24 | printf(";%ld", sizeof(unsigned char)); 25 | printf(";%ld", sizeof(short)); 26 | printf(";%ld", sizeof(unsigned short)); 27 | printf(";%ld", sizeof(int)); 28 | printf(";%ld", sizeof(unsigned int)); 29 | printf(";%ld", sizeof(long)); 30 | printf(";%ld", sizeof(unsigned long)); 31 | printf(";%ld", sizeof(int*)); 32 | printf(";%ld", sizeof(int**)); 33 | printf(";%ld", sizeof(int[])); 34 | printf(";%ld", sizeof(int[4])); 35 | printf(";%ld", sizeof(struct s)); 36 | printf(";%ld", sizeof(union u)); 37 | printf(";%ld", sizeof(mytype)); 38 | 39 | puts(""); 40 | return 0; 41 | } 42 | -------------------------------------------------------------------------------- /test/sizeof-union.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | union u1 { 4 | char x; 5 | }; 6 | 7 | union u2 { 8 | char x; 9 | char y; 10 | char z; 11 | }; 12 | 13 | union u3 { 14 | char x; 15 | short y; 16 | int z; 17 | }; 18 | 19 | union u4 { 20 | char x; 21 | short y; 22 | int z; 23 | char[5] a; 24 | }; 25 | 26 | int 27 | main(int argc, char **argv) 28 | { 29 | printf("%ld", sizeof(union u1)); 30 | printf(";%ld", sizeof(union u2)); 31 | printf(";%ld", sizeof(union u3)); 32 | printf(";%ld", sizeof(union u4)); 33 | 34 | puts(""); 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /test/slcomm.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | static int static_variable; 7 | static char *static_string; 8 | 9 | static_variable = 1; 10 | printf("%d", static_variable); 11 | static_variable = 2; 12 | printf(";%d", static_variable); 13 | static_string = "OK"; 14 | printf(";%s", static_string); 15 | static_string = "NEW"; 16 | printf(";%s", static_string); 17 | puts(""); 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /test/slvar.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | static int static_variable = 1; 7 | static char *static_string = "OK"; 8 | 9 | printf("%d", static_variable); 10 | static_variable = 2; 11 | printf(";%d", static_variable); 12 | printf(";%s", static_string); 13 | static_string = "NEW"; 14 | printf(";%s", static_string); 15 | puts(""); 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /test/src1.cb: -------------------------------------------------------------------------------- 1 | int f(int x) { return x * x; } 2 | -------------------------------------------------------------------------------- /test/src1.hb: -------------------------------------------------------------------------------- 1 | extern int f(int x); 2 | -------------------------------------------------------------------------------- /test/src2.cb: -------------------------------------------------------------------------------- 1 | import src1; 2 | int main(int argc, char **argv) { return f(2); } 3 | -------------------------------------------------------------------------------- /test/staticfunc.cb: -------------------------------------------------------------------------------- 1 | int 2 | main(int argc, char **argv) 3 | { 4 | return private_function(); 5 | } 6 | 7 | static int 8 | private_function(void) 9 | { 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /test/string.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | printf(""); 7 | printf(";"); 8 | printf(";a"); 9 | printf(";aa;b"); 10 | printf(";\""); 11 | printf(";\'"); 12 | printf(";\a\b\e\f\n\r\t\v"); 13 | printf(";\101\102\103\141\142\143"); 14 | puts(""); 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /test/struct-semcheck.cb: -------------------------------------------------------------------------------- 1 | struct a { 2 | }; 3 | 4 | struct b { 5 | struct a x; 6 | }; 7 | 8 | struct c { 9 | struct a x; 10 | struct b y; 11 | }; 12 | 13 | struct d { 14 | struct c x; 15 | struct c y; 16 | }; 17 | 18 | // direct recursion with pointer 19 | struct e { 20 | struct e *ptr; 21 | }; 22 | 23 | // indirect recursion with pointer 24 | struct f { 25 | struct g x; 26 | }; 27 | 28 | struct g { 29 | struct f * ptr; 30 | }; 31 | 32 | int main(int argc, char **argv) { return 0; } 33 | -------------------------------------------------------------------------------- /test/struct-semcheck10.cb: -------------------------------------------------------------------------------- 1 | struct a { 2 | int x; 3 | void y; 4 | }; 5 | 6 | int main(int argc, char **argv) { return 0; } 7 | -------------------------------------------------------------------------------- /test/struct-semcheck2.cb: -------------------------------------------------------------------------------- 1 | struct a { 2 | struct a x; 3 | }; 4 | 5 | int main(int argc, char **argv) { return 0; } 6 | -------------------------------------------------------------------------------- /test/struct-semcheck3.cb: -------------------------------------------------------------------------------- 1 | // indirect recursion 2 | struct a { struct b x; }; 3 | struct b { struct a x; }; 4 | 5 | int main(int argc, char **argv) { return 0; } 6 | -------------------------------------------------------------------------------- /test/struct-semcheck4.cb: -------------------------------------------------------------------------------- 1 | // indirect recursion 2 | struct a { struct b x; }; 3 | struct b { struct c x; }; 4 | struct c { struct a x; }; 5 | 6 | int main(int argc, char **argv) { return 0; } 7 | -------------------------------------------------------------------------------- /test/struct-semcheck5.cb: -------------------------------------------------------------------------------- 1 | struct a { 2 | int x; 3 | }; 4 | 5 | int main(int argc, char **argv) 6 | { 7 | struct a s; 8 | s.x = 1; 9 | return s.nosuchmember; 10 | } 11 | -------------------------------------------------------------------------------- /test/struct-semcheck6.cb: -------------------------------------------------------------------------------- 1 | struct a { 2 | int x; 3 | }; 4 | 5 | int main(int argc, char **argv) 6 | { 7 | struct a s; 8 | struct a *ptr = &s; 9 | ptr->x = 1; 10 | return ptr->nosuchmember; 11 | } 12 | -------------------------------------------------------------------------------- /test/struct-semcheck7.cb: -------------------------------------------------------------------------------- 1 | struct st { 2 | int x; 3 | int x; 4 | }; 5 | 6 | int main(int argc, char **argv) 7 | { 8 | struct st s; 9 | s.x = 0; 10 | return s.x; 11 | } 12 | -------------------------------------------------------------------------------- /test/struct-semcheck8.cb: -------------------------------------------------------------------------------- 1 | int main(int argc, char **argv) { return 1.x; } 2 | -------------------------------------------------------------------------------- /test/struct-semcheck9.cb: -------------------------------------------------------------------------------- 1 | // indirect recursion 2 | struct a { struct b x; }; 3 | typedef struct a struct_a; 4 | struct b { struct c x; }; 5 | struct c { struct_a x; }; 6 | 7 | int main(int argc, char **argv) { return 0; } 8 | -------------------------------------------------------------------------------- /test/struct.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | struct point { 4 | int x; 5 | int y; 6 | }; 7 | 8 | int 9 | main(int argc, char **argv) 10 | { 11 | struct point pnt; 12 | 13 | pnt.x = 11; 14 | pnt.y = 22; 15 | printf("%d;%d\n", pnt.x, pnt.y); 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /test/struct2.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | struct t5 { 4 | int x; 5 | }; 6 | 7 | struct t4 { 8 | struct t5 x; 9 | }; 10 | 11 | struct t3 { 12 | struct t4 x; 13 | }; 14 | 15 | struct t2 { 16 | struct t3 x; 17 | }; 18 | 19 | struct t1 { 20 | struct t2 x; 21 | }; 22 | 23 | struct t1 b; 24 | static struct t1 d; 25 | 26 | int 27 | main(int argc, char **argv) 28 | { 29 | struct t1 a; 30 | static struct t1 c; 31 | 32 | a.x.x.x.x.x = 701; 33 | printf("%d", a.x.x.x.x.x); 34 | 35 | b.x.x.x.x.x = 702; 36 | printf(";%d", b.x.x.x.x.x); 37 | 38 | c.x.x.x.x.x = 703; 39 | printf(";%d", c.x.x.x.x.x); 40 | 41 | d.x.x.x.x.x = 704; 42 | printf(";%d", d.x.x.x.x.x); 43 | 44 | puts(""); 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /test/struct3.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | struct st { 4 | int[4] x; 5 | }; 6 | 7 | int 8 | main(void) 9 | { 10 | struct st s; 11 | s.x[1] = 7; 12 | printf("%d\n", s.x[1]); 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /test/sub.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | static int g = 8; 4 | static int c; 5 | 6 | int 7 | main(int argc, char **argv) 8 | { 9 | int i = 1; 10 | int j; 11 | 12 | printf("%d", 1 - 0); // 1 13 | printf(";%d", 3 - i); // 2 14 | i = 4; 15 | j = 1; 16 | printf(";%d", i - j); // 3 17 | printf(";%d", g - i); // 4 18 | i = 13; 19 | printf(";%d", i - g); // 5 20 | printf(";%d", f(7)); // 6 21 | printf(";%d", f(9) - 1); // 7 22 | i = 1; 23 | printf(";%d", f(10) - i); // 8 24 | c = 2; 25 | printf(";%d", f(12) - c); // 9 26 | i = 11; 27 | printf(";%d", f(i)); // 10 28 | i = 13; 29 | j = 1; 30 | printf(";%d", f(i) - j); // 11 31 | i = 15; 32 | j = 4; 33 | printf(";%d", i - f(j)); // 12 34 | i = 25; 35 | j = 12; 36 | printf(";%d", f(i) - f(j)); // 13 37 | puts(""); 38 | return 0; 39 | } 40 | 41 | int 42 | f(int i) 43 | { 44 | return i - 1; 45 | } 46 | -------------------------------------------------------------------------------- /test/switch.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | switch (argc) { 7 | case 1: 8 | case 2: 9 | puts("1 or 2"); 10 | break; 11 | case 3: 12 | case 4: 13 | puts("3 or 4"); 14 | break; 15 | case 5: 16 | case 6: 17 | puts("5 or 6"); 18 | break; 19 | default: 20 | puts("other"); 21 | break; 22 | } 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /test/syntax1.cb: -------------------------------------------------------------------------------- 1 | // various syntaxes 2 | 3 | // line comment 4 | // line comment----- 5 | 6 | /* block comment */ 7 | /* block 8 | comment in 9 | multiple lines */ 10 | 11 | import stdio; 12 | import stdlib; 13 | import unistd; 14 | 15 | char c; 16 | short s; 17 | int ii; 18 | long l; 19 | 20 | unsigned char uc; 21 | unsigned short us; 22 | unsigned int ui; 23 | unsigned long ul; 24 | 25 | int* p; 26 | int** pp; 27 | int*** ppp; 28 | int**** pppp; 29 | int***** ppppp; 30 | 31 | int[1] a; 32 | int[1][1] aa; 33 | int[1][1][1] aaa; 34 | 35 | int*[1] pa; 36 | int[]* ap; 37 | int**[1] ppa; 38 | int*[]* pap; 39 | int[]** app; 40 | int[1][1]* aap; 41 | int[]*[1] apa; 42 | int*[1][1] paa; 43 | 44 | struct file { 45 | int fd; 46 | char *path; 47 | }; 48 | 49 | struct ifnode { 50 | union node *cond; 51 | union node *then_body; 52 | union node *else_body; 53 | }; 54 | 55 | struct stmt { 56 | union node *expr; 57 | }; 58 | 59 | union node { 60 | struct ifnode ifnode; 61 | struct stmt stmt; 62 | }; 63 | 64 | typedef int myint; 65 | 66 | int 67 | main(int argc, char** argv) 68 | { 69 | ff(); 70 | return f(1, 2, 3); 71 | } 72 | 73 | void ff(void) { return; } 74 | 75 | int 76 | f(int i, int j, int k) 77 | { 78 | i++; 79 | ++i; 80 | i--; 81 | --i; 82 | printf("%d, %d, %d\n", 1, *(int*)&j, (int)h()); 83 | return g(g(i, j % 18), 3 + 5 * 7); 84 | } 85 | 86 | int g(int i, int j) { 87 | ;; return i * h() * *(myint*)&j ; } 88 | 89 | myint h(void) { return 0; } 90 | -------------------------------------------------------------------------------- /test/syntax2.cb: -------------------------------------------------------------------------------- 1 | // lookahead test (defstruct VS defvar) 2 | 3 | struct file { 4 | int fd; 5 | }; 6 | 7 | struct file f; 8 | 9 | int main(int argc, char **argv) { return 0; } 10 | -------------------------------------------------------------------------------- /test/textwrite.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(void) 5 | { 6 | puts = NULL; // causes core dump 7 | return 0; 8 | } 9 | -------------------------------------------------------------------------------- /test/ucharops.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | unsigned char i = 1; 7 | 8 | i <<= 1; 9 | printf("%hhu", i); 10 | i <<= 5; 11 | printf(";%hhu", i); 12 | i <<= 1; 13 | printf(";%hhu", i); 14 | i <<= 1; 15 | printf(";%hhu", i); 16 | puts(""); 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /test/ucharops2.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | unsigned char i = -1; 7 | 8 | i <<= 1; 9 | printf("%hhu", i); 10 | i <<= 5; 11 | printf(";%hhu", i); 12 | i <<= 1; 13 | printf(";%hhu", i); 14 | i <<= 1; 15 | printf(";%hhu", i); 16 | puts(""); 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /test/uintops.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | unsigned int i = 1; 7 | 8 | i <<= 1; 9 | printf("%u", i); 10 | i <<= 29; 11 | printf(";%u", i); 12 | i <<= 1; 13 | printf(";%u", i); 14 | i <<= 1; 15 | printf(";%u", i); 16 | puts(""); 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /test/ulongops.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | unsigned long i = 1; 7 | 8 | printf("%lu", i); 9 | i <<= 1; 10 | printf(";%lu", i); 11 | i <<= 61; 12 | printf(";%lu", i); 13 | i <<= 1; 14 | printf(";%lu", i); 15 | i <<= 1; 16 | printf(";%lu", i); 17 | puts(""); 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /test/unaryminus.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int i = 1; 7 | int j = 0; 8 | int k = -1; 9 | 10 | printf("%d;%d;%d", -i, -j, -k); 11 | puts(""); 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /test/unaryplus.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int i = 1; 7 | int j = 0; 8 | int k = -1; 9 | 10 | printf("%d;%d;%d", +i, +j, +k); 11 | puts(""); 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /test/union-semcheck.cb: -------------------------------------------------------------------------------- 1 | union a { 2 | }; 3 | 4 | union b { 5 | union a x; 6 | }; 7 | 8 | union c { 9 | union a x; 10 | union b y; 11 | }; 12 | 13 | union d { 14 | union c x; 15 | union c y; 16 | }; 17 | 18 | // direct recursion with pointer 19 | union e { 20 | union e *ptr; 21 | }; 22 | 23 | // indirect recursion with pointer 24 | union f { 25 | union g x; 26 | }; 27 | 28 | union g { 29 | union f * ptr; 30 | }; 31 | 32 | int main(int argc, char **argv) { return 0; } 33 | -------------------------------------------------------------------------------- /test/union-semcheck10.cb: -------------------------------------------------------------------------------- 1 | union a { 2 | int x; 3 | void y; 4 | }; 5 | 6 | int main(int argc, char **argv) { return 0; } 7 | -------------------------------------------------------------------------------- /test/union-semcheck2.cb: -------------------------------------------------------------------------------- 1 | union a { 2 | union a x; 3 | }; 4 | 5 | int main(int argc, char **argv) { return 0; } 6 | -------------------------------------------------------------------------------- /test/union-semcheck3.cb: -------------------------------------------------------------------------------- 1 | // indirect recursion 2 | union a { union b x; }; 3 | union b { union a x; }; 4 | 5 | int main(int argc, char **argv) { return 0; } 6 | -------------------------------------------------------------------------------- /test/union-semcheck4.cb: -------------------------------------------------------------------------------- 1 | // indirect recursion 2 | union a { union b x; }; 3 | union b { union c x; }; 4 | union c { union a x; }; 5 | 6 | int main(int argc, char **argv) { return 0; } 7 | -------------------------------------------------------------------------------- /test/union-semcheck5.cb: -------------------------------------------------------------------------------- 1 | union a { 2 | int x; 3 | }; 4 | 5 | int main(int argc, char **argv) 6 | { 7 | union a u; 8 | u.x = 1; 9 | return u.nosuchmember; 10 | } 11 | -------------------------------------------------------------------------------- /test/union-semcheck6.cb: -------------------------------------------------------------------------------- 1 | union a { 2 | int x; 3 | }; 4 | 5 | int main(int argc, char **argv) 6 | { 7 | union a u; 8 | union a* ptr = &u; 9 | ptr->x = 1; 10 | return ptr->nosuchmember; 11 | } 12 | -------------------------------------------------------------------------------- /test/union-semcheck7.cb: -------------------------------------------------------------------------------- 1 | union st { 2 | int x; 3 | int x; 4 | }; 5 | 6 | int main(int argc, char **argv) 7 | { 8 | union st s; 9 | s.x = 0; 10 | return s.x; 11 | } 12 | -------------------------------------------------------------------------------- /test/union-semcheck8.cb: -------------------------------------------------------------------------------- 1 | int main(int argc, char **argv) { return (1+"str").x; } 2 | -------------------------------------------------------------------------------- /test/union-semcheck9.cb: -------------------------------------------------------------------------------- 1 | // indirect recursion 2 | union a { union b x; }; 3 | typedef union a union_a; 4 | union b { union c x; }; 5 | union c { union_a x; }; 6 | 7 | int main(int argc, char **argv) { return 0; } 8 | -------------------------------------------------------------------------------- /test/union.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | union nums { 4 | unsigned char[8] cs; 5 | unsigned short s; 6 | unsigned int i; 7 | unsigned long l; 8 | }; 9 | 10 | int 11 | main(int argc, char **argv) 12 | { 13 | union nums u; 14 | 15 | u.cs[0] = (unsigned char)1; 16 | u.cs[1] = (unsigned char)2; 17 | printf("%hhd;%hhd;%hd\n", u.cs[0], u.cs[1], u.s); 18 | 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /test/usertype.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | struct s { 4 | int x; 5 | int y; 6 | }; 7 | 8 | union u { 9 | int x; 10 | int y; 11 | }; 12 | 13 | typedef char schar; 14 | typedef short sshort; 15 | typedef int sint; 16 | typedef long slong; 17 | typedef unsigned char uchar; 18 | typedef unsigned short ushort; 19 | typedef unsigned int uint; 20 | typedef unsigned long ulong; 21 | typedef struct s struct_s; 22 | typedef union u union_u; 23 | typedef int[8] ints8; 24 | typedef int* intptr; 25 | typedef int (char*)* msgfunc; 26 | typedef sint sint2; 27 | 28 | int 29 | main(int argc, char **argv) 30 | { 31 | sint i = 1; 32 | struct_s st; 33 | union_u un; 34 | ints8 ary; 35 | intptr ptr = &i; 36 | msgfunc myputs = puts; 37 | 38 | printf("%d", i); 39 | printf(";%d", f(2)); 40 | printf(";%d;%d", fs(), (sint)fu()); 41 | st.x = 3; 42 | printf(";%d", st.x); 43 | un.x = 4; 44 | printf(";%d", un.x); 45 | ary[1] = 5; 46 | printf(";%d", ary[1]); 47 | *ptr = 6; 48 | printf(";%d", *ptr); 49 | myputs(";OK"); 50 | return 0; 51 | } 52 | 53 | int f(sint i) { return i; } 54 | 55 | sint fs(void) { return (sint)1; } 56 | uint fu(void) { return (uint)1; } 57 | -------------------------------------------------------------------------------- /test/ushortops.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | unsigned short i = 1; 7 | 8 | i <<= 1; 9 | printf("%hu", i); 10 | i <<= 13; 11 | printf(";%hu", i); 12 | i <<= 1; 13 | printf(";%hu", i); 14 | i <<= 1; 15 | printf(";%hu", i); 16 | puts(""); 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /test/ushortops2.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | unsigned short i = -1; 7 | 8 | i <<= 1; 9 | printf("%hu", i); 10 | i <<= 13; 11 | printf(";%hu", i); 12 | i <<= 1; 13 | printf(";%hu", i); 14 | i <<= 1; 15 | printf(";%hu", i); 16 | puts(""); 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /test/utf.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int main(int argc, char **argv) { puts("こんにちは世界"); } 4 | -------------------------------------------------------------------------------- /test/utf.out: -------------------------------------------------------------------------------- 1 | こんにちは世界 2 | -------------------------------------------------------------------------------- /test/validstmt1.cb: -------------------------------------------------------------------------------- 1 | int 2 | main(void) 3 | { 4 | int[4] a; 5 | a; 6 | return 0; 7 | } 8 | -------------------------------------------------------------------------------- /test/var-semcheck.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | static int n = f(); 4 | 5 | int 6 | main(int argc, char** argv) 7 | { 8 | printf("%d\n", n); 9 | return 0; 10 | } 11 | 12 | int f(void) { return 1; } 13 | -------------------------------------------------------------------------------- /test/varargs.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | import stdarg; 3 | 4 | int 5 | main(int argc, char** argv) 6 | { 7 | myprintf("%d;%d;%d\n", 1, 2, 3); 8 | } 9 | 10 | static void 11 | myprintf(char* fmt, ...) 12 | { 13 | va_list ap = va_init(&fmt); 14 | vfprintf(stdout, fmt, ap); 15 | } 16 | -------------------------------------------------------------------------------- /test/vardecl.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | import errno; 3 | 4 | int 5 | main(int argc, char **argv) 6 | { 7 | printf("<<%s>>\n", sys_errlist[3]); 8 | printf("printf=%p\n", printf); 9 | return 0; 10 | } 11 | -------------------------------------------------------------------------------- /test/while-break.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | while (1) { 7 | break; 8 | puts("NG"); 9 | } 10 | puts("OK"); 11 | 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /test/while-continue.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int i; 7 | 8 | i = 3; 9 | while (i) { 10 | i--; 11 | continue; 12 | puts("NG"); 13 | } 14 | puts("OK"); 15 | 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /test/while1.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | while (0) { 7 | puts("NG"); 8 | return 1; 9 | } 10 | puts("OK"); 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /test/while2.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | while (1) { 7 | puts("OK"); 8 | return 0; 9 | } 10 | puts("NG"); 11 | return 1; 12 | } 13 | -------------------------------------------------------------------------------- /test/while3.cb: -------------------------------------------------------------------------------- 1 | import stdio; 2 | 3 | int 4 | main(int argc, char **argv) 5 | { 6 | int i = 3; 7 | 8 | printf("%d", i); 9 | while (i) { 10 | printf(";%d", i); 11 | i--; 12 | } 13 | printf(";%d\n", i); 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /test/zero.cb: -------------------------------------------------------------------------------- 1 | int 2 | main(int argc, char **argv) 3 | { 4 | return 0; 5 | } 6 | -------------------------------------------------------------------------------- /tools/diffoptimized.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | CBC=$(dirname $0)/../bin/cbc 4 | 5 | for src in "$@" 6 | do 7 | if $CBC $src >/dev/null 2>&1 8 | then 9 | asm=$(basename $src .cb).s 10 | echo "$src:" 11 | $CBC -O -S $src -o $asm.opt && 12 | diff -u $asm $asm.opt 13 | fi 14 | done 15 | -------------------------------------------------------------------------------- /tools/list-untested.rb: -------------------------------------------------------------------------------- 1 | require 'pathname' 2 | 3 | def main 4 | Dir.chdir Pathname.new($PROGRAM_NAME).realpath.dirname.dirname + 'test' 5 | test_sh = File.read('test_cbc.sh') 6 | tested = test_sh.scan(/[\$\w\-]+\.cb/).reject {|n| /\$/ =~ n } + 7 | test_sh.scan(%r<\./[\w\-]+>).map {|n| File.basename(n) + '.cb' } 8 | tested = tested.uniq 9 | print_list Dir.glob('*.cb') - tested 10 | end 11 | 12 | def print_list(list) 13 | list.sort.each do |name| 14 | puts name 15 | end 16 | end 17 | 18 | main 19 | -------------------------------------------------------------------------------- /unit/Makefile: -------------------------------------------------------------------------------- 1 | JAVA = java 2 | JAVAC = javac 3 | CLASSPATH = .:../lib/cbc.jar:./junit-4.5.jar 4 | CLASSES = $(patsubst %.java,%.class,$(wildcard Test*.java)) 5 | 6 | test: $(CLASSES) 7 | $(JAVA) -classpath $(CLASSPATH) TestAll 8 | 9 | %.class: %.java 10 | $(JAVAC) -classpath $(CLASSPATH) $< 11 | -------------------------------------------------------------------------------- /unit/TestAll.java: -------------------------------------------------------------------------------- 1 | import org.junit.*; 2 | import org.junit.runner.*; 3 | import org.junit.runners.*; 4 | import org.junit.runners.Suite.*; 5 | 6 | @RunWith(Suite.class) 7 | @SuiteClasses({ 8 | TestCursor.class, 9 | TestTextUtils.class, 10 | TestAsmUtils.class, 11 | TestListUtils.class 12 | }) 13 | public class TestAll { 14 | static public void main(String[] args) { 15 | JUnitCore.main(TestAll.class.getName()); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /unit/TestAsmUtils.java: -------------------------------------------------------------------------------- 1 | import org.junit.*; 2 | import org.junit.runner.*; 3 | import static org.junit.Assert.*; 4 | import static net.loveruby.cflat.utils.AsmUtils.*; 5 | 6 | public class TestAsmUtils { 7 | static public void main(String[] args) { 8 | JUnitCore.main(TestAsmUtils.class.getName()); 9 | } 10 | 11 | @Test public void test_align() { 12 | assertEquals(0, align(0, 4)); 13 | assertEquals(4, align(1, 4)); 14 | assertEquals(4, align(2, 4)); 15 | assertEquals(4, align(3, 4)); 16 | assertEquals(4, align(4, 4)); 17 | assertEquals(8, align(5, 4)); 18 | assertEquals(8, align(6, 4)); 19 | assertEquals(8, align(7, 4)); 20 | assertEquals(8, align(8, 4)); 21 | assertEquals(12, align(9, 4)); 22 | 23 | assertEquals(0, align(0, 8)); 24 | assertEquals(8, align(1, 8)); 25 | assertEquals(8, align(2, 8)); 26 | assertEquals(8, align(7, 8)); 27 | assertEquals(8, align(8, 8)); 28 | assertEquals(16, align(9, 8)); 29 | assertEquals(16, align(16, 8)); 30 | assertEquals(24, align(17, 8)); 31 | 32 | assertEquals(0, align(0, 16)); 33 | assertEquals(16, align(1, 16)); 34 | assertEquals(16, align(16, 16)); 35 | assertEquals(32, align(17, 16)); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /unit/TestListUtils.java: -------------------------------------------------------------------------------- 1 | import org.junit.*; 2 | import org.junit.runner.*; 3 | import static org.junit.Assert.*; 4 | import java.util.List; 5 | import java.util.ArrayList; 6 | import static net.loveruby.cflat.utils.ListUtils.*; 7 | 8 | public class TestListUtils { 9 | static public void main(String[] args) { 10 | JUnitCore.main(TestListUtils.class.getName()); 11 | } 12 | 13 | @Test public void test_reverse() { 14 | assertEquals("reverse #1", list(), reverse(list())); 15 | assertEquals("reverse #2", list(1), reverse(list(1))); 16 | assertEquals("reverse #3", list(2,1), reverse(list(1,2))); 17 | assertEquals("reverse #4", list(3,2,1), reverse(list(1,2,3))); 18 | } 19 | 20 | private List list(int... values) { 21 | List result = new ArrayList(); 22 | for (int i : values) { 23 | result.add(i); 24 | } 25 | return result; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /unit/TestTextUtils.java: -------------------------------------------------------------------------------- 1 | import org.junit.*; 2 | import org.junit.runner.*; 3 | import static org.junit.Assert.*; 4 | import static net.loveruby.cflat.utils.TextUtils.*; 5 | 6 | public class TestTextUtils { 7 | static public void main(String[] args) { 8 | JUnitCore.main(TestTextUtils.class.getName()); 9 | } 10 | 11 | @Test public void test_dumpString() { 12 | assertEquals("dumpString #1", "\"\"", dumpString("")); 13 | assertEquals("dumpString #2", "\"x\"", dumpString("x")); 14 | assertEquals("dumpString #3", "\"xx\"", dumpString("xx")); 15 | assertEquals("dumpString #4", "\"x\\\"x\"", dumpString("x\"x")); 16 | assertEquals("dumpString #5", "\"x\\nx\"", dumpString("x\nx")); 17 | } 18 | 19 | @Test public void test_isPrintable() { 20 | assertEquals(true, isPrintable('a')); 21 | assertEquals(true, isPrintable('A')); 22 | assertEquals(true, isPrintable(' ')); 23 | assertEquals(false, isPrintable('\t')); 24 | assertEquals(false, isPrintable('\r')); 25 | assertEquals(false, isPrintable('\n')); 26 | assertEquals(false, isPrintable('\0')); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /unit/junit-4.5.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leungwensen/cbc-ubuntu-64bit/8e1121c4afff63fdc4bddd0e5e199adf9e23528f/unit/junit-4.5.jar -------------------------------------------------------------------------------- /unit/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | main() { 4 | if [ $# -eq 0 ] 5 | then 6 | run_class TestAll 7 | else 8 | for t in "$@" 9 | do 10 | run_class $t 11 | done 12 | fi 13 | } 14 | 15 | run_java() { 16 | java -classpath .:../lib/cbc.jar:./junit-4.5.jar "$@" 17 | } 18 | 19 | main "$@" 20 | --------------------------------------------------------------------------------