├── .gitignore ├── .idea ├── .gitignore ├── codeStyles │ └── codeStyleConfig.xml ├── compiler.xml ├── encodings.xml ├── jarRepositories.xml ├── libraries │ └── tools.xml ├── misc.xml ├── runConfigurations.xml └── uiDesigner.xml ├── README.md ├── pom.xml ├── src └── main │ └── java │ └── work │ └── liziyun │ ├── Demo03.java │ ├── LzyJavaCompiler.java │ ├── ast │ ├── Express.java │ ├── LexerBuffer.java │ ├── LzyExpressParser.java │ ├── LzyJavacParser.java │ ├── LzyStatementParser.java │ ├── Parser.java │ └── Statement.java │ ├── code │ ├── LzyClassFile.java │ ├── LzyClassReader.java │ ├── LzyClassWriter.java │ ├── LzyCode.java │ ├── LzyPool.java │ ├── LzyScope.java │ ├── LzySymtab.java │ ├── symbol │ │ ├── LzyClassSymbol.java │ │ ├── LzyMethodSymbol.java │ │ ├── LzyPackageSymbol.java │ │ ├── LzySymbol.java │ │ ├── LzyTypeSymbol.java │ │ └── LzyVarSymbol.java │ └── type │ │ ├── LzyArrayType.java │ │ ├── LzyClassType.java │ │ ├── LzyErrorType.java │ │ ├── LzyMethodType.java │ │ ├── LzyPackageType.java │ │ ├── LzyType.java │ │ ├── LzyTypeParameter.java │ │ └── LzyTypeTags.java │ ├── comp │ ├── LzyAbsGen.java │ ├── LzyAttr.java │ ├── LzyAttrContext.java │ ├── LzyCheck.java │ ├── LzyConstFold.java │ ├── LzyEnter.java │ ├── LzyEnv.java │ ├── LzyGen.java │ ├── LzyInfer.java │ ├── LzyItems.java │ ├── LzyMemberEnter.java │ ├── LzyResolve.java │ └── LzyTodo.java │ ├── io │ └── LzyJavaFile.java │ ├── jvm │ └── LzyTarget.java │ ├── tag │ ├── LzyByteCodes.java │ ├── LzyFlags.java │ └── LzyKinds.java │ ├── tree │ ├── LzyJCCompilationUnit.java │ ├── LzyJCImport.java │ ├── LzyJCIndexed.java │ ├── LzyJCMethodDef.java │ ├── LzyJCModifiers.java │ ├── LzyJCTree.java │ ├── LzyJCTypeParameter.java │ ├── LzyTreeInfo.java │ ├── LzyTreeMaker.java │ ├── LzyVisitor.java │ ├── express │ │ ├── LzyJCApply.java │ │ ├── LzyJCAssign.java │ │ ├── LzyJCAssignop.java │ │ ├── LzyJCBinary.java │ │ ├── LzyJCConditional.java │ │ ├── LzyJCErroneous.java │ │ ├── LzyJCIdent.java │ │ ├── LzyJCLiteral.java │ │ ├── LzyJCNewArray.java │ │ ├── LzyJCNewClass.java │ │ ├── LzyJCParens.java │ │ ├── LzyJCSelect.java │ │ ├── LzyJCTypeArray.java │ │ ├── LzyJCTypeCast.java │ │ ├── LzyJCTypeIdent.java │ │ ├── LzyJCTypeTest.java │ │ └── LzyJCUnary.java │ └── state │ │ ├── LzyJCBlock.java │ │ ├── LzyJCBreak.java │ │ ├── LzyJCCase.java │ │ ├── LzyJCCatch.java │ │ ├── LzyJCClassDef.java │ │ ├── LzyJCContinue.java │ │ ├── LzyJCDoloop.java │ │ ├── LzyJCExec.java │ │ ├── LzyJCExpressionStatement.java │ │ ├── LzyJCForLoop.java │ │ ├── LzyJCIf.java │ │ ├── LzyJCReturn.java │ │ ├── LzyJCSkip.java │ │ ├── LzyJCSwitch.java │ │ ├── LzyJCThrow.java │ │ ├── LzyJCTry.java │ │ ├── LzyJCVarDef.java │ │ └── LzyJCWhileLoop.java │ ├── util │ ├── LzyAssert.java │ ├── LzyByteBuffer.java │ ├── LzyContext.java │ ├── LzyConvert.java │ ├── LzyHashtable.java │ ├── LzyList.java │ ├── LzyListBuffer.java │ └── LzyPosition.java │ └── world │ ├── LzyKeywords.java │ ├── LzyName.java │ ├── LzyScanner.java │ ├── LzyTable.java │ └── LzyToken.java └── test_javac ├── Anlimal.class ├── Anlimal.java ├── Demo03.class ├── Demo03.java └── rt.jar /.gitignore: -------------------------------------------------------------------------------- 1 | # Project exclude paths 2 | /target/ -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Datasource local storage ignored files 5 | /dataSources/ 6 | /dataSources.local.xml 7 | # Editor-based HTTP Client requests 8 | /httpRequests/ 9 | -------------------------------------------------------------------------------- /.idea/codeStyles/codeStyleConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /.idea/jarRepositories.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 14 | 15 | 19 | 20 | -------------------------------------------------------------------------------- /.idea/libraries/tools.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/uiDesigner.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LzyJavac 2 | JavaCompile 仿制的Java前端编译器 基础正版javac的精简版本,添加大量注释说明 3 | 4 | # LzyJavac和正版Javac有什么区别? 5 | LzyJavac是从正版Javac大量抄袭修改而来的,为了帮助大家方便学习理解。 6 | 删减大量复杂非必要的过程,语法检查 和 插件化注解 和 解语法糖并没有实现! 7 | 但是这不影响,我们对Java前端编译器的学习和理解! 8 | 这份源码中,写了大量注释。参考多个jdk版本,选择的算法是简单为主!而不是最好的,因为更容易帮助大家理解! 9 | 10 | # 两个路径 11 | jdk类库路径:存放jdk自带的类 12 | String List 等等 13 | 编译路径:存放Java源代码 14 | 将对这个位置的源代码进行编译处理 15 | # 不支持的功能 16 | 1. 内部类 17 | 2. 枚举 18 | 3. 注解 19 | 4. 泛型 20 | 5. Lambda 21 | 6. switch 22 | 为什么不支持1-5? 23 | 因为要实现他们,过于繁琐难度很大,也不利于大家初步的学习 24 | 为什么不支持6? 25 | 因为懒,大家可以参考我关于switch字节码的分析去实现! 26 | # switch字节码的原理分析 27 | https://www.bilibili.com/video/BV1qv411g7tj/ 28 | 29 | # 作者信息 30 | 李滋芸 鄂州职业大学 31 | 32 | 微信:liziyun_2000 33 | 34 | 公众号:小豆的奇思妙想 35 | 36 | B站up讲课:李滋芸 37 | # 使用教程 38 | https://www.bilibili.com/video/BV1La411C7Xe 39 | 40 | 41 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.example 8 | LzyJavaCompile1.5 9 | 1.0-SNAPSHOT 10 | 11 | 12 | 13 | org.springframework.boot 14 | spring-boot-maven-plugin 15 | 2.3.1.RELEASE 16 | 17 | 18 | work.liziyun.LzyJavaCompiler 19 | 20 | 21 | 22 | 23 | 24 | repackage 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | jdk-1.8 36 | 37 | 1.8 38 | true 39 | 40 | 41 | UTF-8 42 | UTF-8 43 | UTF-8 44 | 1.8 45 | 1.8 46 | 1.8 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/Demo03.java: -------------------------------------------------------------------------------- 1 | package work.liziyun; 2 | 3 | 4 | 5 | class Anlimal{ 6 | public String name = "23"; 7 | } 8 | 9 | public class Demo03 extends Anlimal { 10 | 11 | public Anlimal anlimal = new Anlimal(); 12 | 13 | public static String getName(){ 14 | return "23"; 15 | } 16 | 17 | 18 | public static void main(String []args){ 19 | Demo03 demo03 = new Demo03(); 20 | System.out.println( demo03.anlimal.name ); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/LzyJavaCompiler.java: -------------------------------------------------------------------------------- 1 | package work.liziyun; 2 | 3 | 4 | 5 | import work.liziyun.ast.LexerBuffer; 6 | import work.liziyun.ast.LzyJavacParser; 7 | import work.liziyun.code.LzyClassWriter; 8 | import work.liziyun.code.symbol.LzyClassSymbol; 9 | import work.liziyun.comp.*; 10 | import work.liziyun.code.LzyClassReader; 11 | import work.liziyun.tree.LzyJCCompilationUnit; 12 | 13 | import work.liziyun.tree.LzyTreeMaker; 14 | import work.liziyun.tree.state.LzyJCClassDef; 15 | import work.liziyun.util.LzyContext; 16 | import work.liziyun.util.LzyList; 17 | import work.liziyun.util.LzyListBuffer; 18 | import work.liziyun.world.LzyTable; 19 | import java.io.*; 20 | import java.util.Scanner; 21 | 22 | public class LzyJavaCompiler implements LzyClassReader.SourceCompleter { 23 | 24 | 25 | private work.liziyun.util.LzyContext LzyContext; 26 | 27 | private LzyTreeMaker treeMaker; 28 | 29 | private LzyTable names; 30 | 31 | private LzyEnter enter; 32 | 33 | private LzyClassReader classReader; 34 | 35 | private LzyAttr attr; 36 | 37 | private LzyTodo todo; 38 | 39 | private LzyGen gen; 40 | 41 | private LzyClassWriter classWriter; 42 | 43 | public LzyJavaCompiler(LzyContext LzyContext){ 44 | this.LzyContext = LzyContext; 45 | this.treeMaker = LzyTreeMaker.instance(LzyContext); 46 | this.names = LzyTable.instance(LzyContext); 47 | this.enter = LzyEnter.instance(LzyContext); 48 | this.classReader = LzyClassReader.instance(LzyContext); 49 | // 设置路径: 注意结束符号 classReader.bootclassPath 50 | // 源码路径: 注意结束符号 classReader.sourceClassPath 51 | // 设置填充器 52 | classReader.sourceCompleter = this; 53 | // 引用消除 54 | this.attr = LzyAttr.instance(LzyContext); 55 | // 承上启下的组件 56 | this.todo = LzyTodo.instance(LzyContext); 57 | // 58 | this.gen = LzyGen.instance(LzyContext); 59 | 60 | this.classWriter = LzyClassWriter.instance(LzyContext); 61 | } 62 | 63 | public LzyList compile(LzyList LzyList) throws Exception { 64 | // 抽象语法树建立 65 | LzyList allPath = LzyList; 66 | LzyListBuffer compilationUnitListBuffer = new LzyListBuffer(); 67 | while ( allPath.nonEmpty() ){ 68 | try { 69 | compilationUnitListBuffer.append( this.parse(allPath.head) ); 70 | } catch (IOException e) { 71 | e.printStackTrace(); 72 | } 73 | // 下一个 74 | allPath = allPath.tail; 75 | } 76 | // 符号填充 77 | enter.complete(compilationUnitListBuffer.toList(),null); 78 | // 引用消除 79 | while (todo.nonEmpty()){ 80 | LzyEnv env = (LzyEnv)todo.remove(); 81 | attr.attribClass(env.tree.pos,env.enclClass.sym); 82 | // Gen生成可寻址实体 + 写入字节码IO流 83 | LzyJCClassDef classDef = (LzyJCClassDef) env.tree; 84 | genCode(env,classDef); 85 | } 86 | return null ; 87 | } 88 | 89 | void genCode(LzyEnv env, LzyJCClassDef classDef) throws Exception { 90 | try{ 91 | // 可寻址指令处理 92 | if (this.gen.genClass(env,classDef)){ 93 | // 建立IO流生成字节码 94 | this.classWriter.writeClass( classDef.sym ); 95 | } 96 | }catch (Exception e){ 97 | throw e; 98 | } 99 | } 100 | 101 | 102 | 103 | public static String read(InputStream inputStream) throws IOException { 104 | BufferedReader in = new BufferedReader(new InputStreamReader(inputStream)); 105 | String temp; 106 | StringBuilder sb = new StringBuilder(); 107 | while ( (temp = in.readLine()) != null ){ 108 | sb.append(temp); 109 | } 110 | in.close(); 111 | return sb.toString(); 112 | } 113 | 114 | 115 | public LzyJCCompilationUnit parse(String path) throws IOException { 116 | return parse(path,new FileInputStream(new File(path))); 117 | } 118 | 119 | 120 | public LzyJCCompilationUnit parse(String path,InputStream inputStream) { 121 | // 默认: 空语法树 122 | LzyJCCompilationUnit compilationUnit = this.treeMaker.CompilationUnit(null, LzyList.nil()); 123 | if ( inputStream != null ){ 124 | // 词法解析器 125 | LexerBuffer lexerBuffer = null; 126 | try { 127 | lexerBuffer = new LexerBuffer(LzyContext, read(inputStream).toCharArray(),path); 128 | } catch (IOException e) { 129 | e.printStackTrace(); 130 | } 131 | // 关闭流 132 | try { 133 | inputStream.close(); 134 | } catch (IOException e) { 135 | e.printStackTrace(); 136 | } 137 | // 移动到第一个词 138 | lexerBuffer.nextToken(); 139 | // 解析抽象语法树 140 | LzyJavacParser lzyJavacParser = new LzyJavacParser(lexerBuffer, LzyTreeMaker.instance(LzyContext), LzyTable.instance(LzyContext)); 141 | compilationUnit = lzyJavacParser.parseCompilationUnit(); 142 | } 143 | // 设置文件路径 144 | compilationUnit.sourcefile = this.names.fromString(path); 145 | return compilationUnit; 146 | } 147 | 148 | 149 | /** 150 | * 被动触发的Java源文件: 1. 抽象语法树的建立 2. 符号的填充 151 | * @param classSymbol 152 | * @param sourcePath 153 | * @param inputStream 154 | * 155 | * am 156 | */ 157 | @Override 158 | public void complete(LzyClassSymbol classSymbol , String sourcePath, InputStream inputStream){ 159 | // 抽象语法树的建立 160 | System.out.println("LzyJavaCompiler.complete(): 成功触发其他源文件的编译!"); 161 | LzyJCCompilationUnit compilationUnit = this.parse(sourcePath, inputStream); 162 | // 符号的填充 163 | this.enter.complete(LzyList.of(compilationUnit),classSymbol); 164 | // 填充失败 165 | if ( this.enter.getEnv(classSymbol) == null){ 166 | throw new LzyClassReader.BadClassFile(classSymbol,"file.doesnt.contain.class "+classSymbol.fullName()); 167 | } 168 | } 169 | // 系统下级符号 170 | private static String separator = File.separator; 171 | // 系统分割符号 172 | private static String pathSeparator = File.pathSeparator; 173 | 174 | public static void main(String[] args) throws Exception { 175 | 176 | Scanner sc = new Scanner(System.in); 177 | // 设置编译器路径 178 | System.setProperty("env.class.path",System.getProperty("user.dir")+separator+"test_javac"+separator+pathSeparator ); 179 | // 系统类路径 180 | System.setProperty("sun.boot.class.path",System.getProperty("env.class.path").substring(0,System.getProperty("env.class.path").length()-1)+"rt.jar"+pathSeparator); 181 | System.out.println( "请检查jdk类库路径:" + System.getProperty("env.class.path") ); 182 | System.out.println( "请检查项目路径: " + System.getProperty("sun.boot.class.path") ); 183 | LzyJavaCompiler lzyJavaCompiler = new LzyJavaCompiler(new LzyContext()); 184 | System.out.println("========================================================"); 185 | System.out.println("位置:./LzyJavaCompile1.5/test_javac"); 186 | System.out.println("有包格式:pojo.Student.java"); 187 | System.out.println("无包格式:Student.java"); 188 | System.out.println("========================================================"); 189 | LzyList list = LzyList.nil(); 190 | while (true){ 191 | System.out.println("请输入编译的文件:"); 192 | String javaFileName = sc.next(); 193 | javaFileName = javaFileName.substring(0,javaFileName.lastIndexOf('.')).replace('.',File.separatorChar)+".java"; 194 | list = list.append(System.getProperty("user.dir")+separator+"test_javac"+separator+javaFileName); 195 | System.out.println("是否,继续?(y/n)"); 196 | String yes = sc.next(); 197 | if (!yes.equals("y")){ 198 | break; 199 | } 200 | } 201 | System.out.println("=======================开始编译==========================="); 202 | lzyJavaCompiler.compile( list ); 203 | } 204 | } 205 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/ast/Express.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.ast; 2 | 3 | 4 | import work.liziyun.tree.LzyJCTree; 5 | import work.liziyun.tree.LzyTreeInfo; 6 | import work.liziyun.world.LzyToken; 7 | 8 | public interface Express { 9 | /** 10 | * 赋值表达式 11 | * @return 12 | */ 13 | public LzyJCTree.JCExpression term(); 14 | public LzyJCTree.JCExpression term(int mode); 15 | public LzyJCTree.JCExpression termRest(LzyJCTree.JCExpression var1); 16 | 17 | 18 | /** 19 | * 三元 20 | * @return 21 | */ 22 | public LzyJCTree.JCExpression term1(); 23 | public LzyJCTree.JCExpression term1Rest(LzyJCTree.JCExpression tree); 24 | 25 | 26 | /** 27 | * 二元 28 | * @return 29 | */ 30 | public LzyJCTree.JCExpression term2(); 31 | public LzyJCTree.JCExpression term2Rest(LzyJCTree.JCExpression tree,int op); 32 | 33 | 34 | /** 35 | * 一元 与 基本表达式 36 | * @return 37 | */ 38 | public LzyJCTree.JCExpression term3(); 39 | 40 | static int prec(LzyToken var0) { 41 | int var1 = optag(var0); 42 | return var1 >= 0 ? LzyTreeInfo.opPrec(var1) : -1; 43 | } 44 | 45 | /** 46 | * 基本数据类型的映射值 47 | * @param var0 48 | * @return 49 | */ 50 | static int typetag(LzyToken var0) { 51 | switch(var0) { 52 | case BYTE: 53 | return 1; 54 | case SHORT: 55 | return 3; 56 | case CHAR: 57 | return 2; 58 | case INT: 59 | return 4; 60 | case LONG: 61 | return 5; 62 | case FLOAT: 63 | return 6; 64 | case DOUBLE: 65 | return 7; 66 | case BOOLEAN: 67 | return 8; 68 | default: 69 | return -1; 70 | } 71 | } 72 | 73 | 74 | 75 | /** 76 | * 辅助TreeMark的创建: 一元运算符 映射值 77 | * @param var0 78 | * @return 79 | */ 80 | static int unoptag(LzyToken var0) { 81 | switch(var0) { 82 | case BANG: 83 | return 50; 84 | case TILDE: 85 | return 51; 86 | case LPAREN: 87 | case THIS: 88 | case SUPER: 89 | case NEW: 90 | case LBRACKET: 91 | case DOT: 92 | case QUES: 93 | default: 94 | return -1; 95 | case PLUSPLUS: 96 | return 52; 97 | case SUBSUB: 98 | return 53; 99 | case PLUS: 100 | return 48; 101 | case SUB: 102 | return 49; 103 | } 104 | } 105 | 106 | static int optag(LzyToken var0) { 107 | switch(var0) { 108 | case LT: 109 | return 64; 110 | case BYTE: 111 | case SHORT: 112 | case CHAR: 113 | case INT: 114 | case LONG: 115 | case FLOAT: 116 | case DOUBLE: 117 | case BOOLEAN: 118 | case VOID: 119 | case IDENTIFIER: 120 | case CASE: 121 | case DEFAULT: 122 | case IF: 123 | case FOR: 124 | case WHILE: 125 | case DO: 126 | case TRY: 127 | case SWITCH: 128 | case RETURN: 129 | case THROW: 130 | case BREAK: 131 | case CONTINUE: 132 | case ELSE: 133 | case FINALLY: 134 | case CATCH: 135 | case INTLITERAL: 136 | case LONGLITERAL: 137 | case FLOATLITERAL: 138 | case DOUBLELITERAL: 139 | case CHARLITERAL: 140 | case STRINGLITERAL: 141 | case TRUE: 142 | case FALSE: 143 | case NULL: 144 | case EQ: 145 | case BANG: 146 | case TILDE: 147 | case LPAREN: 148 | case THIS: 149 | case SUPER: 150 | case NEW: 151 | case LBRACKET: 152 | case DOT: 153 | case QUES: 154 | case PLUSPLUS: 155 | case SUBSUB: 156 | case ERROR: 157 | default: 158 | return -1; 159 | case PLUSEQ: 160 | return 88; 161 | case SUBEQ: 162 | return 89; 163 | case STAREQ: 164 | return 90; 165 | case SLASHEQ: 166 | return 91; 167 | case PERCENTEQ: 168 | return 92; 169 | case AMPEQ: 170 | return 78; 171 | case BAREQ: 172 | return 76; 173 | case CARETEQ: 174 | return 77; 175 | case LTLTEQ: 176 | return 85; 177 | case GTGTEQ: 178 | return 86; 179 | case GTGTGTEQ: 180 | return 87; 181 | case PLUS: 182 | return 71; 183 | case SUB: 184 | return 72; 185 | case GTEQ: 186 | return 67; 187 | case GTGTGT: 188 | return 70; 189 | case GTGT: 190 | return 69; 191 | case GT: 192 | return 65; 193 | case BARBAR: 194 | return 57; 195 | case AMPAMP: 196 | return 58; 197 | case BAR: 198 | return 59; 199 | case CARET: 200 | return 60; 201 | case AMP: 202 | return 61; 203 | case EQEQ: 204 | return 62; 205 | case BANGEQ: 206 | return 63; 207 | case LTEQ: 208 | return 66; 209 | case LTLT: 210 | return 68; 211 | case STAR: 212 | return 73; 213 | case SLASH: 214 | return 74; 215 | case PERCENT: 216 | return 75; 217 | case INSTANCEOF: 218 | return 32; 219 | } 220 | } 221 | 222 | } 223 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/ast/LexerBuffer.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.ast; 2 | 3 | 4 | import work.liziyun.util.LzyContext; 5 | import work.liziyun.world.LzyName; 6 | import work.liziyun.world.LzyScanner; 7 | import work.liziyun.world.LzyTable; 8 | import work.liziyun.world.LzyToken; 9 | 10 | 11 | public class LexerBuffer extends LzyScanner { 12 | 13 | private int errorEndPos; 14 | private LzyTable names; 15 | 16 | public LexerBuffer(LzyContext LzyContext, char[] chars,String fileName) { 17 | super( LzyContext,chars,fileName); 18 | 19 | } 20 | 21 | 22 | 23 | /** 24 | * 返回当前词Token的Name 25 | * 注意: 26 | * 1. 不处理assert断言关键字 27 | * 2. 不处理枚举 28 | * 3. 不处理this 29 | * 4. 不处理UNDERSCORE下划线 30 | * @return 31 | */ 32 | public LzyName ident(){ 33 | LzyName name; 34 | // 当前Token是标识符 35 | if (this.token() == LzyToken.IDENTIFIER){ 36 | name = this.name(); 37 | // 移词 38 | this.nextToken(); 39 | return name; 40 | }else{ 41 | // 记录错误: 我们一直期望得到一个标识符的词 42 | this.accept(LzyToken.IDENTIFIER); 43 | return this.names.error; 44 | } 45 | } 46 | 47 | public void accept(LzyToken expectToken){ 48 | if (this.token() == expectToken ){ 49 | this.nextToken(); 50 | 51 | } else { 52 | // 设置错误位置 53 | setErrorEndPos(this.pos()); 54 | // 记录报错信息 55 | System.out.println(this.prevEndPos()+" expected: " + expectToken.toString() ); 56 | } 57 | } 58 | 59 | public void tryEndOf(){ 60 | if (this.bp == this.buf.length-1){ 61 | this.token = LzyToken.EOF; 62 | System.out.println("词法分析结束:"+fileName); 63 | } 64 | } 65 | 66 | public void setErrorEndPos(int errPos) { 67 | if (errPos > errorEndPos) 68 | errorEndPos = errPos; 69 | } 70 | 71 | public int getErrorEndPos(){ 72 | return errorEndPos; 73 | } 74 | 75 | /** Skip forward until a suitable stop token is found. 76 | */ 77 | public void skip(boolean stopAtImport, boolean stopAtMemberDecl, boolean stopAtIdentifier, boolean stopAtStatement) { 78 | while (true) { 79 | switch (token()) { 80 | case SEMI: 81 | nextToken(); 82 | return; 83 | case PUBLIC: 84 | case FINAL: 85 | case ABSTRACT: 86 | case EOF: 87 | case CLASS: 88 | case INTERFACE: 89 | return; 90 | case IMPORT: 91 | if (stopAtImport) 92 | return; 93 | break; 94 | case LBRACE: 95 | case RBRACE: 96 | case PRIVATE: 97 | case PROTECTED: 98 | case STATIC: 99 | 100 | case LT: 101 | case BYTE: 102 | case SHORT: 103 | case CHAR: 104 | case INT: 105 | case LONG: 106 | case FLOAT: 107 | case DOUBLE: 108 | case BOOLEAN: 109 | case VOID: 110 | if (stopAtMemberDecl) 111 | return; 112 | break; 113 | case IDENTIFIER: 114 | if (stopAtIdentifier) 115 | return; 116 | break; 117 | case CASE: 118 | case DEFAULT: 119 | case IF: 120 | case FOR: 121 | case WHILE: 122 | case DO: 123 | case TRY: 124 | case SWITCH: 125 | case RETURN: 126 | case THROW: 127 | case BREAK: 128 | case CONTINUE: 129 | case ELSE: 130 | case FINALLY: 131 | case CATCH: 132 | if (stopAtStatement) 133 | return; 134 | break; 135 | } 136 | nextToken(); 137 | } 138 | } 139 | 140 | 141 | 142 | 143 | 144 | 145 | } 146 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/ast/Parser.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.ast; 2 | 3 | 4 | import work.liziyun.tree.LzyJCCompilationUnit; 5 | import work.liziyun.tree.LzyJCTree; 6 | 7 | public interface Parser { 8 | LzyJCCompilationUnit parseCompilationUnit(); 9 | 10 | LzyJCTree.JCExpression parseExpression(); 11 | 12 | LzyJCTree.JCStatement parseStatement(); 13 | 14 | LzyJCTree.JCExpression parseType(); 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/ast/Statement.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.ast; 2 | 3 | import work.liziyun.tree.LzyJCTree; 4 | import work.liziyun.util.LzyList; 5 | 6 | public interface Statement { 7 | LzyList blockStatements(); 8 | LzyJCTree.JCStatement statement(); 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/code/LzyClassFile.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.code; 2 | 3 | 4 | import work.liziyun.code.type.LzyType; 5 | import work.liziyun.world.LzyName; 6 | import java.io.File; 7 | 8 | public class LzyClassFile { 9 | public static final int JAVA_MAGIC = -889275714; 10 | public static final int CONSTANT_Utf8 = 1; 11 | public static final int CONSTANT_Unicode = 2; 12 | public static final int CONSTANT_Integer = 3; 13 | public static final int CONSTANT_Float = 4; 14 | public static final int CONSTANT_Long = 5; 15 | public static final int CONSTANT_Double = 6; 16 | public static final int CONSTANT_Class = 7; 17 | public static final int CONSTANT_String = 8; 18 | public static final int CONSTANT_Fieldref = 9; 19 | public static final int CONSTANT_Methodref = 10; 20 | public static final int CONSTANT_InterfaceMethodref = 11; 21 | public static final int CONSTANT_NameandType = 12; 22 | public static final int CONSTANT_MethodHandle = 15; 23 | public static final int CONSTANT_MethodType = 16; 24 | public static final int CONSTANT_InvokeDynamic = 18; 25 | public static final int MAX_PARAMETERS = 255; 26 | public static final int MAX_DIMENSIONS = 255; 27 | public static final int MAX_CODE = 65535; 28 | public static final int MAX_LOCALS = 65535; 29 | public static final int MAX_STACK = 65535; 30 | 31 | public LzyClassFile() { 32 | } 33 | 34 | public static byte[] internalize(byte[] var0, int var1, int var2) { 35 | byte[] var3 = new byte[var2]; 36 | 37 | for(int var4 = 0; var4 < var2; ++var4) { 38 | byte var5 = var0[var1 + var4]; 39 | if (var5 == 47) { 40 | var3[var4] = 46; 41 | } else { 42 | var3[var4] = var5; 43 | } 44 | } 45 | 46 | return var3; 47 | } 48 | 49 | public static byte[] internalize(LzyName var0) { 50 | return internalize(var0.getByteArray(), var0.getIndex(), var0.getByteLength()); 51 | } 52 | 53 | public static byte[] externalize(byte[] var0, int var1, int var2) { 54 | byte[] var3 = new byte[var2]; 55 | 56 | for(int var4 = 0; var4 < var2; ++var4) { 57 | byte var5 = var0[var1 + var4]; 58 | if (var5 == 46) { 59 | var3[var4] = 47; 60 | } else { 61 | var3[var4] = var5; 62 | } 63 | } 64 | 65 | return var3; 66 | } 67 | 68 | public static byte[] externalize(LzyName var0) { 69 | return externalize(var0.getByteArray(), var0.getIndex(), var0.getByteLength()); 70 | } 71 | 72 | public static String externalizeFileName(LzyName var0) { 73 | return var0.toString().replace('.', File.separatorChar); 74 | } 75 | public static class NameAndType { 76 | public LzyName name; 77 | public LzyType type; 78 | 79 | public NameAndType(LzyName var1, LzyType var2) { 80 | this.name = var1; 81 | this.type = var2; 82 | } 83 | 84 | public boolean equals(Object var1) { 85 | return var1 instanceof LzyClassFile.NameAndType && this.name == ((LzyClassFile.NameAndType)var1).name && this.type.equals(((LzyClassFile.NameAndType)var1).type); 86 | } 87 | 88 | public int hashCode() { 89 | return this.name.hashCode() * this.type.hashCode(); 90 | } 91 | } 92 | 93 | public static enum Version { 94 | V45_3(45, 3), 95 | V49(49, 0), 96 | V50(50, 0), 97 | V51(51, 0); 98 | 99 | public final int major; 100 | public final int minor; 101 | 102 | private Version(int var3, int var4) { 103 | this.major = var3; 104 | this.minor = var4; 105 | } 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/code/LzyPool.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.code; 2 | 3 | 4 | import work.liziyun.code.symbol.LzyMethodSymbol; 5 | import work.liziyun.code.symbol.LzyVarSymbol; 6 | import java.util.HashMap; 7 | 8 | /** 9 | * 作者: 李滋芸 10 | * 常量池 11 | */ 12 | 13 | interface LzyPoolType{ 14 | int CONSTANT_Utf8_info = 1; 15 | int CONSTANT_Integer_info = 3; 16 | int CONSTANT_Float_info = 4; 17 | int CONSTANT_Long_info = 5; 18 | int CONSTANT_Double_info = 6; 19 | int CONSTANT_Class_info = 7; 20 | int CONSTANT_String_info = 8; 21 | int CONSTANT_Filedref_info = 9; 22 | int CONSTANT_Methodref_info = 10; 23 | int CONSTANT_InterfaceMethodref_info = 11; 24 | int CONSTANT_NameAndType_info =12; 25 | int CONSTANT_MethodHandle_info =15; 26 | int CONSTANT_MethodType_info =16; 27 | int CONSTANT_InvokeDynamic_info =18; 28 | } 29 | 30 | 31 | public class LzyPool { 32 | public static final int MAX_ENTRIES = 65535; 33 | public static final int MAX_STRING_LENGTH= 65535; 34 | int pp; 35 | Object[] pool; 36 | HashMap indices; 37 | 38 | 39 | // 所有的实体个数 40 | public int numEntries(){ 41 | return this.pp; 42 | } 43 | 44 | public LzyPool(){ 45 | this(1,new Object[64]); 46 | } 47 | 48 | private void doublePool(){ 49 | Object[] objects = new Object[this.pool.length * 2]; 50 | System.arraycopy(this.pool,0,objects,0,this.pool.length); 51 | this.pool = objects; 52 | } 53 | 54 | 55 | // 重置操作 56 | public void reset(){ 57 | this.pp = 1; 58 | this.indices.clear(); 59 | } 60 | 61 | public LzyPool(int size,Object[] datas){ 62 | this.pp = size; 63 | this.pool = datas; 64 | indices = new HashMap(datas.length); 65 | for (int i = 0; i < size; i++) { 66 | // 存在数据 67 | if ( datas[i] != null ){ 68 | // key: 值 value: 下标 69 | this.indices.put(datas[i],new Integer(i)); 70 | } 71 | } 72 | } 73 | 74 | 75 | // 获取value值: 即下标 76 | public int get(Object key){ 77 | Integer index = this.indices.get(key); 78 | // 没有找到返回-1 79 | if (index == null){ 80 | return -1; 81 | }else{ 82 | return index; 83 | } 84 | } 85 | 86 | // 放入数据 87 | public int put(Object key){ 88 | // 方法符号 89 | if (key instanceof LzyMethodSymbol){ 90 | // 封装成方法实体 91 | key = new LzyPool.Method((LzyMethodSymbol) key); 92 | }else if (key instanceof LzyVarSymbol){ // 变量符号 93 | key = new LzyPool.Variable((LzyVarSymbol) key); 94 | } 95 | // 获取下标 96 | Integer index = this.indices.get(key); 97 | if (index == null){ 98 | index = new Integer(this.pp); 99 | this.indices.put(key,index); 100 | // 扩容 101 | if (this.pp == this.pool.length){ 102 | this.doublePool(); 103 | } 104 | // 存储 105 | this.pool[this.pp++] = key; 106 | // 如果是数字,那么存储空 107 | if ( key instanceof Long || key instanceof Double ){ 108 | if (this.pp == this.pool.length){ 109 | this.doublePool(); 110 | } 111 | this.pool[this.pp++] = null; 112 | } 113 | } 114 | return index; 115 | } 116 | 117 | // 常量池中的常量项: 方法 118 | static class Method{ 119 | LzyMethodSymbol m; 120 | public int hashCode(){ 121 | int nameCode = this.m.name.hashCode()*33; 122 | int ownerCode = this.m.owner.hashCode()*9; 123 | int typeCode = this.m.type.hashCode(); 124 | return nameCode+ownerCode+typeCode; 125 | } 126 | 127 | public Method(LzyMethodSymbol m) { 128 | this.m = m; 129 | } 130 | public boolean equals(Object obj){ 131 | // 类型不对,直接返回false 132 | if ( !(obj instanceof LzyPool.Method) ){ 133 | return false; 134 | }else{ 135 | // 获取常量项中的方法符号 136 | LzyMethodSymbol methodSymbol = ((Method) obj).m; 137 | // 比较三部分: 1.方法名称 2.方法的所有者 3.方法的类型Type 138 | if (methodSymbol.name == this.m.name && methodSymbol.owner == this.m.owner && methodSymbol.type.equals(this.m.type)){ 139 | return true; 140 | }else { 141 | return false; 142 | } 143 | } 144 | } 145 | } 146 | // 常量池中的常量项: 变量 147 | static class Variable{ 148 | LzyVarSymbol v; 149 | 150 | public Variable(LzyVarSymbol v) { 151 | this.v = v; 152 | } 153 | 154 | public int hashCode(){ 155 | int name = this.v.hashCode()*33; 156 | int owner = this.v.owner.hashCode()*9; 157 | int type = this.v.type.hashCode(); 158 | return name+owner+type; 159 | } 160 | 161 | public boolean equals(Object obj){ 162 | if (!(obj instanceof LzyPool.Variable)){ 163 | return false; 164 | }else{ 165 | LzyVarSymbol varSymbol = ((Variable)obj).v; 166 | //比较内容: 1. 名称 2.所有者 3.类型 167 | return varSymbol.name == this.v.name && varSymbol.owner == this.v.owner && varSymbol.type.equals(this.v.type); 168 | } 169 | } 170 | 171 | } 172 | } 173 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/code/LzyScope.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.code; 2 | 3 | import work.liziyun.code.symbol.LzySymbol; 4 | import work.liziyun.world.LzyName; 5 | 6 | public class LzyScope { 7 | // 外部环境 8 | public LzyScope next; 9 | // 符号所属 10 | public LzySymbol owner; 11 | // 能够访问的其他成员 12 | public LzyScope.Entry[] table; 13 | // 14 | int hashMask; 15 | // 当前作用域下的成员 16 | public LzyScope.Entry elems; 17 | // 大小 18 | public int nelems; 19 | // 初始化大小 20 | private static final int INITIAL_SIZE=128; 21 | // 无效标记成员 22 | private static final LzyScope.Entry sentinel; 23 | // 空作用域 24 | private static final LzyScope emptyScope; 25 | 26 | static { 27 | sentinel = new LzyScope.Entry(null,null,null,null); 28 | emptyScope = new LzyScope(null); 29 | } 30 | 31 | public LzyScope(LzyScope outerScope,LzySymbol ownerSymbol,LzyScope.Entry[] table) { 32 | this.nelems = 0; 33 | this.next = outerScope; 34 | this.owner = ownerSymbol; 35 | this.table = table; 36 | this.hashMask = table.length-1; 37 | this.elems = null; 38 | } 39 | 40 | private void dble(){ 41 | // 能够访问的所有成员: 内部 + 外部 42 | LzyScope.Entry[] ts = this.table; 43 | // 扩容2倍 44 | LzyScope.Entry[] newts = new LzyScope.Entry[ts.length*2]; 45 | // 当前作用域 46 | LzyScope sc = this; 47 | do { 48 | sc.table = newts; 49 | sc.hashMask = newts.length - 1; 50 | // 外部作用域 51 | sc = sc.next; 52 | }while (sc != null); 53 | // 初始化新的数组 54 | for (int i = 0; i < newts.length; i++) { 55 | newts[i] = sentinel; 56 | } 57 | // 旧的数据 复制到 新的中 58 | for (int i = 0; i < ts.length; i++) { 59 | this.copy(ts[i]); 60 | } 61 | 62 | } 63 | 64 | private void copy(LzyScope.Entry oldEntry){ 65 | if (oldEntry.sym != null){ 66 | // 递归处理: hash冲突的链表 67 | this.copy(oldEntry.shadowed); 68 | // 确定下标 69 | int index = oldEntry.sym.name.getIndex() & this.hashMask; 70 | // 连接到冲突的链表上 71 | oldEntry.shadowed = this.table[index]; 72 | // 放入第一个位置 73 | this.table[index] = oldEntry; 74 | } 75 | } 76 | 77 | 78 | // 共享式: table 79 | public LzyScope dup(){ 80 | return new LzyScope(this,this.owner,this.table); 81 | } 82 | 83 | // 非共享式: table 84 | public LzyScope dupUnshared(){ 85 | return new LzyScope(this,this.owner,this.table.clone()); 86 | } 87 | 88 | public LzyScope(LzySymbol owner){ 89 | this(null,owner,new LzyScope.Entry[128]); 90 | for (int i = 0; i < 128; i++) { 91 | this.table[i] = sentinel; 92 | } 93 | } 94 | 95 | 96 | // 情况当前作用域的成员 97 | public LzyScope leave(){ 98 | while (this.elems != null){ 99 | int hash = this.elems.sym.name.getIndex() & this.hashMask; 100 | // 删除: 直接指向hash冲突的下一个! 101 | // 思考: 这么做合理?会不会产生BUG? 102 | // 因为产生冲突的节点,前面也可能有节点。 103 | // 导致误删前一个节点。 104 | // 误删的讨论: 共享式的Table,将会产生混乱! 105 | this.table[hash] = this.elems.shadowed; 106 | // 下一个 107 | this.elems = this.elems.sibling; 108 | } 109 | // 返回外部环境 110 | return this.next; 111 | } 112 | 113 | public LzyScope.Entry lookup(LzyName name){ 114 | LzyScope.Entry e = this.table[name.getIndex()&this.hashMask]; 115 | // 在冲突链表上查找: 解决名称不同产生的hash冲突 116 | while ( e.scope != null && e.sym.name != name ){ 117 | e = e.shadowed; 118 | } 119 | return e; 120 | } 121 | 122 | public void enterIfAbsent(LzySymbol symbol){ 123 | // 复合名称的Entry 124 | LzyScope.Entry e = this.lookup(symbol.name); 125 | // 条件一: 复合当前作用域 条件二: 名称相同,但是类型不同 126 | // 例如: abc的变量,abc的方法 127 | while (e.scope == this && e.sym.kind != symbol.kind){ 128 | // 解决名称相同产生的hash冲突 129 | e.next(); // 如果e找不到,那么返回最后的存储空的Entry 130 | } 131 | 132 | // 作用域不是当前。 133 | // 错误的查找结果: 1. 外部作用域 2.e是空的sentinel 134 | // 正确的查找结果: 1. 作用域一定是当前作用域 135 | if (e.scope != this){ 136 | // 当前作用域下建立符号 137 | this.enter(symbol); 138 | } 139 | 140 | } 141 | 142 | public void enter(LzySymbol symbol){ 143 | this.enter(symbol,this); 144 | } 145 | 146 | // 填充符号到作用域中 147 | public void enter(LzySymbol symbol,LzyScope scope){ 148 | // 扩容 149 | if (this.nelems*3 >= this.hashMask*2){ 150 | this.dble(); 151 | } 152 | // hash 153 | int hash = symbol.name.getIndex() & this.hashMask; 154 | // 建立: 有hash冲突,那么会形成链表 155 | LzyScope.Entry e = new LzyScope.Entry(symbol,this.table[hash],this.elems,scope); 156 | // 放入 157 | this.table[hash] = e; 158 | this.elems = e; 159 | ++this.nelems; 160 | } 161 | 162 | public boolean includes(LzySymbol symbol) { 163 | for(LzyScope.Entry entry = this.lookup(symbol.name); entry.scope == this; entry = entry.next()) { 164 | if (entry.sym == symbol) { 165 | return true; 166 | } 167 | } 168 | return false; 169 | } 170 | 171 | 172 | 173 | public static class Entry{ 174 | public LzySymbol sym; 175 | // 名称相同: 冲突时 176 | public LzyScope.Entry shadowed; 177 | // 下一个 178 | public LzyScope.Entry sibling; 179 | // 作用域 180 | public LzyScope scope; 181 | 182 | 183 | 184 | // 作用: 解析name相同产生的hash冲突 185 | public LzyScope.Entry next(){ 186 | // 冲突链表上寻找: 直到找到名称相同的! 187 | LzyScope.Entry entry = this.shadowed; 188 | while ( entry.scope != null && entry.sym.name != this.sym.name){ 189 | entry = entry.shadowed; 190 | } 191 | return entry; 192 | } 193 | 194 | public Entry(LzySymbol sym, Entry shadowed, Entry sibling, LzyScope scope) { 195 | this.sym = sym; 196 | this.shadowed = shadowed; 197 | this.sibling = sibling; 198 | this.scope = scope; 199 | } 200 | } 201 | 202 | 203 | 204 | // 两个特殊的内部类 205 | public static class ErrorScope extends LzyScope { 206 | public LzyScope dup() { 207 | return new LzyScope.ErrorScope(this, this.owner, this.table); 208 | } 209 | 210 | public LzyScope dupUnshared() { 211 | return new LzyScope.ErrorScope(this, this.owner, (LzyScope.Entry[])this.table.clone()); 212 | } 213 | 214 | public ErrorScope(LzySymbol var1) { 215 | super(var1); 216 | } 217 | 218 | public LzyScope.Entry lookup(LzyName var1) { 219 | LzyScope.Entry var2 = super.lookup(var1); 220 | return var2.scope == null ? new LzyScope.Entry(this.owner, (LzyScope.Entry)null, (LzyScope.Entry)null, (LzyScope)null) : var2; 221 | } 222 | 223 | ErrorScope(LzyScope var1, LzySymbol var2, LzyScope.Entry[] var3) { 224 | super(var1, var2, var3); 225 | } 226 | } 227 | 228 | 229 | 230 | } 231 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/code/symbol/LzyClassSymbol.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.code.symbol; 2 | 3 | 4 | import work.liziyun.code.LzyPool; 5 | import work.liziyun.code.LzyScope; 6 | import work.liziyun.code.type.LzyClassType; 7 | import work.liziyun.code.type.LzyErrorType; 8 | import work.liziyun.code.type.LzyType; 9 | import work.liziyun.code.type.LzyTypeTags; 10 | import work.liziyun.io.LzyJavaFile; 11 | import work.liziyun.tag.LzyFlags; 12 | import work.liziyun.util.LzyList; 13 | import work.liziyun.world.LzyName; 14 | 15 | public class LzyClassSymbol extends LzyTypeSymbol { 16 | public LzyScope members_field; 17 | public LzyName fullname; 18 | public LzyName flatname; 19 | public LzyName sourcefile; 20 | // 两种情况: 1. 压缩包 2.普通文件 21 | public LzyJavaFile classfile; 22 | public LzyPool pool; 23 | private int rank_field; 24 | public static final LzyList emptyList = LzyList.nil(); 25 | 26 | public LzyClassSymbol(long flags_field, LzyName name, LzySymbol symbol){ 27 | this(flags_field,name,new LzyClassType(LzyType.noType,null),symbol); 28 | // 设置Type中Symbol 29 | this.type.tsym = this; 30 | } 31 | 32 | public LzyClassSymbol(long flags_field, LzyName name, LzyType type, LzySymbol symbol) { 33 | super(flags_field, name, type, symbol); 34 | this.rank_field = -1; 35 | this.members_field = null; 36 | this.fullname = formFullName(name,symbol); 37 | this.flatname = formFlatName(name,symbol); 38 | this.sourcefile = null; 39 | this.classfile = null; 40 | this.pool = null; 41 | } 42 | 43 | public void complete(){ 44 | try{ 45 | super.complete(); 46 | }catch(Exception e) { 47 | this.flags_field |= 9; 48 | // 异常时创建错误类型: ErrorType 49 | this.type = new LzyErrorType(this); 50 | throw e; 51 | } 52 | } 53 | 54 | public long flags(){ 55 | if (this.completer != null){ 56 | this.complete(); 57 | } 58 | return this.flags_field; 59 | } 60 | 61 | public LzyScope members(){ 62 | if ( this.completer != null ){ 63 | this.complete(); 64 | } 65 | return this.members_field; 66 | } 67 | 68 | 69 | public LzyName flatName(){ 70 | return this.flatname; 71 | } 72 | 73 | public LzyName fullName(){ 74 | return this.fullname; 75 | } 76 | 77 | @Override 78 | public boolean isSubClass(LzySymbol superSymbol){ 79 | if (this == superSymbol){ 80 | return true; 81 | }else { 82 | LzyType lzyType; 83 | // 接口: 接口间的继承关系 84 | if ( (superSymbol.flags() & LzyFlags.INTERFACE) != 0 ){ 85 | lzyType = this.type; 86 | while (lzyType.tag == LzyTypeTags.CLASS){ 87 | // 当前类的接口 88 | LzyList interfaceList = lzyType.interfaces(); 89 | while (interfaceList.nonEmpty()){ 90 | // 递归寻找 91 | if ( ((LzyType)interfaceList.head).tsym.isSubClass(superSymbol) ){ 92 | return true; 93 | } 94 | // 下一个接口 95 | interfaceList = interfaceList.tail; 96 | } 97 | // 父类 98 | lzyType = lzyType.supertype(); 99 | } 100 | }else{ // 类中的继承关系 101 | lzyType = this.type; 102 | while (lzyType.tag == LzyTypeTags.CLASS){ 103 | if (lzyType.tsym == superSymbol){ 104 | return true; 105 | } 106 | // 父类 107 | lzyType = lzyType.supertype(); 108 | } 109 | } 110 | return false; 111 | } 112 | } 113 | 114 | 115 | 116 | } 117 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/code/symbol/LzyMethodSymbol.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.code.symbol; 2 | 3 | 4 | import work.liziyun.code.LzyCode; 5 | import work.liziyun.code.LzyScope; 6 | import work.liziyun.code.type.LzyType; 7 | import work.liziyun.code.type.LzyTypeTags; 8 | import work.liziyun.tag.LzyFlags; 9 | import work.liziyun.tag.LzyKinds; 10 | import work.liziyun.util.LzyList; 11 | import work.liziyun.world.LzyName; 12 | 13 | 14 | 15 | public class LzyMethodSymbol extends LzySymbol { 16 | 17 | public LzyCode code = null; 18 | public static final LzyList emptyList = LzyList.nil(); 19 | 20 | 21 | // 克隆出一个新对象 22 | @Override 23 | public LzySymbol clone(LzySymbol sym){ 24 | LzyMethodSymbol lzyMethodSymbol = new LzyMethodSymbol(this.flags_field, this.name, this.type, sym); 25 | lzyMethodSymbol.code = this.code; 26 | return lzyMethodSymbol; 27 | } 28 | 29 | // 实现 30 | public LzySymbol implemented(LzyTypeSymbol typeSymbol){ 31 | // 获取所有的接口 32 | LzyList interfaceList = typeSymbol.type.interfaces(); 33 | LzySymbol sym = null; 34 | while ( sym == null && interfaceList.nonEmpty() ){ 35 | LzyTypeSymbol interfaceTypeSymbol = ((LzyType) interfaceList.head).tsym; 36 | // 接口作用域下寻找 37 | LzyScope.Entry entry = interfaceTypeSymbol.members().lookup(this.name); 38 | while (sym == null && entry.scope != null){ 39 | // 重写 40 | boolean overFlag = this.overrides(entry.sym,(LzyTypeSymbol) this.owner); 41 | // 返回值相同 42 | boolean sameReturnFlag = this.type.restype().isSameType(entry.sym.type.restype()); 43 | if (overFlag && sameReturnFlag){ 44 | sym = entry.sym; 45 | } 46 | if (sym == null){ 47 | // 递归: 48 | sym = this.implemented(interfaceTypeSymbol); 49 | } 50 | // 下一个 51 | entry = entry.next(); 52 | } 53 | // 下一个 54 | interfaceList = interfaceList.tail; 55 | } 56 | return sym; 57 | } 58 | 59 | public LzyMethodSymbol implementation(LzyTypeSymbol typeSymbol){ 60 | LzyType type = typeSymbol.type; 61 | while (type.tag == LzyTypeTags.CLASS){ 62 | 63 | LzyTypeSymbol tsym = type.tsym; 64 | 65 | LzyScope.Entry entry = tsym.members().lookup(this.name); 66 | while (entry.scope != null){ 67 | if (entry.sym.kind == LzyKinds.MTH){ 68 | LzyMethodSymbol methodSymbol = (LzyMethodSymbol)entry.sym; 69 | if ( methodSymbol.overrides(this,typeSymbol) ){ 70 | return methodSymbol; 71 | } 72 | } 73 | entry = entry.next(); 74 | } 75 | 76 | // 继承 77 | type = type.supertype(); 78 | } 79 | // 分析: 不可能返回true 80 | if (LzyType.isDerivedRaw(typeSymbol.type)){ 81 | return this.implementation(typeSymbol.type.supertype().tsym); 82 | }else { 83 | return null; 84 | } 85 | } 86 | 87 | @Override 88 | public LzySymbol asMemberOf(LzyType type){ 89 | return new LzyMethodSymbol(this.flags_field,this.name,type.memberType(this),this.owner); 90 | } 91 | 92 | public LzyMethodSymbol binaryImplementation(LzyClassSymbol classSymbol){ 93 | LzyTypeSymbol typeSymbol = classSymbol; 94 | while ( typeSymbol != null){ 95 | LzyScope.Entry entry = typeSymbol.members().lookup(this.name); 96 | while (entry.scope != null){ 97 | if ( entry.sym.kind == LzyKinds.MTH && ((LzyMethodSymbol)entry.sym).binaryOverrides(this,classSymbol) ){ 98 | return (LzyMethodSymbol) entry.sym; 99 | } 100 | // 下一个 101 | entry = entry.next(); 102 | } 103 | // 父类 104 | typeSymbol = typeSymbol.type.supertype().tsym; 105 | } 106 | return null; 107 | } 108 | 109 | 110 | public boolean binaryOverrides(LzySymbol symbol,LzyTypeSymbol typeSymbol){ 111 | // 1. 不是构造方法 2.是一个方法 112 | if ( !this.isConstructor() && symbol.kind == LzyKinds.MTH ){ 113 | if (this == symbol){ 114 | return true; 115 | }else { 116 | LzyMethodSymbol methodSymbol = (LzyMethodSymbol)symbol; 117 | if (methodSymbol.isOverridableIn((LzyTypeSymbol) this.owner)){ 118 | return true; 119 | }else{ 120 | return ((this.flags() & LzyFlags.ABSTRACT)==0) && methodSymbol.isOverridableIn(typeSymbol) && this.isMemberOf(typeSymbol) ; 121 | } 122 | } 123 | }else{ 124 | return false; 125 | } 126 | } 127 | 128 | 129 | /** 130 | * 1. 当前类: 接口中方法 131 | * @param subClassSymbol 实现类 132 | * @return 133 | */ 134 | private boolean isOverridableIn(LzyTypeSymbol subClassSymbol) { 135 | // 接口中方法的修饰符 136 | switch ( (int)(this.flags_field & LzyFlags.AccessFlags) ){ 137 | case 0:// 默认: 本类同包 138 | return this.packge()==subClassSymbol.packge() && ( (subClassSymbol.flags() & LzyFlags.INTERFACE) == 0L ) ; 139 | case LzyFlags.PUBLIC: 140 | return true; 141 | case LzyFlags.PRIVATE: 142 | return false; 143 | default: 144 | throw new AssertionError(); 145 | case LzyFlags.PROTECTED: 146 | // 实现类不是接口 147 | return (subClassSymbol.flags()&LzyFlags.INTERFACE) == 0; 148 | } 149 | } 150 | 151 | /** 152 | * 重写 153 | * 遗留的问题: 返回值的校验,在哪里触发? 154 | * @param symbol 155 | * @param typeSymbol 156 | * @return 157 | */ 158 | public boolean overrides(LzySymbol symbol,LzyTypeSymbol typeSymbol){ 159 | if (!this.isConstructor() && symbol.kind == LzyKinds.MTH ){ 160 | LzyMethodSymbol methodSymbol = (LzyMethodSymbol)symbol; 161 | if ( 162 | // 权限是支持的 163 | methodSymbol.isOverridableIn( (LzyTypeSymbol) this.owner ) 164 | && 165 | // 方法实现所属于类 和 接口中方法所属于类,是继承关系 166 | this.owner.type.asSuper(methodSymbol.owner) != null 167 | && 168 | // 相同的参数: 1. 方法的形式参数 2. 返回值类型 169 | this.type.hasSameArgs(methodSymbol.type) 170 | ){ 171 | return true; 172 | }else{ 173 | // 条件一: 不是抽象 174 | // 条件二: 有权限 175 | // 条件三: 所属关系 176 | // 条件四: 相同的方法参数列表 177 | return ((this.flags() & LzyFlags.ABSTRACT)==0) && methodSymbol.isOverridableIn(typeSymbol) && this.isMemberOf(typeSymbol) && this.type.hasSameArgs(methodSymbol.type) ; 178 | } 179 | }else{ 180 | return false; 181 | } 182 | } 183 | 184 | 185 | public LzyMethodSymbol(long flags_field, LzyName name, LzyType type, LzySymbol symbol) { 186 | super(LzyKinds.MTH, flags_field, name, type, symbol); 187 | } 188 | 189 | public static class OperatorSymbol extends LzyMethodSymbol { 190 | 191 | public int opcode; 192 | 193 | public OperatorSymbol( LzyName name, LzyType type,int opcode, LzySymbol symbol) { 194 | super( (LzyFlags.STATIC|LzyFlags.PUBLIC), name, type, symbol); 195 | this.opcode = opcode; 196 | } 197 | } 198 | } 199 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/code/symbol/LzyPackageSymbol.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.code.symbol; 2 | 3 | import work.liziyun.code.LzyScope; 4 | import work.liziyun.code.type.LzyPackageType; 5 | import work.liziyun.code.type.LzyType; 6 | import work.liziyun.tag.LzyFlags; 7 | import work.liziyun.tag.LzyKinds; 8 | import work.liziyun.world.LzyName; 9 | 10 | public class LzyPackageSymbol extends LzyTypeSymbol { 11 | 12 | public LzyScope members_field; 13 | public LzyName fullname; 14 | 15 | public LzyPackageSymbol(LzyName name,LzySymbol symbol){ 16 | this(name,null,symbol); 17 | this.type = new LzyPackageType(this); 18 | } 19 | 20 | public LzyPackageSymbol( LzyName name, LzyType type, LzySymbol symbol) { 21 | super(LzyFlags.EMPTY, name, type, symbol); 22 | // 设置类型 23 | this.kind = LzyKinds.PCK; 24 | // 成员 25 | this.members_field = null; 26 | // 全限定类名 27 | this.fullname = formFullName(name,symbol); 28 | } 29 | 30 | public long flags(){ 31 | if (this.completer != null){ 32 | this.complete(); 33 | } 34 | return this.flags_field; 35 | } 36 | 37 | 38 | public LzyScope members(){ 39 | if (this.completer != null){ 40 | this.complete(); 41 | } 42 | return this.members_field; 43 | } 44 | 45 | @Override 46 | public LzyName fullName(){ 47 | return this.fullname; 48 | } 49 | 50 | public String toString(){ 51 | return "package "+this.fullname; 52 | } 53 | 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/code/symbol/LzySymbol.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.code.symbol; 2 | 3 | import work.liziyun.code.LzyScope; 4 | import work.liziyun.code.type.LzyMethodType; 5 | import work.liziyun.code.type.LzyType; 6 | import work.liziyun.code.type.LzyTypeTags; 7 | import work.liziyun.tag.LzyFlags; 8 | import work.liziyun.tag.LzyKinds; 9 | import work.liziyun.world.LzyName; 10 | 11 | public class LzySymbol implements LzyFlags, LzyKinds, LzyTypeTags { 12 | // 期望的类型 13 | public int kind; 14 | // 标记 15 | public long flags_field; 16 | // 名称 17 | public LzyName name; 18 | // 所属于 19 | public LzySymbol owner; 20 | // 填充器 21 | public LzySymbol.Completer completer; 22 | // 类型 23 | public LzyType type; 24 | 25 | public LzySymbol(int kind,long flags_field,LzyName name,LzyType type,LzySymbol symbol){ 26 | this.kind = kind; 27 | this.flags_field = flags_field; 28 | this.type = type; 29 | this.owner = symbol; 30 | this.completer = null; 31 | this.name = name; 32 | } 33 | 34 | /** 35 | * 外部的类型 36 | * 注意: 我们并不处理泛型,也不处理内部类外部类 37 | * @return 38 | */ 39 | public LzyType externalType(){ 40 | return type; 41 | } 42 | 43 | 44 | public boolean isInheritedIn(LzySymbol symbol){ 45 | // 当前符号的访问修饰符 46 | switch ( (int)(this.flags_field & LzyFlags.AccessFlags ) ){ 47 | // 缺省 48 | case 0: 49 | // 包符号 50 | LzyPackageSymbol packageSymbol = this.packge(); 51 | Object obj = symbol; 52 | while (obj != null && obj != this.owner){ 53 | if ( ((LzySymbol)obj).packge() != packageSymbol ){ 54 | return false; 55 | } 56 | obj = ((LzySymbol)obj).type.supertype().tsym; 57 | } 58 | // 不是接口 59 | return (symbol.flags()&LzyFlags.INTERFACE) == 0 ; 60 | case LzyFlags.PUBLIC: 61 | return true; 62 | case LzyFlags.PRIVATE: 63 | return this.owner == symbol; 64 | default: 65 | throw new AssertionError(); 66 | case LzyFlags.PROTECTED: 67 | return (symbol.flags() & LzyFlags.INTERFACE) == 0; 68 | 69 | } 70 | } 71 | 72 | /** 73 | * 满足成员关系 74 | * 情况一: 方法属于这个类 75 | * 情况二: 方法所在的类,是这个类的子类 76 | * @param typeSymbol 77 | * @return 78 | */ 79 | public boolean isMemberOf(LzyTypeSymbol typeSymbol){ 80 | // 满足所属关系 81 | if ( this.owner == typeSymbol ){ 82 | return true; 83 | }else if ( typeSymbol.isSubClass(this.owner) && this.isInheritedIn(typeSymbol) && (this.kind == LzyKinds.MTH || !this.hiddenIn((LzyClassSymbol) typeSymbol)) ){// 84 | return true; 85 | } 86 | return false; 87 | } 88 | 89 | 90 | private boolean hiddenIn(LzyClassSymbol classSymbol){ 91 | while (this.owner != classSymbol){ 92 | // 作用域下查找 93 | LzyScope.Entry entry = classSymbol.members().lookup(this.name); 94 | while (entry.scope != null){ 95 | if ( entry.sym.kind == this.kind ){ 96 | return entry.sym != this; 97 | } 98 | entry = entry.next(); 99 | } 100 | // 父类 101 | LzyType supertype = classSymbol.type.supertype(); 102 | if (supertype.tag != LzyTypeTags.CLASS){ 103 | return false; 104 | } 105 | classSymbol = (LzyClassSymbol) supertype.tsym; 106 | } 107 | return false; 108 | } 109 | 110 | 111 | // 调用填充 112 | public void complete(){ 113 | if (this.completer != null){ 114 | LzySymbol.Completer c = this.completer; 115 | // 符号填充只进行一次 116 | this.completer = null; 117 | c.complete(this); 118 | } 119 | } 120 | 121 | public long flags(){ 122 | return this.flags_field; 123 | } 124 | 125 | public LzySymbol clone(LzySymbol var1) { 126 | throw new AssertionError(); 127 | } 128 | 129 | 130 | public interface Completer { 131 | void complete(LzySymbol var1); 132 | } 133 | 134 | public LzyName flatName(){ 135 | return fullName(); 136 | } 137 | 138 | public LzyName fullName() { 139 | return this.name; 140 | } 141 | 142 | 143 | public boolean isConstructor() { 144 | return this.name == this.name.lzyTable.init; 145 | } 146 | 147 | 148 | public boolean isSubClass(LzySymbol superSymbol){ 149 | throw new AssertionError(); 150 | } 151 | 152 | 153 | public LzyMethodType asMethodType() { 154 | throw new AssertionError(); 155 | } 156 | 157 | 158 | public LzySymbol asMemberOf(LzyType type){ 159 | throw new AssertionError(); 160 | } 161 | 162 | /** 163 | * 是否存在: 防止非法强行创建出无效的包 164 | * @return 165 | */ 166 | public boolean exists() { 167 | return (this.flags_field&LzyFlags.EXISTS) != 0; 168 | } 169 | 170 | 171 | // 返回作用域 172 | public LzyScope members(){ 173 | return null; 174 | } 175 | // 包符号 176 | public LzyPackageSymbol packge(){ 177 | LzySymbol symbol = this; 178 | while (symbol.kind != LzyKinds.PCK){ 179 | symbol = symbol.owner; 180 | } 181 | return (LzyPackageSymbol) symbol; 182 | } 183 | 184 | public static class CompletionFailure extends RuntimeException{ 185 | public LzySymbol sym; 186 | public String errmsg; 187 | 188 | public String getMessage(){ 189 | return this.errmsg; 190 | } 191 | 192 | public CompletionFailure(LzySymbol sym, String errmsg) { 193 | this.sym = sym; 194 | this.errmsg = errmsg; 195 | } 196 | } 197 | 198 | } 199 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/code/symbol/LzyTypeSymbol.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.code.symbol; 2 | 3 | import work.liziyun.code.type.LzyType; 4 | import work.liziyun.tag.LzyKinds; 5 | import work.liziyun.world.LzyName; 6 | 7 | public class LzyTypeSymbol extends LzySymbol{ 8 | 9 | public LzyTypeSymbol(long flags_field, LzyName name, LzyType type, LzySymbol symbol) { 10 | super(LzyKinds.TYP, flags_field, name, type, symbol); 11 | } 12 | 13 | // 尝试返回全限定类名 14 | public static LzyName formFullName(LzyName name, LzySymbol symbol) { 15 | if ( symbol == null) { 16 | return name; 17 | } else if ( symbol.kind != LzyKinds.AllKinds && ( symbol.kind & (LzyKinds.MTH|LzyKinds.VAR)) != 0) { 18 | return name; 19 | } else { 20 | LzyName n = symbol.fullName(); 21 | // 拼接全限定类名 22 | if ( n != null && n != n.lzyTable.empty && n != n.lzyTable.emptyPackage ){ 23 | return n.append('.',name); 24 | }else{ 25 | return name; 26 | } 27 | } 28 | } 29 | // 30 | public static LzyName formFlatName(LzyName className,LzySymbol packSymbol){ 31 | if (packSymbol != null && (packSymbol.kind & (LzyKinds.MTH|LzyKinds.VAR)) == 0){ 32 | char c ; 33 | // 如果是一个类型 34 | if ( packSymbol.kind == LzyKinds.TYP ){ 35 | // 考虑内部类的情况 36 | c = '$'; 37 | }else{ 38 | c = '.'; 39 | } 40 | LzyName fullname = packSymbol.flatName(); 41 | // 有包名 42 | if (fullname != null && fullname != fullname.lzyTable.empty && fullname != fullname.lzyTable.emptyPackage ){ 43 | return fullname.append(c,className); 44 | }else{ 45 | // 无包名 46 | return className; 47 | } 48 | }else{ 49 | // 无包名 50 | return className; 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/code/symbol/LzyVarSymbol.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.code.symbol; 2 | 3 | 4 | 5 | import work.liziyun.code.type.LzyType; 6 | import work.liziyun.tag.LzyKinds; 7 | import work.liziyun.util.LzyList; 8 | import work.liziyun.world.LzyName; 9 | 10 | public class LzyVarSymbol extends LzySymbol { 11 | 12 | public int pos ; 13 | public int adr = -1; 14 | public Object constValue; 15 | public static final LzyList emptyList = LzyList.nil(); 16 | 17 | public LzySymbol asMemberOf(LzyType type){ 18 | return new LzyVarSymbol(this.flags_field,this.name,type.memberType(this),this.owner); 19 | } 20 | 21 | public LzyVarSymbol(long flags_field, LzyName name, LzyType type, LzySymbol symbol) { 22 | super(LzyKinds.VAR,flags_field,name,type,symbol); 23 | } 24 | 25 | 26 | // 克隆 27 | @Override 28 | public LzySymbol clone(LzySymbol var1) { 29 | LzyVarSymbol varSymbol = new LzyVarSymbol(this.flags_field, this.name, this.type, var1); 30 | varSymbol.pos = this.pos; 31 | varSymbol.adr = this.adr; 32 | varSymbol.constValue = this.constValue; 33 | return varSymbol; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/code/type/LzyArrayType.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.code.type; 2 | 3 | import work.liziyun.code.symbol.LzyTypeSymbol; 4 | import work.liziyun.world.LzyName; 5 | import work.liziyun.world.LzyTable; 6 | 7 | public class LzyArrayType extends LzyType { 8 | // 数组中元素类型 9 | public LzyType elemtype; 10 | 11 | public LzyArrayType(LzyType elemType, LzyTypeSymbol tsym) { 12 | super(LzyTypeTags.ARRAY, tsym); 13 | this.elemtype = elemType; 14 | } 15 | 16 | public LzyType elemtype() { 17 | return this.elemtype; 18 | } 19 | 20 | public void complete(){ 21 | this.elemtype.complete(); 22 | } 23 | 24 | public int hashCode(){ 25 | return 352+this.elemtype.hashCode(); 26 | } 27 | 28 | 29 | public int dimensions() { 30 | int var1 = 0; 31 | 32 | for(Object var2 = this; ((LzyType)var2).tag == 11; var2 = ((LzyType)var2).elemtype()) { 33 | ++var1; 34 | } 35 | 36 | return var1; 37 | } 38 | 39 | 40 | @Override 41 | public boolean equals(Object obj){ 42 | if (this == obj){ 43 | return true; 44 | }else if ( obj instanceof LzyArrayType && this.elemtype.equals( ((LzyArrayType)obj).elemtype ) ){ 45 | return true; 46 | }else{ 47 | return false; 48 | } 49 | } 50 | 51 | @Override 52 | public boolean isSameType(LzyType type){ 53 | if (this == type) { 54 | return true; 55 | } else if (type.tag >= LzyTypeTags.ERROR) { 56 | // 错误类型 57 | return type.isSameType(this); 58 | } else { 59 | return type.tag == LzyTypeTags.ARRAY && this.elemtype.isSameType(type.elemtype()); 60 | } 61 | } 62 | 63 | 64 | 65 | @Override 66 | public boolean isSubType(LzyType type){ 67 | // 递归结束: 相等 68 | if (this == type){ 69 | return true; 70 | }else if(type.tag >= LzyTypeTags.ERROR){ 71 | // 错误 72 | return type.isSubType(this); 73 | }else if (type.tag == LzyTypeTags.ARRAY){ 74 | // 基本数据类型 75 | if (this.elemtype.tag <= LzyTypeTags.BOOLEAN){ 76 | // 直接相等判断 77 | return this.elemtype.isSameType(type.elemtype()); 78 | }else{// 引用数据类型 79 | // 继承体系中查找: 递归 80 | return this.elemtype.isSubType(type.elemtype()); 81 | } 82 | }else if (type.tag != LzyTypeTags.CLASS){ 83 | return false; 84 | }else { 85 | // 全限定类名 86 | LzyName name = type.tsym.fullName(); 87 | LzyTable lzyTable = name.lzyTable; 88 | // 1.Object 2.Cloneable 3.Serializable 89 | return name == lzyTable.java_lang_Object || name == lzyTable.java_lang_Cloneable || name == lzyTable.java_io_Serializable; 90 | } 91 | } 92 | 93 | 94 | 95 | } 96 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/code/type/LzyClassType.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.code.type; 2 | 3 | 4 | import work.liziyun.code.symbol.LzySymbol; 5 | import work.liziyun.code.symbol.LzyTypeSymbol; 6 | import work.liziyun.tag.LzyFlags; 7 | import work.liziyun.tag.LzyKinds; 8 | import work.liziyun.util.LzyList; 9 | 10 | public class LzyClassType extends LzyType { 11 | 12 | // 外部类型 13 | public LzyType outer_field; 14 | // 继承 15 | public LzyType supertype_field; 16 | // 接口 17 | public LzyList interfaces_field; 18 | 19 | public LzyClassType(LzyType outer_field,LzyTypeSymbol tsym) { 20 | super(CLASS, tsym); 21 | this.outer_field = outer_field; 22 | } 23 | 24 | // 类符号的填充 25 | public void complete(){ 26 | if(this.tsym.completer != null){ 27 | this.tsym.complete(); 28 | } 29 | } 30 | 31 | public LzyType asSuper(LzySymbol superSymbol){ 32 | // 递归结束: 相等时 33 | if (this.tsym == superSymbol){ 34 | return this; 35 | }else{ 36 | // 当前类的父类 37 | LzyType supertype = this.supertype(); 38 | // 39 | if (supertype.tag == LzyTypeTags.CLASS || supertype.tag == LzyTypeTags.ERROR ){ 40 | // 当前类的父类: 递归 41 | LzyType rs = supertype.asSuper(superSymbol); 42 | if (rs != null){ 43 | return rs; 44 | } 45 | } 46 | // 1. 父类是一个接口 2. 当前类也是接口 47 | if ( (superSymbol.flags()& LzyFlags.INTERFACE) != 0){ 48 | LzyList interfaceList = this.interfaces(); 49 | while (interfaceList.nonEmpty()){ 50 | LzyType rs = ((LzyType) interfaceList.head).asSuper(superSymbol); 51 | if (rs != null){ 52 | return rs; 53 | } 54 | interfaceList = interfaceList.tail; 55 | } 56 | } 57 | return null; 58 | } 59 | } 60 | 61 | 62 | public boolean isSuperType(LzyType superType) { 63 | return superType.isSubType(this); 64 | } 65 | 66 | // 继承判断 67 | public boolean isSubType(LzyType superType){ 68 | // 结束递归的地方: 两个类相等! 69 | if (this == superType){ 70 | return true; 71 | }else if (superType.tag >= LzyTypeTags.ERROR){ 72 | return superType.isSubType(this); 73 | }else if (this.tsym == superType.tsym){ 74 | // 字面量类型的引用消除,会创建全新的Type。利用this == superType比较无效! 75 | return true; 76 | }else { 77 | // 比较的类是一个接口 78 | if ( (superType.tsym.flags()&INTERFACE) != 0 ){ 79 | LzyList interfaces = this.interfaces(); 80 | while ( interfaces!=null && interfaces.nonEmpty() ){ 81 | if ( ((LzyType)interfaces.head).isSubType(superType) ){ 82 | return true; 83 | } 84 | // 移动指针 85 | interfaces = interfaces.tail; 86 | } 87 | } 88 | // 当前类的父类 89 | LzyType t = this.supertype(); 90 | // 递归比较: 拿自己的父类。直到两个类相等,那么符合继承关系。 91 | return t.tag == 10 && t.isSubType(superType)?true:t.isErroneous(); 92 | } 93 | } 94 | 95 | 96 | @Override 97 | public LzyType supertype(){ 98 | // 继承为空 99 | if (this.supertype_field == null){ 100 | this.complete(); 101 | // 从符号中获取继承的类型 102 | LzyType type = ((LzyClassType)this.tsym.type).supertype_field; 103 | if (type == null){ 104 | this.supertype_field = noType; 105 | }else if (this == this.tsym.type){ 106 | // 外部封装类型 和 内部封装类型 一致 107 | this.supertype_field = type; 108 | }else{ 109 | this.supertype_field = type; 110 | } 111 | } 112 | return this.supertype_field; 113 | } 114 | 115 | 116 | 117 | public LzyType constType(Object value){ 118 | LzyClassType lzyClassType = new LzyClassType(this.outer_field, this.tsym); 119 | lzyClassType.constValue = value; 120 | return lzyClassType; 121 | } 122 | 123 | 124 | 125 | public LzyList interfaces(){ 126 | if (this.interfaces_field == null){ 127 | this.complete(); 128 | LzyList interfaces_field = ((LzyClassType)this.tsym.type).interfaces_field; 129 | if (interfaces_field == null){ 130 | this.interfaces_field = LzyType.emptyList; 131 | }else if (this == this.tsym.type){ 132 | this.interfaces_field = interfaces_field; 133 | }else{ 134 | this.interfaces_field = interfaces_field; 135 | } 136 | } 137 | return this.interfaces_field; 138 | } 139 | 140 | 141 | @Override 142 | public LzyType memberType(LzySymbol symbol){ 143 | // 这里在尝试擦除泛型 144 | return symbol.type; 145 | } 146 | 147 | @Override 148 | public boolean isSameType(LzyType type){ 149 | if (this == type){ 150 | return true; 151 | }else if (type.tag >= LzyTypeTags.ERROR){ 152 | // 错误类型 153 | return type.isSameType(this); 154 | }else{ 155 | return this.tsym == type.tsym; 156 | } 157 | } 158 | 159 | public LzyType outer(){ 160 | if (this.outer_field == null){ 161 | this.complete(); 162 | this.outer_field = this.tsym.type.outer(); 163 | } 164 | return this.outer_field; 165 | } 166 | 167 | private String className(LzySymbol symbol,boolean bool){ 168 | // 名称长度为0: 匿名实现类 169 | if ( symbol.name.length == 0 ){ 170 | return ""; 171 | }else { 172 | return bool?symbol.fullName().toString():symbol.name.toString(); 173 | } 174 | } 175 | 176 | public String toString(){ 177 | StringBuffer stringBuffer = new StringBuffer(); 178 | // 内部类情况 179 | if (this.outer().tag == LzyTypeTags.CLASS && this.tsym.owner.kind == LzyKinds.TYP){ 180 | stringBuffer.append(this.outer()).toString(); 181 | stringBuffer.append("."); 182 | stringBuffer.append(this.className(this.tsym,false)); 183 | }else { 184 | stringBuffer.append(this.className(this.tsym,true)); 185 | } 186 | return stringBuffer.toString(); 187 | } 188 | 189 | } 190 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/code/type/LzyErrorType.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.code.type; 2 | 3 | import work.liziyun.code.symbol.LzyClassSymbol; 4 | import work.liziyun.tag.LzyKinds; 5 | 6 | 7 | public class LzyErrorType extends LzyClassType{ 8 | 9 | public LzyErrorType(){ 10 | super(null,null); 11 | this.tag = LzyTypeTags.firstPartialTag; 12 | 13 | } 14 | 15 | public LzyErrorType(LzyClassSymbol tsym) { 16 | super( null,tsym); 17 | tsym.type = this; 18 | tsym.kind = LzyKinds.ERR; 19 | 20 | } 21 | 22 | public LzyType elemtype() { 23 | return this; 24 | } 25 | 26 | 27 | public boolean isSameType(LzyType var1) { 28 | return true; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/code/type/LzyMethodType.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.code.type; 2 | 3 | 4 | import work.liziyun.code.symbol.LzyTypeSymbol; 5 | import work.liziyun.util.LzyList; 6 | 7 | public class LzyMethodType extends LzyType implements Cloneable { 8 | public LzyList argtypes; 9 | public LzyType restype; 10 | public LzyList thrown; 11 | public LzyMethodType(LzyList argtypes,LzyType restype,LzyList thrown, LzyTypeSymbol tsym) { 12 | super(LzyTypeTags.METHOD, tsym); 13 | this.argtypes = argtypes; 14 | this.restype = restype; 15 | this.thrown = thrown; 16 | } 17 | 18 | 19 | public LzyType restype() { 20 | return this.restype; 21 | } 22 | 23 | public LzyList argtypes() { return this.argtypes; } 24 | 25 | 26 | public LzyList thrown() { return this.thrown; } 27 | public void setThrown(LzyList thrown) { 28 | this.thrown = thrown; 29 | } 30 | 31 | public LzyMethodType asMethodType(){ 32 | return this; 33 | } 34 | 35 | public int hashCode(){ 36 | int code = 12; 37 | LzyList argList = this.argtypes; 38 | while (argList.tail != null){ 39 | // 疑问: 逻辑障碍,计算当前hashcode的前提是下一个节点的存在! 40 | code = (code<<5) + ((LzyType)argList.head).hashCode(); 41 | // 下一个 42 | argList = argList.tail; 43 | } 44 | return (code << 5) + this.restype.hashCode(); 45 | } 46 | 47 | 48 | 49 | // 调用出: LzyPool.Method.equals() 50 | public boolean equals(Object obj){ 51 | // 一样直接返回true 52 | if (this == obj){ 53 | return true; 54 | }else if ( !(obj instanceof LzyMethodType) ){ // 不是方法类型,直接返回false 55 | return false; 56 | }else{ 57 | // 方法类型 58 | LzyMethodType methodType = (LzyMethodType) obj; 59 | // 目标: 方法的参数列表 60 | LzyList targetArgList = this.argtypes; 61 | // 当前: 方法的参数列表 62 | LzyList currentArgList = methodType.argtypes; 63 | // 存在的问题: 如果下一个为null,那个当前这个将不会调用equals方法 64 | // 例: 最后一个会错过比较的机会,因为下一个为null,那么equals方法将会短路掉 65 | // 辩证: 也许存在一个默认的结尾! 66 | while (targetArgList.tail != null && currentArgList.tail != null && ((LzyType)targetArgList.head).equals(currentArgList.head)){ 67 | // 下一个 68 | targetArgList = targetArgList.tail; 69 | currentArgList = currentArgList.tail; 70 | } 71 | // 注意: 如果方法的参数全部都相等,那么最后一定会移动到null 72 | // 接着比较: 方法的返回值 73 | if (targetArgList.tail == null && currentArgList.tail == null){ 74 | return this.restype.equals(methodType.restype); 75 | }else { 76 | return false; 77 | } 78 | } 79 | } 80 | 81 | 82 | // 符号填充 83 | public void complete(){ 84 | // 形参列表的填充 85 | LzyList argTypeList = this.argtypes; 86 | while ( argTypeList.nonEmpty() ){ 87 | ((LzyType)argTypeList.head).complete(); 88 | argTypeList = argtypes.tail; 89 | } 90 | // 返回类型 91 | this.restype.complete(); 92 | // 异常 93 | LzyList thrownList = this.thrown; 94 | while ( thrownList.nonEmpty() ){ 95 | ((LzyType)thrownList.head).complete(); 96 | thrownList = thrownList.tail; 97 | } 98 | } 99 | 100 | 101 | /** 102 | * 1. 形式参数 103 | * 2. 返回值类型 104 | * @param type 105 | * @return 106 | */ 107 | @Override 108 | public boolean isSameType(LzyType type){ 109 | return this.hasSameArgs(type) && this.restype.isSameType(type.restype()); 110 | } 111 | 112 | 113 | /** 114 | * 方法的形式参数相同判断 115 | * @param type 116 | * @return 117 | */ 118 | @Override 119 | public boolean hasSameArgs(LzyType type){ 120 | return type.tag == LzyTypeTags.METHOD && isSameTypes(this.argtypes,type.argtypes()); 121 | } 122 | 123 | 124 | /** 125 | * 两个方法的形式参数: 相同判断 126 | * @param methodArgs01 127 | * @param methodArgs02 128 | * @return 129 | */ 130 | public static boolean isSameTypes(LzyList methodArgs01, LzyList methodArgs02) { 131 | while (methodArgs01.tail != null && methodArgs02.tail !=null ){ 132 | ((LzyType)methodArgs01.head).isSameType((LzyType)methodArgs02.head); 133 | methodArgs01 = methodArgs01.tail; 134 | methodArgs02 = methodArgs02.tail; 135 | } 136 | return methodArgs01.tail == null && methodArgs02.tail == null; 137 | } 138 | 139 | 140 | public String toString() { 141 | return "(" + this.argtypes.toString() + ")" + this.restype; 142 | } 143 | 144 | 145 | } 146 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/code/type/LzyPackageType.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.code.type; 2 | 3 | import work.liziyun.code.symbol.LzyTypeSymbol; 4 | 5 | public class LzyPackageType extends LzyType { 6 | 7 | public LzyPackageType(LzyTypeSymbol typeSymbol) { 8 | super(LzyTypeTags.PACKAGE, typeSymbol); 9 | } 10 | 11 | public boolean isSameType(LzyType type){ 12 | return type==this; 13 | } 14 | 15 | public String toString(){ 16 | return this.tsym.fullName().toString(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/code/type/LzyType.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.code.type; 2 | 3 | 4 | import work.liziyun.code.symbol.LzySymbol; 5 | import work.liziyun.code.symbol.LzyTypeSymbol; 6 | import work.liziyun.tag.LzyFlags; 7 | import work.liziyun.tag.LzyKinds; 8 | import work.liziyun.util.LzyList; 9 | 10 | public class LzyType implements LzyFlags, LzyKinds,LzyTypeTags { 11 | 12 | // 常量的类型: 没有类型 13 | public static final LzyType noType ; 14 | // Type的标识 15 | public int tag; 16 | // Type的符号: 1. 包符号 2.类符号 17 | public LzyTypeSymbol tsym; 18 | // 空数组 19 | public static final LzyList emptyList; 20 | // 常量值 21 | public Object constValue = null; 22 | static { 23 | noType = new LzyType(LzyTypeTags.NONE,null); 24 | emptyList = LzyList.nil(); 25 | 26 | } 27 | // 构造方法 28 | public LzyType(int tag, LzyTypeSymbol tsym) { 29 | this.tag = tag; 30 | this.tsym = tsym; 31 | } 32 | 33 | public LzyType outer(){ 34 | return null; 35 | } 36 | 37 | public int dimensions() { 38 | return 0; 39 | } 40 | 41 | 42 | /** 43 | * byte char short int 的自动转换检查 44 | * @param 45 | * @return 46 | */ 47 | public boolean isAssignable(LzyType targetType){ 48 | // 当前类型是整形,并且有初始化值. --> 范围校验! 49 | if ( this.tag <= LzyTypeTags.INT && this.constValue != null ){ 50 | int value = ((Number)this.constValue).intValue(); 51 | // 传递的类型 52 | switch (targetType.tag){ 53 | // 传递的类型是Byte 54 | case LzyTypeTags.BYTE: 55 | if ( Byte.MIN_VALUE <= value && value <= Byte.MAX_VALUE ){ 56 | return true; 57 | } 58 | break; 59 | // 传递的类型是Char 60 | case LzyTypeTags.CHAR: 61 | if ( Character.MIN_VALUE <= value && value <= Character.MAX_VALUE ){ 62 | return true; 63 | } 64 | break; 65 | // 传递的类型是Short 66 | case LzyTypeTags.SHORT: 67 | if ( Short.MIN_VALUE <= value && value <= Short.MAX_VALUE ){ 68 | return true; 69 | } 70 | break; 71 | // 传递的类型是Int 72 | case LzyTypeTags.INT: 73 | return true; 74 | } 75 | } 76 | // 类型转换校验 77 | return this.isSubType(targetType); 78 | } 79 | 80 | 81 | public LzyType baseType(){ 82 | return this.constValue == null ? this:this.tsym.type; 83 | } 84 | 85 | 86 | // 接口 87 | public LzyList interfaces(){ 88 | return emptyList; 89 | } 90 | 91 | // 填充: 空实现 92 | public void complete(){ 93 | 94 | } 95 | 96 | 97 | public LzyType constType(Object constValue){ 98 | // 基本数据类型 99 | if ( this.tag <= LzyTypeTags.BOOLEAN ){ 100 | LzyType lzyType = new LzyType(this.tag, this.tsym); 101 | lzyType.constValue = constValue; 102 | return lzyType; 103 | } 104 | throw new AssertionError(); 105 | } 106 | 107 | public LzyMethodType asMethodType() { 108 | throw new AssertionError(); 109 | } 110 | 111 | public String stringValue(){ 112 | if (this.tag == LzyTypeTags.BOOLEAN){ 113 | return ((Integer)this.constValue) == 0?"false":"true"; 114 | }else{ 115 | return this.tag == LzyTypeTags.CHAR?String.valueOf(this.constValue):this.constValue.toString(); 116 | } 117 | } 118 | 119 | 120 | // 121 | public LzyType asSuper(LzySymbol sym){ 122 | return null; 123 | } 124 | 125 | // 原始类型判断: 泛型的擦除相关 126 | public boolean isRaw(){ 127 | return false; 128 | } 129 | 130 | public static boolean isRaw(LzyList LzyList){ 131 | return false; 132 | } 133 | 134 | public static boolean isDerivedRaw(LzyType type){ 135 | if (type.isRaw()){ 136 | return true; 137 | }else if ( type.supertype()!=null && isDerivedRaw(type.supertype()) ){ 138 | return true; 139 | }else if ( isDerivedRaw(type.interfaces()) ){ 140 | return true; 141 | } 142 | return false; 143 | } 144 | 145 | 146 | /** 147 | * 如果所有接口中有一个true,那么整个方法返回true 148 | * @param LzyList 149 | * @return 150 | */ 151 | public static boolean isDerivedRaw(LzyList LzyList){ 152 | LzyList interfaceList = LzyList; 153 | while ( interfaceList.nonEmpty() && !isDerivedRaw((LzyType) LzyList.head) ){ 154 | interfaceList = interfaceList.tail; 155 | } 156 | return interfaceList.nonEmpty(); 157 | } 158 | 159 | 160 | // 常量类型的值: 是否为true 161 | public boolean isTrue(){ 162 | if ( this.tag == BOOLEAN && this.constValue != null && (int)this.constValue != 0 ){ 163 | return true; 164 | } 165 | return false; 166 | } 167 | 168 | public boolean isSuperType(LzyType lzyType) { 169 | return lzyType.isSubType(this); 170 | } 171 | // 继承 172 | public boolean isSubType(LzyType superType){ 173 | if (this == superType){ 174 | return true; 175 | }else if (superType.tag >= 18){ 176 | // 错误类型 177 | return superType.isSuperType(this); 178 | }else if (this.tsym == superType.tsym){ 179 | // 由于标识符的引用消除,会创建出一个新的类型Type。所以无法利用this==superType判断成功! 180 | return true; 181 | }else{ 182 | // 判断当前符号类型 183 | switch (this.tag){ 184 | case LzyTypeTags.BYTE: 185 | case LzyTypeTags.CHAR: 186 | // 父类成立条件第一种: 相等 187 | // 父类成立条件第二种: 相差至少为2,且不超过double ---> 排除short的情况 188 | return this.tag == superType.tag || this.tag+2 <= superType.tag && superType.tag <= LzyTypeTags.DOUBLE; 189 | case LzyTypeTags.SHORT: 190 | case LzyTypeTags.INT: 191 | case LzyTypeTags.LONG: 192 | case LzyTypeTags.FLOAT: 193 | case LzyTypeTags.DOUBLE: 194 | // 基本数据类型的父类 195 | return this.tag <= superType.tag && superType.tag <= 7; 196 | case LzyTypeTags.BOOLEAN: 197 | case LzyTypeTags.VOID: 198 | return this.tag == superType.tag; 199 | // null空指针的类型 200 | case LzyTypeTags.BOT: 201 | return superType.tag == LzyTypeTags.BOT || superType.tag == LzyTypeTags.CLASS || superType.tag == LzyTypeTags.ARRAY; 202 | // 引用数据类型的比较: 在LzyClassType 或者 LzyArrayType中 203 | default: 204 | System.out.println("编译错误: isSubType应该在LzyClassType或LzyArrayType中!"); 205 | return false; 206 | } 207 | } 208 | } 209 | 210 | public boolean isErroneous(){ 211 | return false; 212 | } 213 | 214 | public LzyType elemtype() { 215 | return null; 216 | } 217 | 218 | public LzyType restype() { return null; } 219 | 220 | public LzyList argtypes() { 221 | return emptyList; 222 | } 223 | 224 | public LzyList thrown() { 225 | return emptyList; 226 | } 227 | 228 | 229 | public LzyType supertype(){ 230 | return null; 231 | } 232 | 233 | 234 | public LzyType memberType(LzySymbol sym){ 235 | // 这里尝试擦除泛型 236 | return sym.type; 237 | } 238 | 239 | // 240 | public boolean isSameType(LzyType type){ 241 | if (this == type){ 242 | return true; 243 | }else if (type.tag >= LzyTypeTags.ERROR){ 244 | // 错误类型的处理 245 | return type.isSameType(this); 246 | }else { 247 | switch (this.tag) { 248 | case LzyTypeTags.BYTE: 249 | case LzyTypeTags.CHAR: 250 | case LzyTypeTags.SHORT: 251 | case LzyTypeTags.INT: 252 | case LzyTypeTags.LONG: 253 | case LzyTypeTags.FLOAT: 254 | case LzyTypeTags.DOUBLE: 255 | case LzyTypeTags.VOID: 256 | case LzyTypeTags.BOT: 257 | case LzyTypeTags.NONE: 258 | return this.tag == type.tag; 259 | default: 260 | throw new AssertionError(); 261 | } 262 | } 263 | } 264 | 265 | 266 | // 方法的重写: 相同参数 267 | public boolean hasSameArgs(LzyType type){ 268 | throw new AssertionError(); 269 | } 270 | 271 | public static boolean isSubTypes(LzyList subTypeList,LzyList pubTypeList){ 272 | while (subTypeList.tail != null && pubTypeList.tail != null && subTypeList.head.isSubType(pubTypeList.head) ) { 273 | subTypeList = subTypeList.tail; 274 | pubTypeList = pubTypeList.tail; 275 | } 276 | return subTypeList.tail == null && pubTypeList.tail == null; 277 | } 278 | 279 | public String toString(){ 280 | String rs = null; 281 | if ( this.tsym!=null && this.tsym.name != null ){ 282 | rs = this.tsym.name.toString(); 283 | }else{ 284 | rs = "null"; 285 | } 286 | return rs; 287 | } 288 | 289 | } 290 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/code/type/LzyTypeParameter.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.code.type; 2 | 3 | 4 | import work.liziyun.tree.LzyJCTree; 5 | import work.liziyun.util.LzyList; 6 | 7 | public class LzyTypeParameter extends LzyJCTree { 8 | public static final LzyList emptyList = LzyList.nil(); 9 | 10 | public LzyTypeParameter() { 11 | super(TYPEPARAMETER); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/code/type/LzyTypeTags.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.code.type; 2 | 3 | /** 4 | * Type的标识符 5 | * 6 | * 参考标准: jdk1.4 7 | */ 8 | public interface LzyTypeTags { 9 | // 基本数据类型 10 | int BYTE = 1; 11 | int CHAR = 2; 12 | int SHORT = 3; 13 | int INT = 4; 14 | int LONG = 5; 15 | int FLOAT = 6; 16 | int DOUBLE = 7; 17 | int BOOLEAN = 8; 18 | // 引用数据类型 19 | int VOID = 9; // 无返回值 20 | int CLASS = 10; // 1. 类 2.接口 21 | int ARRAY = 11; // 数组 22 | int METHOD = 12; // 方法 23 | int PACKAGE = 13; // 包 24 | int BOT = 16; // null空指针类型 25 | int NONE = 17; // 无类型 26 | int ERROR = 18; // 错误类型 27 | int UNKNOWN = 19; // 没有找到 28 | int UNDETVAR = 20; // 实例化类型变量的标记 29 | int TypeTagCount = 21; // 数字类型 30 | int lastBaseTag = 8; // 基本数据类型最大值标记 31 | int firstPartialTag = 18; // 基本数据类型最小标记 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/comp/LzyAttrContext.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.comp; 2 | 3 | 4 | import work.liziyun.code.LzyScope; 5 | import work.liziyun.util.LzyList; 6 | 7 | public class LzyAttrContext { 8 | // 局部变量符号的作用域 9 | LzyScope scope = null; 10 | 11 | int staticLevel = 0; 12 | // 是否this或super调用的环境 13 | boolean isSelfCall = false; 14 | // 当前函数应用程序的参数是否已装箱到varargs的数组中 15 | boolean rawArgs = false; 16 | // 上下文环境中全部的类型变量列表 17 | LzyList tvars; 18 | 19 | public LzyAttrContext() { 20 | this.tvars = LzyList.nil(); 21 | } 22 | 23 | LzyAttrContext dup() { 24 | return this.dup(this.scope); 25 | } 26 | 27 | LzyAttrContext dup(LzyScope var1) { 28 | LzyAttrContext var2 = new LzyAttrContext(); 29 | // 设置新的Scope作用域 30 | var2.scope = var1; 31 | // 其他属性全部拷贝 32 | var2.staticLevel = this.staticLevel; 33 | var2.isSelfCall = this.isSelfCall; 34 | 35 | var2.rawArgs = this.rawArgs; 36 | var2.tvars = this.tvars; 37 | return var2; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/comp/LzyCheck.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.comp; 2 | 3 | 4 | import work.liziyun.code.symbol.LzyMethodSymbol; 5 | import work.liziyun.code.symbol.LzySymbol; 6 | import work.liziyun.code.symbol.LzyTypeSymbol; 7 | import work.liziyun.code.type.LzyClassType; 8 | import work.liziyun.code.type.LzyType; 9 | import work.liziyun.code.type.LzyTypeTags; 10 | import work.liziyun.tag.LzyByteCodes; 11 | import work.liziyun.tag.LzyFlags; 12 | import work.liziyun.util.LzyContext; 13 | import work.liziyun.util.LzyList; 14 | import work.liziyun.world.LzyTable; 15 | 16 | public class LzyCheck { 17 | private static final LzyContext.Key key = new LzyContext.Key(); 18 | 19 | private LzyTable names; 20 | 21 | public static LzyCheck instance(LzyContext LzyContext) { 22 | LzyCheck check = (LzyCheck)LzyContext.get(key); 23 | if (check == null) { 24 | check = new LzyCheck(LzyContext); 25 | } 26 | return check; 27 | } 28 | 29 | public LzyCheck(LzyContext LzyContext) { 30 | this.names = LzyTable.instance(LzyContext); 31 | } 32 | 33 | 34 | /** 35 | * 检查类型是 类 还是 接口 36 | * @param pos 37 | * @param type 38 | * @return 39 | */ 40 | LzyType checkClassType(int pos, LzyType type){ 41 | // 检查是否Class 42 | if ( type.tag != LzyTypeTags.CLASS && type.tag != LzyTypeTags.NONE){ 43 | System.out.println("编译错误: 期望Type是一个TypeTag.Class,可能是一个接口或类"); 44 | return null; 45 | }else{ 46 | return type; 47 | } 48 | } 49 | 50 | /** 51 | * 检查修饰符: 1. 是否合法 2. 缺省的修饰符添加进去 52 | * @param var1 53 | * @param var2 54 | * @param var4 55 | * @return 56 | */ 57 | long checkFlags(int var1, long var2, LzySymbol var4) { 58 | long var7 = 0L; 59 | long var5; 60 | switch(var4.kind) { 61 | case 2: 62 | if (var4.owner.kind != 2) { 63 | var5 = 3601L; 64 | } else { 65 | var5 = 3607L; 66 | if (var4.owner.owner.kind == 1 || (var4.owner.flags_field & 8L) != 0L) { 67 | var5 |= 8L; 68 | } 69 | 70 | if ((var2 & 512L) != 0L) { 71 | var7 = 8L; 72 | } 73 | } 74 | 75 | if ((var2 & 512L) != 0L) { 76 | var7 |= 1024L; 77 | } 78 | 79 | var7 |= var4.owner.flags_field & 2048L; 80 | break; 81 | case 4: 82 | if (var4.owner.kind != 2) { 83 | var5 = 8589934608L; 84 | } else if ((var4.owner.flags_field & 512L) != 0L) { 85 | var7 = 25L; 86 | var5 = 25L; 87 | } else { 88 | var5 = 223L; 89 | } 90 | break; 91 | case 16: 92 | if (var4.name == this.names.init) { 93 | var5 = 7L; 94 | } else if ((var4.owner.flags_field & 512L) != 0L) { 95 | var7 = 1025L; 96 | var5 = 1025L; 97 | } else { 98 | var5 = 3391L; 99 | } 100 | 101 | if (((var2 | var7) & 1024L) == 0L) { 102 | var7 |= var4.owner.flags_field & 2048L; 103 | } 104 | break; 105 | default: 106 | throw new AssertionError(); 107 | } 108 | 109 | long var9 = var2 & 4095L & ~var5; 110 | 111 | return var2 & (var5 | -4096L) | var7; 112 | } 113 | 114 | /** 115 | * 除0异常的检查 116 | * @param operator 117 | * @param operand 118 | */ 119 | void checkDivZero( LzySymbol operator, LzyType operand) { 120 | if (operand.constValue != null 121 | && ((Number) (operand.constValue)).longValue() == 0) { 122 | int opc = ((LzyMethodSymbol.OperatorSymbol)operator).opcode; 123 | if (opc == LzyByteCodes.idiv || opc == LzyByteCodes.imod 124 | || opc == LzyByteCodes.ldiv || opc == LzyByteCodes.lmod) { 125 | System.out.println("编译错误: 除数不能是0"); 126 | } 127 | } 128 | } 129 | 130 | LzyType checkNonCyclic(int i,LzyType type){ 131 | // 类符号 132 | LzyTypeSymbol typeSymbol = ((LzyType)type).tsym; 133 | 134 | if ( (typeSymbol.flags_field& LzyFlags.LOCKED) != 0 ){ 135 | System.out.println("编译错误: 上锁LOCK"+type.tsym.name.toString()); 136 | }else{ 137 | // 如果有ACYCLIC修饰: 即无环 138 | if ( (typeSymbol.flags_field&LzyFlags.ACYCLIC) != 0 ){ 139 | return type; 140 | } 141 | // 非错误类型 142 | if ( !typeSymbol.type.isErroneous() ){ 143 | try { 144 | // 上锁操作 145 | typeSymbol.flags_field |= LzyFlags.LOCKED; 146 | // 接口 147 | // 注意: interfaces() ---> 如果没有接口,那么会触发类的加载! 148 | LzyList interList = typeSymbol.type.interfaces(); 149 | while ( interList.nonEmpty() ){ 150 | interList.head = checkNonCyclic(i , (LzyType) interList.head ); 151 | //下一个 152 | interList = interList.tail; 153 | } 154 | // 继承 155 | LzyType supertype = typeSymbol.type.supertype(); 156 | // 如果父类 157 | if (supertype != null && supertype.tag == LzyTypeTags.CLASS ){ 158 | // 递归 159 | ((LzyClassType)typeSymbol.type).supertype_field = this.checkNonCyclic(i,supertype); 160 | } 161 | }finally { 162 | // 清除锁标记 163 | typeSymbol.flags_field &= (-(LzyFlags.LOCKED+1)); 164 | } 165 | } 166 | } 167 | // 标记无环 168 | typeSymbol.flags_field |= LzyFlags.ACYCLIC; 169 | return type; 170 | } 171 | 172 | 173 | } 174 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/comp/LzyEnv.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.comp; 2 | 3 | import work.liziyun.tree.LzyJCCompilationUnit; 4 | import work.liziyun.tree.LzyJCMethodDef; 5 | import work.liziyun.tree.LzyJCTree; 6 | import work.liziyun.tree.state.LzyJCClassDef; 7 | 8 | public class LzyEnv { 9 | 10 | // 下一个封闭环境 11 | public LzyEnv next = null; 12 | // 包含当前类的环境 13 | public LzyEnv outer = null; 14 | // 环境相关的树 15 | public LzyJCTree tree; 16 | // 封闭的编译单元 17 | public LzyJCCompilationUnit toplevel; 18 | // 下一个封闭类的定义 19 | public LzyJCClassDef enclClass; 20 | // 下一孤封闭的方法定义 21 | public LzyJCMethodDef enclMethod; 22 | // 用于进一步信息的通用字段 23 | public A info; 24 | 25 | public LzyEnv enclosing(int var1) { 26 | LzyEnv var2; 27 | for(var2 = this; var2 != null && var2.tree.getTag() != var1; var2 = var2.next) { 28 | } 29 | return var2; 30 | } 31 | 32 | public LzyEnv dupto(LzyEnv var1) { 33 | // 新环境的下一个封闭环境是自己 34 | var1.next = this; // 新环境的下一个: 当前环境 35 | var1.outer = this.outer; // 新环境的外部: 当前环境的外部(很有可能是编译单元!) 36 | var1.toplevel = this.toplevel; 37 | var1.enclClass = this.enclClass; 38 | var1.enclMethod = this.enclMethod; 39 | return var1; 40 | } 41 | 42 | public LzyEnv dup(LzyJCTree var1) { 43 | return this.dup(var1, this.info); 44 | } 45 | 46 | public LzyEnv(LzyJCTree var1, A var2) { 47 | this.tree = var1; 48 | this.toplevel = null; 49 | this.enclClass = null; 50 | this.enclMethod = null; 51 | this.info = var2; 52 | } 53 | 54 | public LzyEnv dup(LzyJCTree var1, Object var2) { 55 | return this.dupto(new LzyEnv(var1, var2)); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/comp/LzyInfer.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.comp; 2 | 3 | import work.liziyun.code.type.LzyType; 4 | import work.liziyun.code.type.LzyTypeTags; 5 | import work.liziyun.tag.LzyFlags; 6 | import work.liziyun.tag.LzyKinds; 7 | 8 | public class LzyInfer implements LzyKinds, LzyFlags, LzyTypeTags { 9 | public static final LzyType anyPoly = new LzyType(LzyTypeTags.NONE,null); 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/comp/LzyTodo.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.comp; 2 | 3 | 4 | import work.liziyun.util.LzyContext; 5 | import work.liziyun.util.LzyListBuffer; 6 | 7 | public class LzyTodo extends LzyListBuffer { 8 | private static final LzyContext.Key todoKey = new LzyContext.Key(); 9 | 10 | private LzyTodo(LzyContext var1) { 11 | var1.put(todoKey, this); 12 | } 13 | 14 | public Object first() { 15 | return super.first(); 16 | } 17 | 18 | public Object next() { 19 | return super.next(); 20 | } 21 | 22 | public boolean contains(Object var1) { 23 | return super.contains((LzyEnv)var1); 24 | } 25 | 26 | public static LzyTodo instance(LzyContext var0) { 27 | LzyTodo var1 = (LzyTodo)var0.get(todoKey); 28 | if (var1 == null) { 29 | var1 = new LzyTodo(var0); 30 | } 31 | 32 | return var1; 33 | } 34 | 35 | public LzyListBuffer append(Object var1) { 36 | return super.append((LzyEnv)var1); 37 | } 38 | 39 | public LzyListBuffer prepend(Object var1) { 40 | return super.prepend((LzyEnv)var1); 41 | } 42 | 43 | public LzyListBuffer appendArray(Object[] var1) { 44 | return super.appendArray((LzyEnv[])var1); 45 | } 46 | 47 | public Object[] toArray(Object[] var1) { 48 | return super.toArray((LzyEnv[])var1); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/io/LzyJavaFile.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.io; 2 | 3 | import java.io.File; 4 | import java.io.FileInputStream; 5 | import java.io.IOException; 6 | import java.io.InputStream; 7 | import java.util.zip.ZipEntry; 8 | import java.util.zip.ZipFile; 9 | 10 | public interface LzyJavaFile { 11 | // 修改时间: 判断文件是否改动 12 | long lastMod(); 13 | // 简单类名: xxx.class 14 | String getSimpleName(); 15 | // 文件名 16 | String getFileName(); 17 | // 获取文件路径 18 | String getPath(); 19 | // IO流 20 | InputStream open() throws IOException; 21 | // 获取文件类型 22 | Kind getKind(); 23 | enum Kind { 24 | SOURCE(".java"), 25 | CLASS(".class"), 26 | HTML(".html"), 27 | OTHER(""); 28 | public final String extension; 29 | private Kind(String extension) { 30 | this.extension = extension; 31 | } 32 | }; 33 | 34 | 35 | /** 36 | * 压缩包文件 37 | */ 38 | class JarFile implements LzyJavaFile { 39 | // 简单类名 40 | private String simpleName; 41 | // 文件名 42 | private String fileName; 43 | // 目录(压缩包) 44 | private ZipFile zipFile; 45 | // 文件(压缩包中文件) 46 | private ZipEntry zipEntry; 47 | // 类型 48 | private Kind kind; 49 | 50 | public JarFile(String fileName, ZipFile zipFile, ZipEntry zipEntry) { 51 | this.fileName = fileName; 52 | this.zipFile = zipFile; 53 | this.zipEntry = zipEntry; 54 | if (fileName.endsWith(".class")){ 55 | kind = Kind.CLASS; 56 | this.simpleName = this.fileName.substring(0,this.fileName.length()-kind.extension.length()); 57 | }else{ 58 | kind = Kind.SOURCE; 59 | this.simpleName = this.fileName.substring(0,this.fileName.length()-kind.extension.length()); 60 | } 61 | } 62 | 63 | @Override 64 | public long lastMod() { 65 | return zipEntry.getTime(); 66 | } 67 | 68 | @Override 69 | public String getSimpleName() { 70 | return simpleName; 71 | } 72 | 73 | @Override 74 | public String getFileName() { 75 | return fileName; 76 | } 77 | 78 | 79 | @Override 80 | public String getPath() { 81 | // 压缩包(文件) 82 | return zipFile.getName() +"(" + zipEntry.getName() + ")"; 83 | 84 | } 85 | 86 | @Override 87 | public InputStream open() throws IOException { 88 | return this.zipFile.getInputStream(this.zipEntry); 89 | } 90 | 91 | @Override 92 | public Kind getKind() { 93 | return kind; 94 | } 95 | } 96 | 97 | /** 98 | * 普通文件 99 | */ 100 | class CommonFile implements LzyJavaFile { 101 | // 文件名称: xxx.class 102 | private String simpleName; 103 | // 104 | private String fileName; 105 | // 文件 106 | private File file; 107 | // 类型 108 | private Kind kind; 109 | 110 | public CommonFile(String fileName, File file) { 111 | this.fileName = fileName; 112 | this.file = file; 113 | if (fileName.endsWith(".class")){ 114 | kind = Kind.CLASS; 115 | this.simpleName = this.fileName.substring(0,this.fileName.length()-kind.extension.length()); 116 | }else{ 117 | kind = Kind.SOURCE; 118 | this.simpleName = this.fileName.substring(0,this.fileName.length()-kind.extension.length()); 119 | } 120 | } 121 | 122 | @Override 123 | public long lastMod() { 124 | return file.lastModified(); 125 | } 126 | 127 | @Override 128 | public String getSimpleName() { 129 | return simpleName; 130 | } 131 | 132 | @Override 133 | public String getFileName() { 134 | return fileName; 135 | } 136 | 137 | 138 | 139 | @Override 140 | public String getPath() { 141 | return file.getPath(); 142 | } 143 | 144 | @Override 145 | public InputStream open() throws IOException { 146 | return new FileInputStream(file); 147 | } 148 | 149 | @Override 150 | public Kind getKind() { 151 | return kind; 152 | } 153 | } 154 | 155 | } 156 | 157 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/jvm/LzyTarget.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.jvm; 2 | 3 | 4 | import work.liziyun.util.LzyContext; 5 | 6 | import java.util.HashMap; 7 | import java.util.Map; 8 | 9 | public enum LzyTarget { 10 | JDK1_1("1.1", 45, 3), 11 | JDK1_2("1.2", 46, 0), 12 | JDK1_3("1.3", 47, 0), 13 | JDK1_4("1.4", 48, 0), 14 | JSR14("jsr14", 48, 0), 15 | JDK1_4_1("1.4.1", 48, 0), 16 | JDK1_4_2("1.4.2", 48, 0); 17 | 18 | 19 | private static final LzyContext.Key targetKey = new LzyContext.Key(); 20 | private static LzyTarget MIN; 21 | private static LzyTarget MAX; 22 | private static Map tab = new HashMap(); 23 | public final String name; 24 | public final int majorVersion; 25 | 26 | public final int minorVersion; 27 | 28 | public static final LzyTarget DEFAULT; 29 | 30 | static { 31 | LzyTarget[] values = values(); 32 | // 最小值和最大值: jdk1.7 33 | for (LzyTarget value : values) { 34 | if (MIN == null){ 35 | MIN = value; 36 | } 37 | MAX = value; 38 | tab.put(value.name,value); 39 | } 40 | // 默认值: jdk1.4 41 | DEFAULT = JDK1_4; 42 | } 43 | 44 | LzyTarget(String name, int majorVersion, int minorVersion) { 45 | this.name = name; 46 | this.majorVersion = majorVersion; 47 | this.minorVersion = minorVersion; 48 | } 49 | 50 | 51 | 52 | 53 | public static LzyTarget instance(LzyContext LzyContext){ 54 | LzyTarget lzyTarget = LzyContext.get(targetKey); 55 | if (lzyTarget == null){ 56 | // 省略: 尝试获取指定的编译版本 57 | lzyTarget = DEFAULT; 58 | LzyContext.put(targetKey,lzyTarget); 59 | } 60 | return lzyTarget; 61 | } 62 | 63 | public static LzyTarget MAX() { 64 | return MAX; 65 | } 66 | 67 | public static LzyTarget MIN() { 68 | return MIN; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/tag/LzyByteCodes.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.tag; 2 | 3 | public interface LzyByteCodes { 4 | int illegal = -1; 5 | int nop = 0; 6 | int aconst_null = 1; 7 | int iconst_m1 = 2; 8 | int iconst_0 = 3; 9 | int iconst_1 = 4; 10 | int iconst_2 = 5; 11 | int iconst_3 = 6; 12 | int iconst_4 = 7; 13 | int iconst_5 = 8; 14 | int lconst_0 = 9; 15 | int lconst_1 = 10; 16 | int fconst_0 = 11; 17 | int fconst_1 = 12; 18 | int fconst_2 = 13; 19 | int dconst_0 = 14; 20 | int dconst_1 = 15; 21 | int bipush = 16; 22 | int sipush = 17; 23 | int ldc1 = 18; 24 | int ldc2 = 19; 25 | int ldc2w = 20; 26 | int iload = 21; 27 | int lload = 22; 28 | int fload = 23; 29 | int dload = 24; 30 | int aload = 25; 31 | int iload_0 = 26; 32 | int iload_1 = 27; 33 | int iload_2 = 28; 34 | int iload_3 = 29; 35 | int lload_0 = 30; 36 | int lload_1 = 31; 37 | int lload_2 = 32; 38 | int lload_3 = 33; 39 | int fload_0 = 34; 40 | int fload_1 = 35; 41 | int fload_2 = 36; 42 | int fload_3 = 37; 43 | int dload_0 = 38; 44 | int dload_1 = 39; 45 | int dload_2 = 40; 46 | int dload_3 = 41; 47 | int aload_0 = 42; 48 | int aload_1 = 43; 49 | int aload_2 = 44; 50 | int aload_3 = 45; 51 | int iaload = 46; 52 | int laload = 47; 53 | int faload = 48; 54 | int daload = 49; 55 | int aaload = 50; 56 | int baload = 51; 57 | int caload = 52; 58 | int saload = 53; 59 | int istore = 54; 60 | int lstore = 55; 61 | int fstore = 56; 62 | int dstore = 57; 63 | int astore = 58; 64 | 65 | int istore_0 = 59; 66 | int istore_1 = 60; 67 | int istore_2 = 61; 68 | int istore_3 = 62; 69 | 70 | 71 | int lstore_0 = 63; 72 | int lstore_1 = 64; 73 | int lstore_2 = 65; 74 | int lstore_3 = 66; 75 | 76 | 77 | int fstore_0 = 67; 78 | int fstore_1 = 68; 79 | int fstore_2 = 69; 80 | int fstore_3 = 70; 81 | 82 | 83 | int dstore_0 = 71; 84 | int dstore_1 = 72; 85 | int dstore_2 = 73; 86 | int dstore_3 = 74; 87 | 88 | 89 | int astore_0 = 75; 90 | int astore_1 = 76; 91 | int astore_2 = 77; 92 | int astore_3 = 78; 93 | int iastore = 79; 94 | int lastore = 80; 95 | int fastore = 81; 96 | int dastore = 82; 97 | int aastore = 83; 98 | int bastore = 84; 99 | int castore = 85; 100 | int sastore = 86; 101 | int pop = 87; 102 | int pop2 = 88; 103 | int dup = 89; 104 | int dup_x1 = 90; 105 | int dup_x2 = 91; 106 | int dup2 = 92; 107 | int dup2_x1 = 93; 108 | int dup2_x2 = 94; 109 | int swap = 95; 110 | int iadd = 96; 111 | int ladd = 97; 112 | int fadd = 98; 113 | int dadd = 99; 114 | int isub = 100; 115 | int lsub = 101; 116 | int fsub = 102; 117 | int dsub = 103; 118 | int imul = 104; 119 | int lmul = 105; 120 | int fmul = 106; 121 | int dmul = 107; 122 | int idiv = 108; 123 | int ldiv = 109; 124 | int fdiv = 110; 125 | int ddiv = 111; 126 | int imod = 112; 127 | int lmod = 113; 128 | int fmod = 114; 129 | int dmod = 115; 130 | int ineg = 116; 131 | int lneg = 117; 132 | int fneg = 118; 133 | int dneg = 119; 134 | int ishl = 120; 135 | int lshl = 121; 136 | int ishr = 122; 137 | int lshr = 123; 138 | int iushr = 124; 139 | int lushr = 125; 140 | int iand = 126; 141 | int land = 127; 142 | int ior = 128; 143 | int lor = 129; 144 | int ixor = 130; 145 | int lxor = 131; 146 | int iinc = 132; 147 | int i2l = 133; 148 | int i2f = 134; 149 | int i2d = 135; 150 | int l2i = 136; 151 | int l2f = 137; 152 | int l2d = 138; 153 | int f2i = 139; 154 | int f2l = 140; 155 | int f2d = 141; 156 | int d2i = 142; 157 | int d2l = 143; 158 | int d2f = 144; 159 | int int2byte = 145; 160 | int int2char = 146; 161 | int int2short = 147; 162 | int lcmp = 148; 163 | int fcmpl = 149; 164 | int fcmpg = 150; 165 | int dcmpl = 151; 166 | int dcmpg = 152; 167 | int ifeq = 153; 168 | int ifne = 154; 169 | int iflt = 155; 170 | int ifge = 156; 171 | int ifgt = 157; 172 | int ifle = 158; 173 | int if_icmpeq = 159; 174 | int if_icmpne = 160; 175 | int if_icmplt = 161; 176 | int if_icmpge = 162; 177 | int if_icmpgt = 163; 178 | int if_icmple = 164; 179 | int if_acmpeq = 165; 180 | int if_acmpne = 166; 181 | int goto_ = 167; 182 | int jsr = 168; 183 | int ret = 169; 184 | int tableswitch = 170; 185 | int lookupswitch = 171; 186 | int ireturn = 172; 187 | int lreturn = 173; 188 | int freturn = 174; 189 | int dreturn = 175; 190 | int areturn = 176; 191 | int return_ = 177; 192 | int getstatic = 178; 193 | int putstatic = 179; 194 | int getfield = 180; 195 | int putfield = 181; 196 | int invokevirtual = 182; 197 | int invokespecial = 183; 198 | int invokestatic = 184; 199 | int invokeinterface = 185; 200 | int newfromname = 186; 201 | int new_ = 187; 202 | int newarray = 188; 203 | int anewarray = 189; 204 | int arraylength = 190; 205 | int athrow = 191; 206 | int checkcast = 192; 207 | int instanceof_ = 193; 208 | 209 | int monitorenter = 194; // 获取监视器锁 210 | 211 | int monitorexit = 195; // 释放监视器锁 212 | int wide = 196; 213 | int multianewarray = 197; 214 | int if_acmp_null = 198; 215 | int if_acmp_nonnull = 199; 216 | int goto_w = 200; 217 | int jsr_w = 201; 218 | int breakpoint = 202; 219 | int ByteCodeCount = 203; 220 | int string_add = 256; 221 | int bool_not = 257; 222 | int bool_and = 258; 223 | int bool_or = 259; 224 | int ishll = 270; // int左移用long计数 225 | int lshll = 271; // long左移用long计数 226 | int ishrl = 272; // int右移用long计数 227 | int lshrl = 273; // long右移用long计数 228 | int iushrl = 274; 229 | int lushrl = 275; 230 | int nullchk = 276; 231 | int error = 277; 232 | int dontgoto = 168; 233 | int preShift = 9; 234 | int preMask = 511; 235 | int INTcode = 0; 236 | int LONGcode = 1; 237 | int FLOATcode = 2; 238 | int DOUBLEcode = 3; 239 | int OBJECTcode = 4; 240 | int BYTEcode = 5; 241 | int CHARcode = 6; 242 | int SHORTcode = 7; 243 | int VOIDcode = 8; 244 | int TypeCodeCount = 9; 245 | String[] typecodeNames = new String[]{"int", "long", "float", "double", "object", "byte", "char", "short", "void", "oops"}; 246 | } 247 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/tag/LzyFlags.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.tag; 2 | 3 | public interface LzyFlags { 4 | public static final int EMPTY = 0 ; 5 | public static final int PUBLIC = 1; 6 | public static final int PRIVATE = 2; 7 | public static final int PROTECTED = 4; 8 | public static final int STATIC = 8; 9 | public static final int FINAL = 16; 10 | public static final int SYNCHRONIZED = 32; 11 | public static final int VOLATILE = 64; 12 | public static final int TRANSIENT = 128; 13 | public static final int NATIVE = 256; 14 | public static final int INTERFACE = 512; 15 | public static final int ABSTRACT = 1024; 16 | public static final int STRICTFP = 2048; 17 | public static final int SYNTHETIC = 4096; 18 | public static final int ANNOTATION = 8192; 19 | public static final int ENUM = 16384; 20 | public static final int StandardFlags = 4095; 21 | public static final int ModifierFlags = 3583; 22 | public static final int ACC_SUPER = 32; 23 | public static final int ACC_BRIDGE = 64; 24 | public static final int ACC_VARARGS = 128; 25 | public static final int DEPRECATED = 131072; 26 | public static final int HASINIT = 262144; 27 | public static final int BLOCK = 1048576; 28 | public static final int IPROXY = 2097152; 29 | public static final int NOOUTERTHIS = 4194304; 30 | public static final int EXISTS = 8388608; 31 | public static final int COMPOUND = 16777216; 32 | public static final int CLASS_SEEN = 33554432; 33 | public static final int SOURCE_SEEN = 67108864; 34 | public static final int LOCKED = 134217728; 35 | public static final int UNATTRIBUTED = 268435456; 36 | public static final int ANONCONSTR = 536870912; 37 | public static final int ACYCLIC = 1073741824; 38 | public static final long BRIDGE = 2147483648L; 39 | public static final long PARAMETER = 8589934592L; 40 | public static final long VARARGS = 17179869184L; 41 | public static final long ACYCLIC_ANN = 34359738368L; 42 | public static final long GENERATEDCONSTR = 68719476736L; 43 | public static final long HYPOTHETICAL = 137438953472L; 44 | public static final long PROPRIETARY = 274877906944L; 45 | public static final long UNION = 549755813888L; 46 | public static final long POLYMORPHIC_SIGNATURE = 1099511627776L; 47 | public static final long OVERRIDE_BRIDGE = 2199023255552L; 48 | public static final long EFFECTIVELY_FINAL = 4398046511104L; 49 | public static final long CLASH = 8796093022208L; 50 | public static final int AccessFlags = 7; 51 | public static final int LocalClassFlags = 23568; 52 | public static final int MemberClassFlags = 24087; 53 | public static final int ClassFlags = 32273; 54 | public static final int InterfaceVarFlags = 25; 55 | public static final int VarFlags = 16607; 56 | public static final int ConstructorFlags = 7; 57 | public static final int InterfaceMethodFlags = 1025; 58 | public static final int MethodFlags = 3391; 59 | public static final long LocalVarFlags = 8589934608L; 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/tag/LzyKinds.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.tag; 2 | 3 | public interface LzyKinds { 4 | int NIL = 0; 5 | int PCK = 1; 6 | int TYP = 2; 7 | int VAR = 4; 8 | int VAL = 12; 9 | int MTH = 16; 10 | int ERR = 31; 11 | int AllKinds = 31; 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/tree/LzyJCCompilationUnit.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.tree; 2 | 3 | 4 | import work.liziyun.code.LzyScope; 5 | import work.liziyun.code.symbol.LzyPackageSymbol; 6 | import work.liziyun.util.LzyList; 7 | import work.liziyun.world.LzyName; 8 | 9 | public class LzyJCCompilationUnit extends LzyJCTree { 10 | public LzyJCTree pid; 11 | public LzyList defs; 12 | public LzyName sourcefile; 13 | public LzyPackageSymbol packageSymbol; 14 | // 普通导入的作用域 15 | public LzyScope namedImportScope; 16 | // 星号导入的作用域 17 | public LzyScope starImportScope; 18 | 19 | 20 | public LzyJCCompilationUnit(LzyJCTree pid, LzyList defs, LzyName name, LzyPackageSymbol lzyPackageSymbol, LzyScope namedImportScope, LzyScope starImportScope) { 21 | super(TOPLEVEL); 22 | this.pid = pid; 23 | this.defs = defs; 24 | this.sourcefile = name; 25 | this.packageSymbol = lzyPackageSymbol; 26 | this.namedImportScope = namedImportScope; 27 | this.starImportScope = starImportScope; 28 | } 29 | 30 | @Override 31 | public void accept(LzyVisitor visitor) { 32 | visitor.visitJCCompilationUnit(this); 33 | } 34 | 35 | 36 | public int getTag(){ 37 | return tag; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/tree/LzyJCImport.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.tree; 2 | 3 | 4 | public class LzyJCImport extends LzyJCTree { 5 | public LzyJCTree qualid; 6 | @Override 7 | public void accept(LzyVisitor visitor) { 8 | visitor.visitJCImport(this); 9 | } 10 | 11 | public LzyJCImport(LzyJCTree qualid) { 12 | super(IMPORT); 13 | this.qualid = qualid; 14 | } 15 | 16 | public int getTag(){ 17 | return tag; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/tree/LzyJCIndexed.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.tree; 2 | 3 | public class LzyJCIndexed extends LzyJCTree.JCExpression { 4 | public LzyJCTree indexed; 5 | public LzyJCTree index; 6 | @Override 7 | public void accept(LzyVisitor visitor) { 8 | visitor.visitJCIndexed(this); 9 | } 10 | 11 | public LzyJCIndexed(LzyJCTree indexed, LzyJCTree index) { 12 | super(INDEXED); 13 | this.indexed = indexed; 14 | this.index = index; 15 | } 16 | 17 | 18 | public int getTag(){ 19 | return tag; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/tree/LzyJCMethodDef.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.tree; 2 | 3 | 4 | import work.liziyun.code.symbol.LzyMethodSymbol; 5 | import work.liziyun.tree.state.LzyJCBlock; 6 | import work.liziyun.util.LzyList; 7 | import work.liziyun.world.LzyName; 8 | 9 | public class LzyJCMethodDef extends LzyJCTree { 10 | public long flags; 11 | public LzyName name; 12 | public LzyJCTree restype; 13 | // 内置泛型 14 | public LzyList typarams; 15 | public LzyList params; 16 | public LzyList thrown; 17 | public LzyJCBlock block; 18 | public LzyMethodSymbol sym; 19 | @Override 20 | public void accept(LzyVisitor visitor) { 21 | visitor.visitJCMethodDef(this); 22 | } 23 | 24 | public LzyJCMethodDef(long flags, LzyName name, LzyJCTree restype, LzyList typarams, LzyList params, LzyList thrown, LzyJCBlock block, LzyMethodSymbol sym) { 25 | super(METHODDEF); 26 | this.flags = flags; 27 | this.name = name; 28 | this.restype = restype; 29 | this.typarams = typarams; 30 | this.params = params; 31 | this.thrown = thrown; 32 | this.block = block; 33 | this.sym = sym; 34 | } 35 | 36 | public int getTag(){ 37 | return tag; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/tree/LzyJCModifiers.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.tree; 2 | 3 | 4 | 5 | public class LzyJCModifiers extends LzyJCTree{ 6 | public long flags; 7 | 8 | public LzyJCModifiers(long flags) { 9 | super(LzyJCTree.MODIFIERS); 10 | this.flags = flags; 11 | } 12 | @Override 13 | public void accept(LzyVisitor var1) { 14 | var1.visitModifiers(this); 15 | } 16 | 17 | public int getTag(){ 18 | return tag; 19 | } 20 | 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/tree/LzyJCTree.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.tree; 2 | 3 | 4 | import work.liziyun.code.type.LzyType; 5 | 6 | public abstract class LzyJCTree { 7 | public static final int TOPLEVEL = 1; 8 | public static final int IMPORT = 2; 9 | public static final int CLASSDEF = 3; 10 | public static final int METHODDEF = 4; 11 | public static final int VARDEF = 5; 12 | public static final int SKIP = 6; 13 | public static final int BLOCK = 7; 14 | public static final int DOLOOP = 8; 15 | public static final int WHILELOOP = 9; 16 | public static final int FORLOOP = 10; 17 | public static final int FOREACHLOOP = 11; 18 | public static final int LABELLED = 12; 19 | public static final int SWITCH = 13; 20 | public static final int CASE = 14; 21 | public static final int SYNCHRONIZED = 15; 22 | public static final int TRY = 16; 23 | public static final int CATCH = 17; 24 | public static final int CONDEXPR = 18; 25 | public static final int IF = 19; 26 | public static final int EXEC = 20; 27 | public static final int BREAK = 21; 28 | public static final int CONTINUE = 22; 29 | public static final int RETURN = 23; 30 | public static final int THROW = 24; 31 | public static final int ASSERT = 25; 32 | public static final int APPLY = 26; 33 | public static final int NEWCLASS = 27; 34 | public static final int NEWARRAY = 28; 35 | public static final int PARENS = 29; 36 | public static final int ASSIGN = 30; 37 | public static final int TYPECAST = 31; 38 | public static final int TYPETEST = 32; 39 | public static final int INDEXED = 33; 40 | public static final int SELECT = 34; 41 | public static final int IDENT = 35; 42 | public static final int LITERAL = 36; 43 | public static final int TYPEIDENT = 37; 44 | public static final int TYPEARRAY = 38; 45 | public static final int TYPEAPPLY = 39; 46 | public static final int TYPEUNION = 40; 47 | public static final int TYPEPARAMETER = 41; 48 | public static final int WILDCARD = 42; 49 | public static final int TYPEBOUNDKIND = 43; 50 | public static final int ANNOTATION = 44; 51 | public static final int MODIFIERS = 45; 52 | public static final int ANNOTATED_TYPE = 46; 53 | public static final int ERRONEOUS = 47; 54 | public static final int POS = 48; // + 55 | public static final int NEG = 49; // - 56 | public static final int NOT = 50; // ! 57 | public static final int COMPL = 51; // ~ 58 | public static final int PREINC = 52; // ++ _ 59 | public static final int PREDEC = 53; // -- _ 60 | public static final int POSTINC = 54; // _ ++ 61 | public static final int POSTDEC = 55; // _ -- 62 | public static final int NULLCHK = 56; 63 | public static final int OR = 57; // || 64 | public static final int AND = 58; // && 65 | public static final int BITOR = 59; // | 66 | public static final int BITXOR = 60; // ^ 67 | public static final int BITAND = 61; // & 68 | public static final int EQ = 62; // == 69 | public static final int NE = 63; // != 70 | public static final int LT = 64; // < 71 | public static final int GT = 65; // > 72 | public static final int LE = 66; // <= 73 | public static final int GE = 67; // >= 74 | public static final int SL = 68; // << 75 | public static final int SR = 69; // >> 76 | public static final int USR = 70; // >>> 77 | public static final int PLUS = 71; // + 78 | public static final int MINUS = 72; // - 79 | public static final int MUL = 73; // * 80 | public static final int DIV = 74; // / 81 | public static final int MOD = 75; // % 82 | public static final int BITOR_ASG = 76; // |= 83 | public static final int BITXOR_ASG = 77; // ^= 84 | public static final int BITAND_ASG = 78; // &= 85 | public static final int SL_ASG = 85; // <<= 86 | public static final int SR_ASG = 86; // >>= 87 | public static final int USR_ASG = 87; // >>>= 88 | public static final int PLUS_ASG = 88; // += 89 | public static final int MINUS_ASG = 89; // -= 90 | public static final int MUL_ASG = 90; // *= 91 | public static final int DIV_ASG = 91; // /= 92 | public static final int MOD_ASG = 92; // %= 93 | public static final int LETEXPR = 93; 94 | public static final int ASGOffset = 17; 95 | public int pos; 96 | public LzyType type; 97 | public int tag; 98 | 99 | public LzyJCTree(int tag) { 100 | this.tag = tag; 101 | } 102 | 103 | public LzyJCTree() { 104 | } 105 | 106 | public int getTag(){ 107 | return tag; 108 | } 109 | // 110 | public LzyJCTree setPos(int pos){ 111 | this.pos = pos; 112 | return this; 113 | } 114 | // 115 | public LzyJCTree setType(LzyType type){ 116 | this.type = type; 117 | return this; 118 | } 119 | // 访问者 120 | public void accept(LzyVisitor visitor){ 121 | visitor.visitJCTree(this); 122 | } 123 | 124 | 125 | public static class JCExpression extends LzyJCTree { 126 | 127 | public JCExpression () { 128 | super(); 129 | } 130 | 131 | public JCExpression (int tag) { 132 | super(tag); 133 | } 134 | 135 | public JCExpression setType(LzyType var1) { 136 | super.setType(var1); 137 | return this; 138 | } 139 | 140 | public JCExpression setPos(int var1) { 141 | super.setPos(var1); 142 | return this; 143 | } 144 | } 145 | 146 | public static class JCStatement extends LzyJCTree{ 147 | public JCStatement(int tag) { 148 | super(tag); 149 | } 150 | 151 | 152 | public JCStatement setType(LzyType var1) { 153 | super.setType(var1); 154 | return this; 155 | } 156 | 157 | public JCStatement setPos(int var1) { 158 | super.setPos(var1); 159 | return this; 160 | } 161 | } 162 | 163 | } 164 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/tree/LzyJCTypeParameter.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.tree; 2 | 3 | 4 | import work.liziyun.util.LzyList; 5 | 6 | // 泛型 7 | public class LzyJCTypeParameter extends LzyJCTree{ 8 | public static final LzyList emptyList = LzyList.nil(); 9 | 10 | public LzyJCTypeParameter() { 11 | // 疑问这里为什么是0,而不是TYPEPARAMETER 12 | super(TYPEPARAMETER); 13 | } 14 | 15 | public int getTag(){ 16 | return tag; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/tree/LzyVisitor.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.tree; 2 | 3 | 4 | import work.liziyun.tree.express.*; 5 | import work.liziyun.tree.state.*; 6 | 7 | 8 | public class LzyVisitor { 9 | public LzyVisitor(){} 10 | 11 | public void visitModifiers(LzyJCModifiers modifers){ 12 | this.visitModifiers(modifers); 13 | } 14 | 15 | public void visitJCCompilationUnit(LzyJCCompilationUnit lzyJCTopLevel){ 16 | this.visitJCTree(lzyJCTopLevel); 17 | } 18 | 19 | 20 | public void visitJCWhileLoop(LzyJCWhileLoop jcWhileLoop){ 21 | this.visitJCTree(jcWhileLoop); 22 | } 23 | 24 | 25 | public void visitJCUnary(LzyJCUnary jcUnary){ 26 | this.visitJCTree(jcUnary); 27 | } 28 | 29 | public void visitJCTypeIdent(LzyJCTypeIdent jcTypeIdent){ 30 | this.visitJCTree(jcTypeIdent); 31 | } 32 | 33 | public void visitJCTypeTest(LzyJCTypeTest jcTypeTest){ 34 | this.visitJCTree(jcTypeTest); 35 | } 36 | 37 | public void visitJCTypeCast(LzyJCTypeCast jcTypeCast){ 38 | this.visitJCTree(jcTypeCast); 39 | } 40 | 41 | public void visitJCTypeArray(LzyJCTypeArray jcTypeArray){ 42 | this.visitJCTree(jcTypeArray); 43 | } 44 | 45 | public void visitJCTry(LzyJCTry jctry){ 46 | this.visitJCTree(jctry); 47 | } 48 | 49 | 50 | 51 | public void visitJCThrow(LzyJCThrow jcThrow){ 52 | this.visitJCTree(jcThrow); 53 | } 54 | public void visitJCSwitch(LzyJCSwitch jcSwitch){ 55 | this.visitJCTree(jcSwitch); 56 | } 57 | 58 | public void visitJCSkip(LzyJCSkip jcSkip){ 59 | this.visitJCTree(jcSkip); 60 | } 61 | 62 | public void visitJCSelect(LzyJCSelect jcSelect){ 63 | this.visitJCTree(jcSelect); 64 | } 65 | public void visitJCReturn(LzyJCReturn jcReturn){ 66 | this.visitJCTree(jcReturn); 67 | } 68 | 69 | public void visitJCParens(LzyJCParens jcParens){ 70 | this.visitJCTree(jcParens); 71 | } 72 | 73 | 74 | public void visitJCNewArray(LzyJCNewArray jcNewArray){ 75 | this.visitJCTree(jcNewArray); 76 | } 77 | 78 | 79 | public void visitJCNewClass(LzyJCNewClass jcNewClass){ 80 | this.visitJCTree(jcNewClass); 81 | } 82 | public void visitJCMethodDef(LzyJCMethodDef jcMethodDef){ 83 | this.visitJCTree(jcMethodDef); 84 | } 85 | 86 | public void visitJCLiteral(LzyJCLiteral jcLiteral){ 87 | this.visitJCTree(jcLiteral); 88 | } 89 | public void visitJCIndexed(LzyJCIndexed jcIndexed){ 90 | this.visitJCTree(jcIndexed); 91 | } 92 | 93 | public void visitJCImport(LzyJCImport jcImport){ 94 | this.visitJCTree(jcImport); 95 | } 96 | 97 | public void visitJCIf(LzyJCIf jcIf){ 98 | this.visitJCTree(jcIf); 99 | } 100 | 101 | public void visitJCForLoop(LzyJCForLoop jcForLoop){ 102 | this.visitJCTree(jcForLoop); 103 | } 104 | 105 | public void visitJCIdent(LzyJCIdent jcIdent) { 106 | this.visitJCTree(jcIdent); 107 | } 108 | 109 | public void visitJCExec(LzyJCExec jcExec){ 110 | this.visitJCTree(jcExec); 111 | } 112 | public void visitJCExec(LzyJCExpressionStatement jcExpressionStatement){ 113 | this.visitJCTree(jcExpressionStatement); 114 | } 115 | 116 | public void visitJCErroneous(LzyJCErroneous jcErroneous){ 117 | this.visitJCTree(jcErroneous); 118 | } 119 | 120 | public void visitJCDoloop(LzyJCDoloop jcDoloop){ 121 | this.visitJCTree(jcDoloop); 122 | } 123 | 124 | public void visitJCContinue(LzyJCContinue jcContinue){ 125 | this.visitJCTree(jcContinue); 126 | } 127 | public void visitJCConditional(LzyJCConditional jcConditional){ 128 | this.visitJCTree(jcConditional); 129 | } 130 | public void visitJCClassDef(LzyJCClassDef jcClassDef){ 131 | this.visitJCTree(jcClassDef); 132 | } 133 | 134 | public void visitJCVarDef(LzyJCVarDef jcVarDef){ 135 | this.visitJCTree(jcVarDef); 136 | } 137 | 138 | public void visitJCCatch(LzyJCCatch jcCatch){ 139 | this.visitJCTree(jcCatch); 140 | } 141 | 142 | public void visitJCCase(LzyJCCase jcCase){ 143 | this.visitJCTree(jcCase); 144 | } 145 | 146 | public void visitJCBreak(LzyJCBreak jcBreak){ 147 | this.visitJCTree(jcBreak); 148 | } 149 | 150 | public void visitJCBlock(LzyJCBlock jcBlock){ 151 | this.visitJCTree(jcBlock); 152 | } 153 | 154 | public void visitJCBinary(LzyJCBinary jcBinary){ 155 | this.visitJCTree(jcBinary); 156 | } 157 | 158 | public void visitJCAssignop(LzyJCAssignop lzyAssignop){ 159 | this.visitJCTree(lzyAssignop); 160 | } 161 | 162 | public void visitJCApply(LzyJCApply apply){ 163 | this.visitJCTree(apply); 164 | } 165 | 166 | public void visitJCTree(LzyJCTree jcTree){ 167 | System.out.println("不能访问visitTree"); 168 | } 169 | public void visitJCAssign(LzyJCAssign lzyAssign){ 170 | this.visitJCTree(lzyAssign); 171 | } 172 | 173 | } 174 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/tree/express/LzyJCApply.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.tree.express; 2 | 3 | 4 | 5 | import work.liziyun.tree.LzyJCTree; 6 | import work.liziyun.tree.LzyVisitor; 7 | import work.liziyun.util.LzyList; 8 | 9 | public class LzyJCApply extends LzyJCTree.JCExpression { 10 | 11 | public LzyJCTree meth; 12 | public LzyList args; 13 | 14 | @Override 15 | public void accept(LzyVisitor visitor) { 16 | visitor.visitJCApply(this); 17 | } 18 | 19 | public LzyJCApply(LzyJCTree meth, LzyList args) { 20 | super(APPLY); 21 | this.meth = meth; 22 | this.args = args; 23 | } 24 | 25 | public int getTag(){ 26 | return tag; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/tree/express/LzyJCAssign.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.tree.express; 2 | 3 | import work.liziyun.tree.LzyJCTree; 4 | import work.liziyun.tree.LzyVisitor; 5 | 6 | /** 7 | * 作者: 李滋芸 8 | * 语法树节点: 普通赋值节点 9 | * 10 | */ 11 | public class LzyJCAssign extends LzyJCTree.JCExpression{ 12 | 13 | public LzyJCTree lhs; 14 | public LzyJCTree rhs; 15 | 16 | @Override 17 | public void accept(LzyVisitor visitor) { 18 | visitor.visitJCAssign(this); 19 | } 20 | 21 | public LzyJCAssign( LzyJCTree lhs, LzyJCTree rhs) { 22 | super(ASSIGN); 23 | this.lhs = lhs; 24 | this.rhs = rhs; 25 | } 26 | 27 | public int getTag(){ 28 | return tag; 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/tree/express/LzyJCAssignop.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.tree.express; 2 | 3 | import work.liziyun.code.symbol.LzySymbol; 4 | import work.liziyun.tree.LzyJCTree; 5 | import work.liziyun.tree.LzyVisitor; 6 | 7 | /** 8 | * 作者: 李滋芸 9 | * 语法树节点: 复合赋值节点 10 | * 11 | */ 12 | public class LzyJCAssignop extends LzyJCTree.JCExpression { 13 | public LzyJCTree lhs; 14 | public LzyJCTree rhs; 15 | public LzySymbol operator; 16 | @Override 17 | public void accept(LzyVisitor visitor) { 18 | visitor.visitJCAssignop(this); 19 | } 20 | 21 | public LzyJCAssignop(int tag, LzyJCTree lhs, LzyJCTree rhs, LzySymbol operator) { 22 | super(tag); 23 | this.lhs = lhs; 24 | this.rhs = rhs; 25 | this.operator = operator; 26 | } 27 | 28 | public int getTag(){ 29 | return tag; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/tree/express/LzyJCBinary.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.tree.express; 2 | 3 | 4 | 5 | import work.liziyun.code.symbol.LzySymbol; 6 | import work.liziyun.tree.LzyJCTree; 7 | import work.liziyun.tree.LzyVisitor; 8 | 9 | /** 10 | * 作者: 李滋芸 11 | * 语法树节点: 算术运算 12 | * 13 | */ 14 | public class LzyJCBinary extends LzyJCTree.JCExpression { 15 | public int opcode; 16 | public LzyJCTree lhs; 17 | public LzyJCTree rhs; 18 | public LzySymbol operator; 19 | @Override 20 | public void accept(LzyVisitor visitor) { 21 | visitor.visitJCBinary(this); 22 | } 23 | 24 | public LzyJCBinary(int opcode, LzyJCTree lhs, LzyJCTree rhs, LzySymbol operator) { 25 | this.opcode = opcode; 26 | this.lhs = lhs; 27 | this.rhs = rhs; 28 | this.operator = operator; 29 | } 30 | 31 | public int getTag(){ 32 | return tag; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/tree/express/LzyJCConditional.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.tree.express; 2 | 3 | import work.liziyun.tree.LzyJCTree; 4 | import work.liziyun.tree.LzyVisitor; 5 | 6 | public class LzyJCConditional extends LzyJCTree.JCExpression { 7 | public LzyJCTree cond; 8 | public LzyJCTree truepart; 9 | public LzyJCTree falsepart; 10 | 11 | @Override 12 | public void accept(LzyVisitor visitor) { 13 | visitor.visitJCConditional(this); 14 | } 15 | 16 | public LzyJCConditional(LzyJCTree cond, LzyJCTree truepart, LzyJCTree falsepart) { 17 | super(CONDEXPR); 18 | this.cond = cond; 19 | this.truepart = truepart; 20 | this.falsepart = falsepart; 21 | } 22 | 23 | public int getTag(){ 24 | return tag; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/tree/express/LzyJCErroneous.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.tree.express; 2 | 3 | 4 | import work.liziyun.tree.LzyJCTree; 5 | import work.liziyun.tree.LzyVisitor; 6 | 7 | public class LzyJCErroneous extends LzyJCTree.JCExpression { 8 | 9 | public LzyJCErroneous() { 10 | super(ERRONEOUS); 11 | } 12 | 13 | @Override 14 | public void accept(LzyVisitor visitor) { 15 | visitor.visitJCErroneous(this); 16 | } 17 | 18 | 19 | public int getTag(){ 20 | return tag; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/tree/express/LzyJCIdent.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.tree.express; 2 | 3 | import work.liziyun.code.symbol.LzySymbol; 4 | import work.liziyun.tree.LzyJCTree; 5 | import work.liziyun.tree.LzyVisitor; 6 | import work.liziyun.world.LzyName; 7 | 8 | public class LzyJCIdent extends LzyJCTree.JCExpression { 9 | public LzyName name; 10 | public LzySymbol symbol; 11 | 12 | @Override 13 | public void accept(LzyVisitor visitor) { 14 | visitor.visitJCIdent(this); 15 | } 16 | 17 | public LzyJCIdent(LzyName name, LzySymbol symbol) { 18 | super(IDENT); 19 | this.name = name; 20 | this.symbol = symbol; 21 | } 22 | 23 | public int getTag(){ 24 | return tag; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/tree/express/LzyJCLiteral.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.tree.express; 2 | 3 | 4 | import work.liziyun.tree.LzyJCTree; 5 | import work.liziyun.tree.LzyVisitor; 6 | 7 | public class LzyJCLiteral extends LzyJCTree.JCExpression { 8 | 9 | public int typetag; 10 | 11 | public Object value; 12 | 13 | @Override 14 | public void accept(LzyVisitor visitor) { 15 | visitor.visitJCLiteral(this); 16 | } 17 | 18 | public LzyJCLiteral(int typetag, Object value) { 19 | super(LITERAL); 20 | this.typetag = typetag; 21 | this.value = value; 22 | } 23 | 24 | public int getTag(){ 25 | return tag; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/tree/express/LzyJCNewArray.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.tree.express; 2 | 3 | 4 | import work.liziyun.tree.LzyJCTree; 5 | import work.liziyun.tree.LzyVisitor; 6 | import work.liziyun.util.LzyList; 7 | 8 | public class LzyJCNewArray extends LzyJCTree.JCExpression { 9 | 10 | public LzyJCTree elemtype; 11 | public LzyList dims; 12 | public LzyList elems; 13 | 14 | public void accept(LzyVisitor visitor) { 15 | visitor.visitJCNewArray(this); } 16 | 17 | public LzyJCNewArray(LzyJCTree elemtype, LzyList dims, LzyList elems) { 18 | super(NEWARRAY); 19 | this.elemtype = elemtype; 20 | this.dims = dims; 21 | this.elems = elems; 22 | } 23 | 24 | public int getTag(){ 25 | return tag; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/tree/express/LzyJCNewClass.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.tree.express; 2 | 3 | 4 | import work.liziyun.code.symbol.LzySymbol; 5 | import work.liziyun.tree.LzyJCTree; 6 | import work.liziyun.tree.LzyVisitor; 7 | import work.liziyun.tree.state.LzyJCClassDef; 8 | import work.liziyun.util.LzyList; 9 | 10 | public class LzyJCNewClass extends LzyJCTree.JCExpression { 11 | public LzyJCTree encl; 12 | public LzyJCTree clazz; 13 | public LzyList args; 14 | public LzyJCClassDef def; 15 | public LzySymbol constructor; 16 | @Override 17 | public void accept(LzyVisitor visitor) { 18 | visitor.visitJCNewClass(this); 19 | } 20 | 21 | public LzyJCNewClass(LzyJCTree encl, LzyJCTree clazz, LzyList args, LzyJCClassDef def, LzySymbol constructor) { 22 | super(NEWCLASS); 23 | this.encl = encl; 24 | this.clazz = clazz; 25 | this.args = args; 26 | this.def = def; 27 | this.constructor = constructor; 28 | } 29 | 30 | public int getTag(){ 31 | return tag; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/tree/express/LzyJCParens.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.tree.express; 2 | 3 | import work.liziyun.tree.LzyJCTree; 4 | import work.liziyun.tree.LzyVisitor; 5 | 6 | public class LzyJCParens extends LzyJCTree.JCExpression { 7 | public LzyJCTree expr; 8 | @Override 9 | public void accept(LzyVisitor visitor) { 10 | visitor.visitJCParens(this); 11 | } 12 | 13 | public LzyJCParens(LzyJCTree expr) { 14 | super(PARENS); 15 | this.expr = expr; 16 | } 17 | 18 | public int getTag(){ 19 | return tag; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/tree/express/LzyJCSelect.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.tree.express; 2 | 3 | 4 | import work.liziyun.code.symbol.LzySymbol; 5 | import work.liziyun.tree.LzyJCTree; 6 | import work.liziyun.tree.LzyVisitor; 7 | import work.liziyun.world.LzyName; 8 | 9 | public class LzyJCSelect extends LzyJCTree.JCExpression { 10 | public LzyJCTree selected; 11 | public LzyName name; 12 | public LzySymbol sym; 13 | @Override 14 | public void accept(LzyVisitor visitor) { 15 | visitor.visitJCSelect(this); 16 | } 17 | 18 | public LzyJCSelect(LzyJCTree selected, LzyName name, LzySymbol sym) { 19 | super(SELECT); 20 | this.selected = selected; 21 | this.name = name; 22 | this.sym = sym; 23 | } 24 | 25 | public int getTag(){ 26 | return tag; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/tree/express/LzyJCTypeArray.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.tree.express; 2 | 3 | import work.liziyun.tree.LzyJCTree; 4 | import work.liziyun.tree.LzyVisitor; 5 | 6 | public class LzyJCTypeArray extends LzyJCTree.JCExpression { 7 | public LzyJCTree elemtype; 8 | @Override 9 | public void accept(LzyVisitor visitor) { 10 | visitor.visitJCTypeArray(this); 11 | } 12 | 13 | 14 | public LzyJCTypeArray(LzyJCTree elemtype) { 15 | super(TYPEARRAY); 16 | this.elemtype = elemtype; 17 | } 18 | 19 | public int getTag(){ 20 | return tag; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/tree/express/LzyJCTypeCast.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.tree.express; 2 | 3 | 4 | import work.liziyun.tree.LzyJCTree; 5 | import work.liziyun.tree.LzyVisitor; 6 | 7 | public class LzyJCTypeCast extends LzyJCTree.JCExpression { 8 | 9 | public LzyJCTree clazz; 10 | public LzyJCTree expr; 11 | 12 | 13 | @Override 14 | public void accept(LzyVisitor visitor) { 15 | visitor.visitJCTypeCast(this); 16 | } 17 | 18 | public LzyJCTypeCast(LzyJCTree clazz, LzyJCTree expr) { 19 | super(TYPECAST); 20 | this.clazz = clazz; 21 | this.expr = expr; 22 | } 23 | 24 | public int getTag(){ 25 | return tag; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/tree/express/LzyJCTypeIdent.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.tree.express; 2 | 3 | import work.liziyun.tree.LzyJCTree; 4 | import work.liziyun.tree.LzyVisitor; 5 | 6 | public class LzyJCTypeIdent extends LzyJCTree.JCExpression { 7 | public int typetag; 8 | 9 | @Override 10 | public void accept(LzyVisitor visitor) { 11 | visitor.visitJCTypeIdent(this); 12 | } 13 | 14 | public LzyJCTypeIdent(int typetag) { 15 | super(TYPEIDENT); 16 | this.typetag = typetag; 17 | } 18 | 19 | public int getTag(){ 20 | return tag; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/tree/express/LzyJCTypeTest.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.tree.express; 2 | 3 | import work.liziyun.tree.LzyJCTree; 4 | import work.liziyun.tree.LzyVisitor; 5 | // instanceOf 6 | public class LzyJCTypeTest extends LzyJCTree.JCExpression { 7 | public LzyJCTree expr; 8 | public LzyJCTree clazz; 9 | 10 | 11 | public void accept(LzyVisitor var1) { 12 | var1.visitJCTypeTest(this); 13 | } 14 | 15 | public LzyJCTypeTest(LzyJCTree expr, LzyJCTree clazz) { 16 | super(TYPETEST); 17 | this.expr = expr; 18 | this.clazz = clazz; 19 | } 20 | 21 | public int getTag(){ 22 | return tag; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/tree/express/LzyJCUnary.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.tree.express; 2 | 3 | import work.liziyun.code.symbol.LzySymbol; 4 | import work.liziyun.tree.LzyJCTree; 5 | import work.liziyun.tree.LzyVisitor; 6 | 7 | public class LzyJCUnary extends LzyJCTree.JCExpression{ 8 | public LzyJCTree arg; 9 | public LzySymbol operator; 10 | 11 | public void accept(LzyVisitor var1) { 12 | var1.visitJCUnary(this); 13 | } 14 | 15 | 16 | public LzyJCUnary(int tag,LzyJCTree arg, LzySymbol operator) { 17 | super(tag); 18 | this.arg = arg; 19 | this.operator = operator; 20 | } 21 | public int getTag(){ 22 | return tag; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/tree/state/LzyJCBlock.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.tree.state; 2 | 3 | 4 | import work.liziyun.tree.LzyJCTree; 5 | import work.liziyun.tree.LzyVisitor; 6 | import work.liziyun.util.LzyList; 7 | 8 | public class LzyJCBlock extends LzyJCTree.JCStatement { 9 | public long flags; 10 | public LzyList stats; 11 | public int endpos = 0; 12 | @Override 13 | public void accept(LzyVisitor visitor) { 14 | visitor.visitJCBlock(this); 15 | } 16 | 17 | public LzyJCBlock(long flags, LzyList stats) { 18 | super(BLOCK); 19 | this.flags = flags; 20 | this.stats = stats; 21 | } 22 | 23 | public int getTag(){ 24 | return tag; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/tree/state/LzyJCBreak.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.tree.state; 2 | 3 | import work.liziyun.tree.LzyJCTree; 4 | import work.liziyun.tree.LzyVisitor; 5 | import work.liziyun.world.LzyName; 6 | 7 | public class LzyJCBreak extends LzyJCTree.JCStatement { 8 | 9 | public LzyName label; 10 | public LzyJCTree target; 11 | 12 | @Override 13 | public void accept(LzyVisitor visitor) { 14 | visitor.visitJCBreak(this); 15 | } 16 | 17 | public LzyJCBreak(LzyName label, LzyJCTree target) { 18 | super(BREAK); 19 | this.label = label; 20 | this.target = target; 21 | } 22 | 23 | public int getTag(){ 24 | return tag; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/tree/state/LzyJCCase.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.tree.state; 2 | 3 | 4 | 5 | import work.liziyun.tree.LzyJCTree; 6 | import work.liziyun.tree.LzyVisitor; 7 | import work.liziyun.util.LzyList; 8 | 9 | public class LzyJCCase extends LzyJCTree.JCStatement { 10 | public LzyJCTree pat; 11 | public LzyList stats; 12 | 13 | @Override 14 | public void accept(LzyVisitor visitor) { 15 | visitor.visitJCCase(this); 16 | } 17 | 18 | public LzyJCCase(LzyJCTree pat, LzyList stats) { 19 | super(CASE); 20 | this.pat = pat; 21 | this.stats = stats; 22 | } 23 | public int getTag(){ 24 | return tag; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/tree/state/LzyJCCatch.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.tree.state; 2 | 3 | 4 | import work.liziyun.tree.LzyJCTree; 5 | 6 | import work.liziyun.tree.LzyVisitor; 7 | import work.liziyun.util.LzyList; 8 | 9 | public class LzyJCCatch extends LzyJCTree.JCStatement { 10 | public LzyJCVarDef param; 11 | public LzyJCTree body; 12 | public static LzyList emptyList = LzyList.nil(); 13 | @Override 14 | public void accept(LzyVisitor visitor) { 15 | visitor.visitJCCatch(this); 16 | } 17 | 18 | public LzyJCCatch(LzyJCVarDef param, LzyJCTree body) { 19 | super(CATCH); 20 | this.param = param; 21 | this.body = body; 22 | } 23 | 24 | public int getTag(){ 25 | return tag; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/tree/state/LzyJCClassDef.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.tree.state; 2 | 3 | import work.liziyun.code.symbol.LzyClassSymbol; 4 | import work.liziyun.tree.LzyJCTree; 5 | import work.liziyun.tree.LzyVisitor; 6 | import work.liziyun.util.LzyList; 7 | import work.liziyun.world.LzyName; 8 | 9 | public class LzyJCClassDef extends LzyJCTree.JCStatement { 10 | public long flags; 11 | public LzyName name; 12 | // 内置泛型 13 | public LzyList typarams; 14 | public LzyJCTree extending; 15 | public LzyList implementing; 16 | public LzyList defs; 17 | public LzyClassSymbol sym; 18 | @Override 19 | public void accept(LzyVisitor visitor) { 20 | visitor.visitJCClassDef(this); 21 | } 22 | 23 | public LzyJCClassDef(long flags, LzyName name, LzyList typarams, LzyJCTree extending, LzyList implementing, LzyList defs, LzyClassSymbol sym) { 24 | super(CLASSDEF); 25 | this.flags = flags; 26 | this.name = name; 27 | this.typarams = typarams; 28 | this.extending = extending; 29 | this.implementing = implementing; 30 | this.defs = defs; 31 | this.sym = sym; 32 | } 33 | 34 | public int getTag(){ 35 | return tag; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/tree/state/LzyJCContinue.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.tree.state; 2 | 3 | import work.liziyun.tree.LzyJCTree; 4 | import work.liziyun.tree.LzyVisitor; 5 | import work.liziyun.world.LzyName; 6 | 7 | public class LzyJCContinue extends LzyJCTree.JCStatement { 8 | public LzyName label; 9 | public LzyJCTree target; 10 | 11 | @Override 12 | public void accept(LzyVisitor visitor) { 13 | visitor.visitJCContinue(this); 14 | } 15 | 16 | public LzyJCContinue(LzyName label, LzyJCTree target) { 17 | super(CONTINUE); 18 | this.label = label; 19 | this.target = target; 20 | } 21 | 22 | public int getTag(){ 23 | return tag; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/tree/state/LzyJCDoloop.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.tree.state; 2 | 3 | import work.liziyun.tree.LzyJCTree; 4 | import work.liziyun.tree.LzyVisitor; 5 | 6 | public class LzyJCDoloop extends LzyJCTree.JCStatement { 7 | public LzyJCTree body; 8 | public LzyJCTree cond; 9 | @Override 10 | public void accept(LzyVisitor visitor) { 11 | visitor.visitJCDoloop(this); 12 | } 13 | 14 | public LzyJCDoloop(LzyJCTree body, LzyJCTree cond) { 15 | super(DOLOOP); 16 | this.body = body; 17 | this.cond = cond; 18 | } 19 | 20 | public int getTag(){ 21 | return tag; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/tree/state/LzyJCExec.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.tree.state; 2 | 3 | import work.liziyun.tree.LzyJCTree; 4 | import work.liziyun.tree.LzyVisitor; 5 | 6 | public class LzyJCExec extends LzyJCTree.JCStatement { 7 | public LzyJCTree expr; 8 | @Override 9 | public void accept(LzyVisitor visitor) { 10 | visitor.visitJCExec(this); 11 | } 12 | 13 | public LzyJCExec(LzyJCTree expr) { 14 | super(EXEC); 15 | this.expr = expr; 16 | } 17 | 18 | public int getTag(){ 19 | return tag; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/tree/state/LzyJCExpressionStatement.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.tree.state; 2 | 3 | import work.liziyun.tree.LzyJCTree; 4 | import work.liziyun.tree.LzyVisitor; 5 | 6 | public class LzyJCExpressionStatement extends LzyJCTree.JCStatement { 7 | 8 | public LzyJCTree.JCExpression expr; 9 | 10 | public LzyJCExpressionStatement(LzyJCTree.JCExpression expr) { 11 | super(LzyJCTree.EXEC); 12 | this.expr = expr; 13 | } 14 | 15 | @Override 16 | public void accept(LzyVisitor var1) { 17 | var1.visitJCExec(this); 18 | } 19 | 20 | public int getTag(){ 21 | return tag; 22 | } 23 | 24 | 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/tree/state/LzyJCForLoop.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.tree.state; 2 | 3 | 4 | import work.liziyun.tree.LzyJCTree; 5 | import work.liziyun.tree.LzyVisitor; 6 | import work.liziyun.util.LzyList; 7 | 8 | public class LzyJCForLoop extends LzyJCTree.JCStatement { 9 | 10 | public LzyList init; 11 | public LzyJCTree.JCExpression cond; 12 | public LzyList step; 13 | public LzyJCTree.JCStatement body; 14 | 15 | @Override 16 | public void accept(LzyVisitor visitor) { 17 | visitor.visitJCForLoop(this); 18 | } 19 | 20 | public LzyJCForLoop(LzyList init, LzyJCTree.JCExpression cond, LzyList step, LzyJCTree.JCStatement body) { 21 | super(FORLOOP); 22 | this.init = init; 23 | this.cond = cond; 24 | this.step = step; 25 | this.body = body; 26 | } 27 | 28 | public int getTag(){ 29 | return tag; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/tree/state/LzyJCIf.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.tree.state; 2 | 3 | import work.liziyun.tree.LzyJCTree; 4 | import work.liziyun.tree.LzyVisitor; 5 | 6 | public class LzyJCIf extends LzyJCTree.JCStatement { 7 | public LzyJCTree cond; 8 | public LzyJCTree thenpart; 9 | public LzyJCTree elsepart; 10 | @Override 11 | public void accept(LzyVisitor visitor) { 12 | visitor.visitJCIf(this); 13 | } 14 | 15 | public LzyJCIf(LzyJCTree cond, LzyJCTree thenpart, LzyJCTree elsepart) { 16 | super(IF); 17 | this.cond = cond; 18 | this.thenpart = thenpart; 19 | this.elsepart = elsepart; 20 | } 21 | 22 | public int getTag(){ 23 | return tag; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/tree/state/LzyJCReturn.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.tree.state; 2 | 3 | 4 | import work.liziyun.tree.LzyJCTree; 5 | import work.liziyun.tree.LzyVisitor; 6 | 7 | public class LzyJCReturn extends LzyJCTree.JCStatement { 8 | public LzyJCTree expr; 9 | @Override 10 | public void accept(LzyVisitor visitor) { 11 | visitor.visitJCReturn(this); 12 | } 13 | 14 | public LzyJCReturn(LzyJCTree expr) { 15 | super(RETURN); 16 | this.expr = expr; 17 | } 18 | public int getTag(){ 19 | return tag; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/tree/state/LzyJCSkip.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.tree.state; 2 | 3 | import work.liziyun.tree.LzyJCTree; 4 | import work.liziyun.tree.LzyVisitor; 5 | 6 | public class LzyJCSkip extends LzyJCTree.JCStatement { 7 | @Override 8 | public void accept(LzyVisitor visitor) { 9 | visitor.visitJCSkip(this); 10 | } 11 | 12 | public LzyJCSkip() { 13 | super(SKIP); 14 | } 15 | 16 | public int getTag(){ 17 | return tag; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/tree/state/LzyJCSwitch.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.tree.state; 2 | 3 | 4 | import work.liziyun.tree.LzyJCTree; 5 | import work.liziyun.tree.LzyVisitor; 6 | import work.liziyun.util.LzyList; 7 | 8 | public class LzyJCSwitch extends LzyJCTree.JCStatement { 9 | 10 | public LzyJCTree selector; 11 | public LzyList cases; 12 | 13 | @Override 14 | public void accept(LzyVisitor visitor) { 15 | visitor.visitJCSwitch(this); 16 | } 17 | 18 | public LzyJCSwitch(LzyJCTree selector, LzyList cases) { 19 | super(SWITCH); 20 | this.selector = selector; 21 | this.cases = cases; 22 | } 23 | 24 | public int getTag(){ 25 | return tag; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/tree/state/LzyJCThrow.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.tree.state; 2 | 3 | import work.liziyun.tree.LzyJCTree; 4 | import work.liziyun.tree.LzyVisitor; 5 | 6 | public class LzyJCThrow extends LzyJCTree.JCStatement { 7 | public LzyJCTree expr; 8 | @Override 9 | public void accept(LzyVisitor visitor) { 10 | visitor.visitJCThrow(this); 11 | } 12 | 13 | public LzyJCThrow(LzyJCTree expr) { 14 | super(THROW); 15 | this.expr = expr; 16 | } 17 | public int getTag(){ 18 | return tag; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/tree/state/LzyJCTry.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.tree.state; 2 | 3 | 4 | import work.liziyun.tree.LzyJCTree; 5 | import work.liziyun.tree.LzyVisitor; 6 | import work.liziyun.util.LzyList; 7 | 8 | public class LzyJCTry extends LzyJCTree.JCStatement { 9 | 10 | public LzyJCTree body; 11 | public LzyList catchers; 12 | public LzyJCBlock finalizer; 13 | 14 | @Override 15 | public void accept(LzyVisitor visitor) { 16 | visitor.visitJCTry(this); 17 | } 18 | 19 | public LzyJCTry(LzyJCTree body,LzyList catchers, LzyJCBlock finalizer) { 20 | super(TRY); 21 | this.body = body; 22 | this.catchers = catchers; 23 | this.finalizer = finalizer; 24 | } 25 | public int getTag(){ 26 | return tag; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/tree/state/LzyJCVarDef.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.tree.state; 2 | 3 | 4 | import work.liziyun.code.symbol.LzyVarSymbol; 5 | import work.liziyun.tree.LzyJCTree; 6 | import work.liziyun.tree.LzyVisitor; 7 | import work.liziyun.util.LzyList; 8 | import work.liziyun.world.LzyName; 9 | 10 | public class LzyJCVarDef extends LzyJCTree.JCStatement { 11 | public long flags; 12 | public LzyName name; 13 | public LzyJCTree vartype; 14 | public LzyJCTree init; 15 | public LzyVarSymbol sym; 16 | public static final LzyList emptyList = LzyList.nil(); 17 | @Override 18 | public void accept(LzyVisitor visitor) { 19 | visitor.visitJCVarDef(this); 20 | } 21 | 22 | public LzyJCVarDef(long flags, LzyName name, LzyJCTree vartype, LzyJCTree init, LzyVarSymbol sym) { 23 | super(VARDEF); 24 | this.flags = flags; 25 | this.name = name; 26 | this.vartype = vartype; 27 | this.init = init; 28 | this.sym = sym; 29 | } 30 | 31 | public int getTag(){ 32 | return tag; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/tree/state/LzyJCWhileLoop.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.tree.state; 2 | 3 | import work.liziyun.tree.LzyJCTree; 4 | import work.liziyun.tree.LzyVisitor; 5 | 6 | public class LzyJCWhileLoop extends LzyJCTree.JCStatement { 7 | public LzyJCTree cond; 8 | public LzyJCTree body; 9 | 10 | @Override 11 | public void accept(LzyVisitor visitor) { 12 | visitor.visitJCWhileLoop(this); 13 | } 14 | 15 | public LzyJCWhileLoop(LzyJCTree cond, LzyJCTree body) { 16 | super(WHILELOOP); 17 | this.cond = cond; 18 | this.body = body; 19 | } 20 | 21 | public int getTag(){ 22 | return tag; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/util/LzyAssert.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.util; 2 | 3 | public class LzyAssert { 4 | 5 | public static void check(boolean var0) { 6 | if (!var0) { 7 | error(); 8 | } 9 | 10 | } 11 | 12 | public static void checkNull(Object var0) { 13 | if (var0 != null) { 14 | error(); 15 | } 16 | 17 | } 18 | 19 | public static T checkNonNull(T var0) { 20 | if (var0 == null) { 21 | error(); 22 | } 23 | 24 | return var0; 25 | } 26 | 27 | public static void check(boolean var0, int var1) { 28 | if (!var0) { 29 | error(String.valueOf(var1)); 30 | } 31 | 32 | } 33 | 34 | public static void check(boolean var0, long var1) { 35 | if (!var0) { 36 | error(String.valueOf(var1)); 37 | } 38 | 39 | } 40 | 41 | public static void check(boolean var0, Object var1) { 42 | if (!var0) { 43 | error(String.valueOf(var1)); 44 | } 45 | 46 | } 47 | 48 | public static void check(boolean var0, String var1) { 49 | if (!var0) { 50 | error(var1); 51 | } 52 | 53 | } 54 | 55 | public static void checkNull(Object var0, Object var1) { 56 | if (var0 != null) { 57 | error(String.valueOf(var1)); 58 | } 59 | 60 | } 61 | 62 | public static void checkNull(Object var0, String var1) { 63 | if (var0 != null) { 64 | error(var1); 65 | } 66 | 67 | } 68 | 69 | public static T checkNonNull(T var0, String var1) { 70 | if (var0 == null) { 71 | error(var1); 72 | } 73 | 74 | return var0; 75 | } 76 | 77 | public static void error() { 78 | throw new AssertionError(); 79 | } 80 | 81 | public static void error(String var0) { 82 | throw new AssertionError(var0); 83 | } 84 | 85 | private LzyAssert() { 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/util/LzyByteBuffer.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.util; 2 | 3 | import work.liziyun.world.LzyName; 4 | import work.liziyun.world.LzyTable; 5 | 6 | import java.io.ByteArrayOutputStream; 7 | import java.io.DataOutputStream; 8 | import java.io.IOException; 9 | 10 | public class LzyByteBuffer { 11 | public byte[] elems; 12 | public int length; 13 | 14 | public LzyByteBuffer() { 15 | this(64); 16 | } 17 | 18 | public void reset() { 19 | this.length = 0; 20 | } 21 | 22 | public void appendDouble(double var1) { 23 | ByteArrayOutputStream var3 = new ByteArrayOutputStream(8); 24 | DataOutputStream var4 = new DataOutputStream(var3); 25 | 26 | try { 27 | var4.writeDouble(var1); 28 | this.appendBytes(var3.toByteArray(), 0, 8); 29 | } catch (IOException var6) { 30 | throw new AssertionError("write"); 31 | } 32 | } 33 | 34 | public void appendFloat(float var1) { 35 | ByteArrayOutputStream var2 = new ByteArrayOutputStream(4); 36 | DataOutputStream var3 = new DataOutputStream(var2); 37 | 38 | try { 39 | var3.writeFloat(var1); 40 | this.appendBytes(var2.toByteArray(), 0, 4); 41 | } catch (IOException var5) { 42 | throw new AssertionError("write"); 43 | } 44 | } 45 | 46 | public LzyByteBuffer(int var1) { 47 | this.elems = new byte[var1]; 48 | this.length = 0; 49 | } 50 | 51 | public void appendByte(int var1) { 52 | if (this.length >= this.elems.length) { 53 | this.copy(this.elems.length * 2); 54 | } 55 | 56 | this.elems[this.length++] = (byte)var1; 57 | } 58 | 59 | public void appendChar(int var1) { 60 | while(this.length + 1 >= this.elems.length) { 61 | this.copy(this.elems.length * 2); 62 | } 63 | 64 | this.elems[this.length] = (byte)(var1 >> 8 & 255); 65 | this.elems[this.length + 1] = (byte)(var1 & 255); 66 | this.length += 2; 67 | } 68 | 69 | public void appendInt(int var1) { 70 | while(this.length + 3 >= this.elems.length) { 71 | this.copy(this.elems.length * 2); 72 | } 73 | 74 | this.elems[this.length] = (byte)(var1 >> 24 & 255); 75 | this.elems[this.length + 1] = (byte)(var1 >> 16 & 255); 76 | this.elems[this.length + 2] = (byte)(var1 >> 8 & 255); 77 | this.elems[this.length + 3] = (byte)(var1 & 255); 78 | this.length += 4; 79 | } 80 | 81 | private void copy(int var1) { 82 | byte[] var2 = new byte[var1]; 83 | System.arraycopy(this.elems, 0, var2, 0, this.elems.length); 84 | this.elems = var2; 85 | } 86 | 87 | public void appendLong(long var1) { 88 | ByteArrayOutputStream var3 = new ByteArrayOutputStream(8); 89 | DataOutputStream var4 = new DataOutputStream(var3); 90 | 91 | try { 92 | var4.writeLong(var1); 93 | this.appendBytes(var3.toByteArray(), 0, 8); 94 | } catch (IOException var6) { 95 | throw new AssertionError("write"); 96 | } 97 | } 98 | 99 | public void appendBytes(byte[] var1) { 100 | this.appendBytes(var1, 0, var1.length); 101 | } 102 | 103 | public void appendBytes(byte[] var1, int var2, int var3) { 104 | while(this.length + var3 > this.elems.length) { 105 | this.copy(this.elems.length * 2); 106 | } 107 | 108 | System.arraycopy(var1, var2, this.elems, this.length, var3); 109 | this.length += var3; 110 | } 111 | 112 | public void appendName(LzyName name) { 113 | this.appendBytes(name.lzyTable.bytes, name.index, name.length); 114 | } 115 | 116 | public LzyName toName(LzyTable var1) { 117 | return var1.fromUtf(this.elems, 0, this.length); 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/util/LzyContext.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.util; 2 | 3 | 4 | 5 | 6 | import java.util.HashMap; 7 | import java.util.Iterator; 8 | import java.util.Map; 9 | 10 | public class LzyContext { 11 | 12 | private Map, Object> ht = new HashMap(); 13 | private Map, LzyContext.Factory> ft = new HashMap(); 14 | private Map, LzyContext.Key> kt = new HashMap(); 15 | 16 | public void put(LzyContext.Key var1, LzyContext.Factory var2) { 17 | checkState(this.ht); 18 | Object var3 = this.ht.put(var1, var2); 19 | if (var3 != null) { 20 | throw new AssertionError("duplicate LzyContext value"); 21 | } else { 22 | checkState(this.ft); 23 | this.ft.put(var1, var2); 24 | } 25 | } 26 | 27 | public void put(LzyContext.Key var1, T var2) { 28 | if (var2 instanceof LzyContext.Factory) { 29 | throw new AssertionError("T extends LzyContext.Factory"); 30 | } else { 31 | checkState(this.ht); 32 | Object var3 = this.ht.put(var1, var2); 33 | if (var3 != null && !(var3 instanceof LzyContext.Factory) && var3 != var2 && var2 != null) { 34 | throw new AssertionError("duplicate LzyContext value"); 35 | } 36 | } 37 | } 38 | 39 | public T get(LzyContext.Key var1) { 40 | checkState(this.ht); 41 | Object var2 = this.ht.get(var1); 42 | if (var2 instanceof LzyContext.Factory) { 43 | LzyContext.Factory var3 = (LzyContext.Factory)var2; 44 | var2 = var3.make(this); 45 | if (var2 instanceof LzyContext.Factory) { 46 | throw new AssertionError("T extends LzyContext.Factory"); 47 | } 48 | 49 | LzyAssert.check(this.ht.get(var1) == var2); 50 | } 51 | 52 | return (T) uncheckedCast(var2); 53 | } 54 | 55 | public LzyContext() { 56 | } 57 | 58 | public LzyContext(LzyContext var1) { 59 | this.kt.putAll(var1.kt); 60 | this.ft.putAll(var1.ft); 61 | this.ht.putAll(var1.ft); 62 | } 63 | 64 | private LzyContext.Key key(Class var1) { 65 | checkState(this.kt); 66 | LzyContext.Key var2 = (LzyContext.Key)uncheckedCast(this.kt.get(var1)); 67 | if (var2 == null) { 68 | var2 = new LzyContext.Key(); 69 | this.kt.put(var1, var2); 70 | } 71 | 72 | return var2; 73 | } 74 | 75 | public T get(Class var1) { 76 | return this.get(this.key(var1)); 77 | } 78 | 79 | public void put(Class var1, T var2) { 80 | this.put(this.key(var1), var2); 81 | } 82 | 83 | public void put(Class var1, LzyContext.Factory var2) { 84 | this.put(this.key(var1), var2); 85 | } 86 | 87 | private static T uncheckedCast(T var0) { 88 | return var0; 89 | } 90 | 91 | public void dump() { 92 | Iterator var1 = this.ht.values().iterator(); 93 | 94 | while(var1.hasNext()) { 95 | Object var2 = var1.next(); 96 | System.err.println(var2 == null ? null : var2.getClass()); 97 | } 98 | 99 | } 100 | 101 | public void clear() { 102 | this.ht = null; 103 | this.kt = null; 104 | this.ft = null; 105 | } 106 | 107 | private static void checkState(Map var0) { 108 | if (var0 == null) { 109 | throw new IllegalStateException(); 110 | } 111 | } 112 | 113 | public interface Factory { 114 | T make(LzyContext var1); 115 | } 116 | 117 | public static class Key { 118 | public Key() { 119 | } 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/util/LzyConvert.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.util; 2 | 3 | 4 | 5 | import work.liziyun.world.LzyName; 6 | 7 | public class LzyConvert { 8 | 9 | public static int string2int(String data,int raidx){ 10 | if ( raidx == 10 ){ 11 | return Integer.parseInt(data,raidx); 12 | }else{ 13 | System.out.println("编译错误: 只能处理10进制字面量!"); 14 | return -1; 15 | } 16 | } 17 | 18 | public static long string2long(String data,int radix){ 19 | if ( radix == 10 ){ 20 | return Long.parseLong(data,radix); 21 | }else{ 22 | System.out.println("编译错误: 只能处理10进制字面量!"); 23 | return -1; 24 | } 25 | } 26 | 27 | 28 | public static int chars2utf(char[] src,int sIndex,byte[] dst,int dIndex,int len){ 29 | int j = dIndex; 30 | int sEnd = sIndex + len; 31 | for ( int i = sIndex ; i < sEnd ; i++ ){ 32 | // 1100000 + 后5位 33 | char c = src[i]; 34 | 35 | if ( c >= 1 && c <= 127){ 36 | dst[j++] = (byte) c; 37 | }else{ 38 | System.out.println("编译错误: 暂不支持复杂的字符编码"); 39 | } 40 | } 41 | return j; 42 | } 43 | 44 | 45 | /** 46 | * 截取$符号前的Name 47 | * @param name 48 | * @return 49 | */ 50 | public static LzyList enclosingCandidates(LzyName name){ 51 | LzyList list = LzyList.nil(); 52 | int pos; 53 | // 在Name中查找'$'的位置. 54 | // 注意: 如果$的位置是第一个,那么不处理。因为我们要截取$符号前面的内容 55 | while ( ( pos = name.lastIndexOf((byte)'$') ) > 0){ 56 | name = name.subName(0,pos); 57 | list = list.prepend(name); 58 | } 59 | return list; 60 | } 61 | 62 | /** 63 | * 截取简单类名: 去掉前面的包名 64 | * @param name 65 | * @return 66 | */ 67 | public static LzyName shortName(LzyName name){ 68 | return name.subName(name.lastIndexOf((byte)'.')+1,name.getByteLength()); 69 | } 70 | 71 | 72 | public static LzyName packagePart(LzyName name){ 73 | return name.subName(0,name.lastIndexOf((byte)'.')); 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/util/LzyHashtable.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.util; 2 | 3 | 4 | public class LzyHashtable { 5 | private int hashSize; 6 | private int hashMask; 7 | private int limit; 8 | private int size; 9 | private LzyHashtable.Entry[] table; 10 | 11 | public int size(){ 12 | return this.size; 13 | } 14 | 15 | 16 | public LzyHashtable(){ 17 | this(32); 18 | } 19 | 20 | public LzyHashtable(int maxSize){ 21 | this(maxSize,0.75f); 22 | } 23 | 24 | 25 | /** 26 | * 27 | * @param maxSize 大小的参考值 28 | * @param rate 增长因子 29 | */ 30 | public LzyHashtable(int maxSize,float rate){ 31 | int capacity = 1; 32 | while (size < maxSize){ 33 | // 2倍增长 34 | capacity <<= 1; 35 | } 36 | this.hashSize = capacity; 37 | this.hashMask = capacity - 1; 38 | // 阀值 39 | this.limit = (int)(size * rate); 40 | // 实际大小 41 | this.size = 0; 42 | // 初始化 43 | this.table = new LzyHashtable.Entry[capacity]; 44 | } 45 | 46 | 47 | 48 | // 工厂方法 49 | public static LzyHashtable make(){ 50 | return new LzyHashtable(); 51 | } 52 | // 扩容 53 | private void dble(){ 54 | // 大小增长一倍 55 | this.hashSize <<= 1; 56 | // 掩码 57 | this.hashMask = this.hashSize - 1; 58 | // 阀值: 增长一倍 59 | this.limit <<= 1; 60 | // 旧数据 61 | LzyHashtable.Entry[] oldTables = this.table; 62 | // 新 63 | this.table = new LzyHashtable.Entry[this.hashSize]; 64 | // 复制数据 65 | for (Entry oldEntry : oldTables) { 66 | // 冲突链 67 | LzyHashtable.Entry entry = null; 68 | while (oldEntry != null){ 69 | entry = oldEntry.next; 70 | // hash 71 | int hash = oldEntry.hash & this.hashMask; 72 | // 指向旧链 73 | oldEntry.next = this.table[hash]; 74 | // 放入第一个位置 75 | this.table[hash] = oldEntry; 76 | // 下一个 77 | oldEntry = entry; 78 | } 79 | } 80 | } 81 | 82 | 83 | // 置空 84 | public void reset(){ 85 | for (int i = 0; i < this.table.length; i++) { 86 | this.table[i] = null; 87 | } 88 | this.size = 0; 89 | } 90 | /* 91 | public List keys(){ 92 | 93 | } 94 | 95 | public Object get(Object key){ 96 | 97 | } 98 | 99 | public Object remove(Object key){ 100 | 101 | }*/ 102 | 103 | // 元素 104 | private static class Entry{ 105 | Object key; 106 | Object value; 107 | int hash; 108 | LzyHashtable.Entry next; 109 | 110 | public Entry(Object key, Object value, int hash, Entry next) { 111 | this.key = key; 112 | this.value = value; 113 | this.hash = hash; 114 | this.next = next; 115 | } 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/util/LzyList.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.util; 2 | 3 | 4 | 5 | 6 | import java.lang.reflect.Array; 7 | import java.util.*; 8 | 9 | public class LzyList extends AbstractCollection implements java.util.List { 10 | public A head; 11 | public LzyList tail; 12 | private static LzyList EMPTY_LIST = new LzyList((Object)null, (LzyList)null) { 13 | public LzyList setTail(LzyList var1) { 14 | throw new UnsupportedOperationException(); 15 | } 16 | 17 | public boolean isEmpty() { 18 | return true; 19 | } 20 | }; 21 | private static Iterator EMPTYITERATOR = new Iterator() { 22 | public boolean hasNext() { 23 | return false; 24 | } 25 | 26 | public Object next() { 27 | throw new NoSuchElementException(); 28 | } 29 | 30 | public void remove() { 31 | throw new UnsupportedOperationException(); 32 | } 33 | }; 34 | 35 | LzyList(A var1, LzyList var2) { 36 | this.tail = var2; 37 | this.head = var1; 38 | } 39 | 40 | public static LzyList nil() { 41 | return (LzyList) EMPTY_LIST; 42 | } 43 | 44 | public static LzyList of(A var0) { 45 | return new LzyList(var0, nil()); 46 | } 47 | 48 | public static LzyList of(A var0, A var1) { 49 | return new LzyList(var0, of(var1)); 50 | } 51 | 52 | public static LzyList of(A var0, A var1, A var2) { 53 | return new LzyList(var0, of(var1, var2)); 54 | } 55 | 56 | public static LzyList of(A var0, A var1, A var2, A... var3) { 57 | return new LzyList(var0, new LzyList(var1, new LzyList(var2, from(var3)))); 58 | } 59 | 60 | public static LzyList from(A[] var0) { 61 | LzyList var1 = nil(); 62 | if (var0 != null) { 63 | for(int var2 = var0.length - 1; var2 >= 0; --var2) { 64 | var1 = new LzyList(var0[var2], var1); 65 | } 66 | } 67 | 68 | return var1; 69 | } 70 | 71 | /** @deprecated */ 72 | @Deprecated 73 | public static LzyList fill(int var0, A var1) { 74 | LzyList var2 = nil(); 75 | 76 | for(int var3 = 0; var3 < var0; ++var3) { 77 | var2 = new LzyList(var1, var2); 78 | } 79 | 80 | return var2; 81 | } 82 | 83 | public boolean isEmpty() { 84 | return this.tail == null; 85 | } 86 | 87 | public boolean nonEmpty() { 88 | return this.tail != null; 89 | } 90 | 91 | public int length() { 92 | LzyList var1 = this; 93 | 94 | int var2; 95 | for(var2 = 0; var1.tail != null; ++var2) { 96 | var1 = var1.tail; 97 | } 98 | 99 | return var2; 100 | } 101 | 102 | public int size() { 103 | return this.length(); 104 | } 105 | 106 | public LzyList setTail(LzyList var1) { 107 | this.tail = var1; 108 | return var1; 109 | } 110 | 111 | public LzyList prepend(A var1) { 112 | return new LzyList(var1, this); 113 | } 114 | 115 | public LzyList prependList(LzyList var1) { 116 | if (this.isEmpty()) { 117 | return var1; 118 | } else if (var1.isEmpty()) { 119 | return this; 120 | } else if (var1.tail.isEmpty()) { 121 | return this.prepend(var1.head); 122 | } else { 123 | LzyList var2 = this; 124 | LzyList var3 = var1.reverse(); 125 | LzyAssert.check(var3 != var1); 126 | 127 | while(var3.nonEmpty()) { 128 | LzyList var4 = var3; 129 | var3 = var3.tail; 130 | var4.setTail(var2); 131 | var2 = var4; 132 | } 133 | 134 | return var2; 135 | } 136 | } 137 | 138 | public LzyList reverse() { 139 | if (!this.isEmpty() && !this.tail.isEmpty()) { 140 | LzyList var1 = nil(); 141 | 142 | for(LzyList var2 = this; var2.nonEmpty(); var2 = var2.tail) { 143 | var1 = new LzyList(var2.head, var1); 144 | } 145 | 146 | return var1; 147 | } else { 148 | return this; 149 | } 150 | } 151 | 152 | public LzyList append(A var1) { 153 | return of(var1).prependList(this); 154 | } 155 | 156 | public LzyList appendList(LzyList var1) { 157 | return var1.prependList(this); 158 | } 159 | 160 | public LzyList appendList(LzyListBuffer var1) { 161 | return this.appendList(var1.toList()); 162 | } 163 | 164 | public T[] toArray(T[] var1) { 165 | int var2 = 0; 166 | LzyList var3 = this; 167 | 168 | for(Object[] var4 = var1; var3.nonEmpty() && var2 < var1.length; ++var2) { 169 | var4[var2] = var3.head; 170 | var3 = var3.tail; 171 | } 172 | 173 | if (var3.isEmpty()) { 174 | if (var2 < var1.length) { 175 | var1[var2] = null; 176 | } 177 | 178 | return var1; 179 | } else { 180 | var1 = (T[]) Array.newInstance(var1.getClass().getComponentType(), this.size()); 181 | return this.toArray(var1); 182 | } 183 | } 184 | 185 | public Object[] toArray() { 186 | return this.toArray(new Object[this.size()]); 187 | } 188 | 189 | public String toString(String var1) { 190 | if (this.isEmpty()) { 191 | return ""; 192 | } else { 193 | StringBuffer var2 = new StringBuffer(); 194 | var2.append(this.head); 195 | 196 | for(LzyList var3 = this.tail; var3.nonEmpty(); var3 = var3.tail) { 197 | var2.append(var1); 198 | var2.append(var3.head); 199 | } 200 | 201 | return var2.toString(); 202 | } 203 | } 204 | 205 | public String toString() { 206 | return this.toString(","); 207 | } 208 | 209 | public int hashCode() { 210 | LzyList var1 = this; 211 | 212 | int var2; 213 | for(var2 = 1; var1.tail != null; var1 = var1.tail) { 214 | var2 = var2 * 31 + (var1.head == null ? 0 : var1.head.hashCode()); 215 | } 216 | 217 | return var2; 218 | } 219 | 220 | public boolean equals(Object var1) { 221 | if (var1 instanceof List) { 222 | return equals(this, (LzyList)var1); 223 | } else if (!(var1 instanceof java.util.List)) { 224 | return false; 225 | } else { 226 | LzyList var2 = this; 227 | 228 | Iterator var3; 229 | for(var3 = ((java.util.List)var1).iterator(); var2.tail != null && var3.hasNext(); var2 = var2.tail) { 230 | Object var4 = var3.next(); 231 | if (var2.head == null) { 232 | if (var4 != null) { 233 | return false; 234 | } 235 | } else if (!var2.head.equals(var4)) { 236 | return false; 237 | } 238 | } 239 | 240 | return var2.isEmpty() && !var3.hasNext(); 241 | } 242 | } 243 | 244 | public static boolean equals(LzyList var0, LzyList var1) { 245 | while(var0.tail != null && var1.tail != null) { 246 | if (var0.head == null) { 247 | if (var1.head != null) { 248 | return false; 249 | } 250 | } else if (!var0.head.equals(var1.head)) { 251 | return false; 252 | } 253 | 254 | var0 = var0.tail; 255 | var1 = var1.tail; 256 | } 257 | 258 | return var0.tail == null && var1.tail == null; 259 | } 260 | 261 | public boolean contains(Object var1) { 262 | for(LzyList var2 = this; var2.tail != null; var2 = var2.tail) { 263 | if (var1 == null) { 264 | if (var2.head == null) { 265 | return true; 266 | } 267 | } else if (var2.head.equals(var1)) { 268 | return true; 269 | } 270 | } 271 | 272 | return false; 273 | } 274 | 275 | public A last() { 276 | A var1 = null; 277 | 278 | for(LzyList var2 = this; var2.tail != null; var2 = var2.tail) { 279 | var1 = var2.head; 280 | } 281 | 282 | return var1; 283 | } 284 | 285 | public static LzyList convert(Class var0, LzyList var1) { 286 | if (var1 == null) { 287 | return null; 288 | } else { 289 | Iterator var2 = var1.iterator(); 290 | 291 | while(var2.hasNext()) { 292 | Object var3 = var2.next(); 293 | var0.cast(var3); 294 | } 295 | 296 | return var1; 297 | } 298 | } 299 | 300 | private static Iterator emptyIterator() { 301 | return (Iterator) EMPTYITERATOR; 302 | } 303 | 304 | public Iterator iterator() { 305 | return this.tail == null ? emptyIterator() : new Iterator() { 306 | LzyList elems = LzyList.this; 307 | 308 | public boolean hasNext() { 309 | return this.elems.tail != null; 310 | } 311 | 312 | public A next() { 313 | if (this.elems.tail == null) { 314 | throw new NoSuchElementException(); 315 | } else { 316 | A var1 = this.elems.head; 317 | this.elems = this.elems.tail; 318 | return var1; 319 | } 320 | } 321 | 322 | public void remove() { 323 | throw new UnsupportedOperationException(); 324 | } 325 | }; 326 | } 327 | 328 | public A get(int var1) { 329 | if (var1 < 0) { 330 | throw new IndexOutOfBoundsException(String.valueOf(var1)); 331 | } else { 332 | LzyList var2 = this; 333 | 334 | for(int var3 = var1; var3-- > 0 && !var2.isEmpty(); var2 = var2.tail) { 335 | } 336 | 337 | if (var2.isEmpty()) { 338 | throw new IndexOutOfBoundsException("Index: " + var1 + ", " + "Size: " + this.size()); 339 | } else { 340 | return var2.head; 341 | } 342 | } 343 | } 344 | 345 | public boolean addAll(int var1, Collection var2) { 346 | if (var2.isEmpty()) { 347 | return false; 348 | } else { 349 | throw new UnsupportedOperationException(); 350 | } 351 | } 352 | 353 | public A set(int var1, A var2) { 354 | throw new UnsupportedOperationException(); 355 | } 356 | 357 | public void add(int var1, A var2) { 358 | throw new UnsupportedOperationException(); 359 | } 360 | 361 | public A remove(int var1) { 362 | throw new UnsupportedOperationException(); 363 | } 364 | 365 | public int indexOf(Object var1) { 366 | int var2 = 0; 367 | LzyList var3 = this; 368 | 369 | while(true) { 370 | if (var3.tail == null) { 371 | return -1; 372 | } 373 | 374 | if (var3.head == null) { 375 | if (var1 == null) { 376 | break; 377 | } 378 | } else if (var3.head.equals(var1)) { 379 | break; 380 | } 381 | 382 | var3 = var3.tail; 383 | ++var2; 384 | } 385 | 386 | return var2; 387 | } 388 | 389 | public int lastIndexOf(Object var1) { 390 | int var2 = -1; 391 | int var3 = 0; 392 | 393 | for(LzyList var4 = this; var4.tail != null; ++var3) { 394 | label18: { 395 | if (var4.head == null) { 396 | if (var1 != null) { 397 | break label18; 398 | } 399 | } else if (!var4.head.equals(var1)) { 400 | break label18; 401 | } 402 | 403 | var2 = var3; 404 | } 405 | 406 | var4 = var4.tail; 407 | } 408 | 409 | return var2; 410 | } 411 | 412 | public ListIterator listIterator() { 413 | return Collections.unmodifiableList(new ArrayList(this)).listIterator(); 414 | } 415 | 416 | public ListIterator listIterator(int var1) { 417 | return Collections.unmodifiableList(new ArrayList(this)).listIterator(var1); 418 | } 419 | 420 | public java.util.List subList(int var1, int var2) { 421 | if (var1 >= 0 && var2 <= this.size() && var1 <= var2) { 422 | ArrayList var3 = new ArrayList(var2 - var1); 423 | int var4 = 0; 424 | 425 | for(LzyList var5 = this; var5.tail != null && var4 != var2; ++var4) { 426 | if (var4 >= var1) { 427 | var3.add(var5.head); 428 | } 429 | 430 | var5 = var5.tail; 431 | } 432 | 433 | return Collections.unmodifiableList(var3); 434 | } else { 435 | throw new IllegalArgumentException(); 436 | } 437 | } 438 | 439 | 440 | } 441 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/util/LzyListBuffer.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.util; 2 | 3 | 4 | 5 | import java.util.AbstractQueue; 6 | import java.util.Collection; 7 | import java.util.Iterator; 8 | import java.util.NoSuchElementException; 9 | 10 | public class LzyListBuffer extends AbstractQueue { 11 | public LzyList elems; 12 | public LzyList last; 13 | public int count; 14 | public boolean shared; 15 | 16 | public static LzyListBuffer lb() { 17 | return new LzyListBuffer(); 18 | } 19 | 20 | public static LzyListBuffer of(T var0) { 21 | LzyListBuffer var1 = new LzyListBuffer(); 22 | var1.add(var0); 23 | return var1; 24 | } 25 | 26 | public LzyListBuffer() { 27 | this.clear(); 28 | } 29 | 30 | public final void clear() { 31 | this.elems = new LzyList((Object)null, (LzyList)null); 32 | this.last = this.elems; 33 | this.count = 0; 34 | this.shared = false; 35 | } 36 | 37 | public int length() { 38 | return this.count; 39 | } 40 | 41 | public int size() { 42 | return this.count; 43 | } 44 | 45 | public boolean isEmpty() { 46 | return this.count == 0; 47 | } 48 | 49 | public boolean nonEmpty() { 50 | return this.count != 0; 51 | } 52 | 53 | private void copy() { 54 | LzyList var1 = this.elems = new LzyList(this.elems.head, this.elems.tail); 55 | 56 | while(true) { 57 | LzyList var2 = var1.tail; 58 | if (var2 == null) { 59 | this.last = var1; 60 | this.shared = false; 61 | return; 62 | } 63 | 64 | var2 = new LzyList(var2.head, var2.tail); 65 | var1.setTail(var2); 66 | var1 = var2; 67 | } 68 | } 69 | 70 | public LzyListBuffer prepend(A var1) { 71 | this.elems = this.elems.prepend(var1); 72 | ++this.count; 73 | return this; 74 | } 75 | 76 | public LzyListBuffer append(A var1) { 77 | var1.getClass(); 78 | if (this.shared) { 79 | this.copy(); 80 | } 81 | 82 | this.last.head = var1; 83 | this.last.setTail(new LzyList((Object)null, (LzyList)null)); 84 | this.last = this.last.tail; 85 | ++this.count; 86 | return this; 87 | } 88 | 89 | public LzyListBuffer appendList(LzyList var1) { 90 | while(var1.nonEmpty()) { 91 | this.append(var1.head); 92 | var1 = var1.tail; 93 | } 94 | 95 | return this; 96 | } 97 | 98 | public LzyListBuffer appendList(LzyListBuffer var1) { 99 | return this.appendList(var1.toList()); 100 | } 101 | 102 | public LzyListBuffer appendArray(A[] var1) { 103 | for(int var2 = 0; var2 < var1.length; ++var2) { 104 | this.append(var1[var2]); 105 | } 106 | 107 | return this; 108 | } 109 | 110 | public LzyList toList() { 111 | this.shared = true; 112 | return this.elems; 113 | } 114 | 115 | public boolean contains(Object var1) { 116 | return this.elems.contains(var1); 117 | } 118 | 119 | public T[] toArray(T[] var1) { 120 | return this.elems.toArray(var1); 121 | } 122 | 123 | public Object[] toArray() { 124 | return this.toArray(new Object[this.size()]); 125 | } 126 | 127 | public A first() { 128 | return this.elems.head; 129 | } 130 | 131 | public A next() { 132 | A var1 = this.elems.head; 133 | if (this.elems != this.last) { 134 | this.elems = this.elems.tail; 135 | --this.count; 136 | } 137 | 138 | return var1; 139 | } 140 | 141 | public Iterator iterator() { 142 | return new Iterator() { 143 | LzyList elems; 144 | 145 | { 146 | this.elems = LzyListBuffer.this.elems; 147 | } 148 | 149 | public boolean hasNext() { 150 | return this.elems != LzyListBuffer.this.last; 151 | } 152 | 153 | public A next() { 154 | if (this.elems == LzyListBuffer.this.last) { 155 | throw new NoSuchElementException(); 156 | } else { 157 | A var1 = this.elems.head; 158 | this.elems = this.elems.tail; 159 | return var1; 160 | } 161 | } 162 | 163 | public void remove() { 164 | throw new UnsupportedOperationException(); 165 | } 166 | }; 167 | } 168 | 169 | public boolean add(A var1) { 170 | this.append(var1); 171 | return true; 172 | } 173 | 174 | public boolean remove(Object var1) { 175 | throw new UnsupportedOperationException(); 176 | } 177 | 178 | public boolean containsAll(Collection var1) { 179 | Iterator var2 = var1.iterator(); 180 | 181 | Object var3; 182 | do { 183 | if (!var2.hasNext()) { 184 | return true; 185 | } 186 | 187 | var3 = var2.next(); 188 | } while(this.contains(var3)); 189 | 190 | return false; 191 | } 192 | 193 | public boolean addAll(Collection var1) { 194 | Iterator var2 = var1.iterator(); 195 | 196 | while(var2.hasNext()) { 197 | A var3 = (A) var2.next(); 198 | this.append(var3); 199 | } 200 | 201 | return true; 202 | } 203 | 204 | public boolean removeAll(Collection var1) { 205 | throw new UnsupportedOperationException(); 206 | } 207 | 208 | public boolean retainAll(Collection var1) { 209 | throw new UnsupportedOperationException(); 210 | } 211 | 212 | public boolean offer(A var1) { 213 | this.append(var1); 214 | return true; 215 | } 216 | 217 | public A poll() { 218 | return this.next(); 219 | } 220 | 221 | public A peek() { 222 | return this.first(); 223 | } 224 | } 225 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/util/LzyPosition.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.util; 2 | 3 | public class LzyPosition { 4 | public static final int LINESHIFT = 10; 5 | public static final int COLUMNMASK = 1023; 6 | public static final int NOPOS = 0; 7 | public static final int FIRSTPOS = 1025; 8 | public static final int MAXPOS = 2147483647; 9 | 10 | public LzyPosition() { 11 | } 12 | 13 | 14 | public static int column(int var0) { 15 | return var0 & 1023; 16 | } 17 | 18 | public static int line(int var0) { 19 | return var0 >>> 10; 20 | } 21 | 22 | public static int make(int var0, int var1) { 23 | return (var0 << 10) + var1; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/world/LzyKeywords.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.world; 2 | 3 | 4 | import work.liziyun.util.LzyContext; 5 | 6 | public class LzyKeywords { 7 | public static final LzyContext.Key key = new LzyContext.Key(); 8 | private final LzyTable lzyTable; 9 | // 下标原则: 通过Name在bytes中index 10 | private final LzyToken[] tokens; 11 | // 所有的Token建立Name,最大的Name在bytes中index 12 | private int maxKey = 0; 13 | // 敏感词的Name,下标原则: 枚举的下标 注意: 枚举中元素name不为空,才建立! 14 | private LzyName[] tokenName = new LzyName[LzyToken.values().length]; 15 | 16 | public static LzyKeywords instance(LzyContext LzyContext){ 17 | LzyKeywords lzyKeywords = (LzyKeywords)LzyContext.get(key); 18 | if (lzyKeywords == null){ 19 | lzyKeywords = new LzyKeywords(LzyContext); 20 | } 21 | return lzyKeywords; 22 | } 23 | public LzyKeywords(LzyContext LzyContext){ 24 | LzyContext.put(key,this); 25 | this.lzyTable = LzyTable.instance(LzyContext); 26 | // 所有的敏感词: Token转Name ---> 存储到tokenName 27 | for (LzyToken t : LzyToken.values()) { 28 | if (t.name != null){ 29 | this.enterKeyword(t.name,t); 30 | }else{ 31 | this.tokenName[t.ordinal()] = null; 32 | } 33 | } 34 | // 所有的Token: 标识符 35 | this.tokens = new LzyToken[this.maxKey+1]; 36 | for (int i = 0; i < tokens.length; i++) { 37 | this.tokens[i] = LzyToken.IDENTIFIER; 38 | } 39 | // 所有的敏感词: Name转Token ---> 存储到tokens 40 | for (LzyToken t : LzyToken.values()) { 41 | if (t.name != null){ 42 | // 获取每个Name的index 43 | int index = this.tokenName[t.ordinal()].getIndex(); 44 | this.tokens[index] = t; 45 | } 46 | } 47 | 48 | } 49 | 50 | // 通过Name获取Token 51 | public LzyToken key(LzyName lzyName){ 52 | // 标识符 53 | if ( lzyName.getIndex() > this.maxKey ){ 54 | return LzyToken.IDENTIFIER; 55 | }else{ 56 | return this.tokens[lzyName.getIndex()]; 57 | } 58 | } 59 | 60 | // 敏感词: Token转Name,全部存储成Name 61 | private void enterKeyword(String str,LzyToken lzyToken){ 62 | // 创建Name 63 | LzyName lzyName = this.lzyTable.fromString(str); 64 | this.tokenName[lzyToken.ordinal()] = lzyName; 65 | if (lzyName.getIndex() > this.maxKey){ 66 | this.maxKey = lzyName.getIndex(); 67 | } 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/world/LzyName.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.world; 2 | 3 | public class LzyName { 4 | public LzyTable lzyTable; 5 | public int index; 6 | public int length; 7 | LzyName next; 8 | 9 | public LzyName(LzyTable lzyTable, int index, int length) { 10 | this.lzyTable = lzyTable; 11 | this.index = index; 12 | this.length = length; 13 | } 14 | 15 | 16 | public int getIndex(){ 17 | return index; 18 | } 19 | public int getByteLength(){ 20 | return length; 21 | } 22 | public int hashCode(){ 23 | return this.index; 24 | } 25 | public String toString(){ 26 | return lzyTable.getString(index,length); 27 | } 28 | 29 | // 追加Name 30 | public LzyName append(char c,LzyName name){ 31 | // 新词的大小 32 | byte[] newBytes = new byte[this.length + name.length + 1]; 33 | // 将旧数据 拷贝到 新数据中 34 | this.getBytes(newBytes,0); 35 | // 新数组添加一个字符 36 | newBytes[this.length] = (byte) c; 37 | // 将name添加到新数据中 38 | name.getBytes(newBytes,this.length+1); 39 | // 不转码的方式创建 40 | return lzyTable.fromUtf(newBytes,0,newBytes.length); 41 | } 42 | // 追加Name: 两个Name相加 43 | public LzyName append(LzyName name){ 44 | byte[] newBytes = new byte[this.length + name.length]; 45 | // 拷贝数据到newBytes中: 目标0开始 46 | this.getBytes(newBytes,0); 47 | // 拷贝数据: 目标length开w 48 | name.getBytes(newBytes,this.length); 49 | return lzyTable.fromUtf(newBytes,0,newBytes.length); 50 | } 51 | 52 | public void getBytes(byte[] bytes,int start){ 53 | System.arraycopy(this.lzyTable.bytes,this.index,bytes,start,this.length); 54 | } 55 | 56 | public byte[] getByteArray(){ 57 | return this.lzyTable.bytes; 58 | } 59 | 60 | 61 | /** 62 | * 如果byte在Name存在,那么返回值一定大于等于0。 63 | * 如果bye不在Name中存在,那么返回值一定等于-1 64 | * @param b 65 | * @return 66 | */ 67 | public int lastIndexOf(byte b){ 68 | // Table中byte数组 69 | byte[] byteArray = this.getByteArray(); 70 | // Name的开始下标 71 | int startIndex = this.index; 72 | // Name的长度-1 73 | int length = this.length-1; 74 | // 在Name中查找指定的byte 75 | while (length >= 0 && byteArray[startIndex+length] != b){ 76 | length--; 77 | } 78 | return length; 79 | } 80 | 81 | 82 | /** 83 | * Name截取 84 | * @param start 相对于Name的开始位置 85 | * @param end 相对于Name的结束位置 86 | * @return 87 | */ 88 | public LzyName subName(int start,int end){ 89 | // 我们要更大的int 90 | if (end < start){ 91 | end = start; 92 | } 93 | // 参数二: 绝对位置 参数三: 长度 94 | return this.lzyTable.fromUtf(this.getByteArray(),this.index+start,end-start); 95 | } 96 | 97 | public byte[] toUtf() { 98 | byte[] newBytes = new byte[this.length]; 99 | System.arraycopy(this.lzyTable.bytes, this.index, newBytes, 0, this.length); 100 | return newBytes; 101 | } 102 | 103 | } 104 | 105 | -------------------------------------------------------------------------------- /src/main/java/work/liziyun/world/LzyToken.java: -------------------------------------------------------------------------------- 1 | package work.liziyun.world; 2 | 3 | /** 4 | * 作者: 李滋芸 5 | * Java敏感词 6 | */ 7 | public enum LzyToken { 8 | EOF, // 结束 9 | ERROR, // 错误 10 | IDENTIFIER, // 标识符 11 | ABSTRACT("abstract"), // 抽象 12 | BOOLEAN("boolean"), // 布尔 13 | BREAK("break"), 14 | BYTE("byte"), 15 | CASE("case"), 16 | CHAR("char"), 17 | CLASS("class"), 18 | CONTINUE("continue"), 19 | CATCH("catch"), 20 | DEFAULT("default"), 21 | DO("do"), 22 | DOUBLE("double"), 23 | ELSE("else"), 24 | EXTENDS("extends"), 25 | SYNCHRONIZED("synchronized"), 26 | FINAL("final"), 27 | FLOAT("float"), 28 | FINALLY("finally"), 29 | FOR("for"), 30 | IF("if"), 31 | IMPLEMENTS("implements"), 32 | IMPORT("import"), 33 | INSTANCEOF("instanceof"), 34 | INT("int"), 35 | INTERFACE("interface"), 36 | LONG("long"), 37 | NEW("new"), 38 | PACKAGE("package"), 39 | PRIVATE("private"), 40 | PROTECTED("protected"), 41 | PUBLIC("public"), 42 | RETURN("return"), 43 | SHORT("short"), 44 | STATIC("static"), 45 | SUPER("super"), 46 | SWITCH("switch"), 47 | THIS("this"), 48 | TRY("try"), 49 | THROW("throw"), 50 | VOID("void"), 51 | WHILE("while"), 52 | INTLITERAL, 53 | LONGLITERAL, 54 | FLOATLITERAL, 55 | DOUBLELITERAL, 56 | CHARLITERAL, 57 | STRINGLITERAL, 58 | TRUE("true"), 59 | FALSE("false"), 60 | NULL("null"), 61 | LPAREN("("), 62 | RPAREN(")"), 63 | LBRACE("{"), 64 | RBRACE("}"), 65 | LBRACKET("["), 66 | RBRACKET("]"), 67 | SEMI(";"), 68 | COMMA(","), 69 | DOT("."), 70 | EQ("="), 71 | GT(">"), 72 | LT("<"), 73 | BANG("!"), 74 | TILDE("~"), 75 | QUES("?"), 76 | COLON(":"), 77 | EQEQ("=="), 78 | LTEQ("<="), 79 | GTEQ(">="), 80 | BANGEQ("!="), 81 | AMPAMP("&&"), 82 | BARBAR("||"), 83 | PLUSPLUS("++"), 84 | SUBSUB("--"), 85 | PLUS("+"), 86 | SUB("-"), 87 | STAR("*"), 88 | SLASH("/"), 89 | AMP("&"), 90 | BAR("|"), 91 | CARET("^"), 92 | PERCENT("%"), 93 | LTLT("<<"), 94 | GTGT(">>"), 95 | GTGTGT(">>>"), 96 | PLUSEQ("+="), 97 | SUBEQ("-="), 98 | STAREQ("*="), 99 | SLASHEQ("/="), 100 | AMPEQ("&="), 101 | BAREQ("|="), 102 | CARETEQ("^="), 103 | PERCENTEQ("%="), 104 | LTLTEQ("<<="), 105 | GTGTEQ(">>="), 106 | GTGTGTEQ(">>>="), 107 | CUSTOM; 108 | // 关键字的名字 109 | public final String name; 110 | 111 | LzyToken() { 112 | this(null); 113 | } 114 | 115 | LzyToken(String name) { 116 | this.name = name; 117 | } 118 | // 词的类型: Java敏感词 119 | public String getKind(){ 120 | return "Token(Java敏感词)"; 121 | } 122 | // Java敏感词转字符串 123 | public String toString(){ 124 | switch (this){ 125 | // 标识符 126 | case IDENTIFIER: 127 | return "token.identifier"; 128 | case CHARLITERAL: // char字面量 129 | return "token.character"; 130 | case STRINGLITERAL: // 字符串 131 | return "token.string"; 132 | case INTLITERAL: // int字面量 133 | return "token.integer"; 134 | case LONGLITERAL: // long字面量 135 | return "token.long-integer"; 136 | case FLOATLITERAL: // float字面量 137 | return "token.float"; 138 | case DOUBLELITERAL: // double字面量 139 | return "token.double"; 140 | case ERROR: // 错误 141 | return "token.bad-symbol"; 142 | case EOF: // 结束 143 | return "token.end-of-input"; 144 | case DOT: // 点 145 | case COMMA: // 逗号 146 | case SEMI: // 分号 147 | case LPAREN: // 左小括号 148 | case RPAREN: // 右小括号 149 | case LBRACKET: // 左中括号 150 | case RBRACKET: // 右中括号 151 | case LBRACE: // 左花括号 152 | case RBRACE: // 右花括号 153 | return "'" + this.name + "'"; 154 | default: 155 | return this.name; 156 | } 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /test_javac/Anlimal.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anyewl/LzyJavac/58e8afbd8bab582df3c9b6d50162b1bf797fbfa3/test_javac/Anlimal.class -------------------------------------------------------------------------------- /test_javac/Anlimal.java: -------------------------------------------------------------------------------- 1 | public class Anlimal{ 2 | public Anlimal(){ 3 | System.out.println("111"); 4 | } 5 | public String name = "123"; 6 | } -------------------------------------------------------------------------------- /test_javac/Demo03.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anyewl/LzyJavac/58e8afbd8bab582df3c9b6d50162b1bf797fbfa3/test_javac/Demo03.class -------------------------------------------------------------------------------- /test_javac/Demo03.java: -------------------------------------------------------------------------------- 1 | public class Demo03 extends Anlimal{ 2 | 3 | public Anlimal anlimal = new Anlimal(); 4 | 5 | 6 | public static String[] fun(String[][][] args){ 7 | 8 | } 9 | 10 | public static void main(String []args){ 11 | int a = 1; 12 | int b = 2+3+a+1; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /test_javac/rt.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anyewl/LzyJavac/58e8afbd8bab582df3c9b6d50162b1bf797fbfa3/test_javac/rt.jar --------------------------------------------------------------------------------