├── .gitignore ├── .travis.yml ├── MANIFEST.MF ├── README.md ├── build.gradle ├── compiler ├── Main.sjava ├── avars.sjava ├── commands.sjava ├── emitters.sjava ├── handlers.sjava ├── mfilters.sjava └── tokens.sjava ├── examples ├── doubledispatch.expected.txt ├── doubledispatch.sjava ├── formatterTest.expected.txt ├── formatterTest.sjava ├── generics.expected.txt ├── generics.sjava ├── helloworld.sjava ├── intf.expected.txt ├── intf.sjava ├── lol.expected.txt ├── lol.sjava ├── macro.sjava ├── scope.expected.txt ├── scope.sjava ├── test.expected.txt ├── test.sjava ├── tictactoe.sjava ├── wow.expected.txt └── wow │ ├── a.sjava │ └── x │ └── y.sjava ├── fernflower.jar ├── generated-java └── sjava │ ├── compiler │ ├── AMethodInfo.java │ ├── AVar.java │ ├── Arg.java │ ├── CastVar.java │ ├── ClassInfo.java │ ├── ClassMacroMethodInfo.java │ ├── CompileScope.java │ ├── FileScope.java │ ├── Formatter.java │ ├── Lexer.java │ ├── MacroInfo.java │ ├── Main.java │ ├── MethodInfo.java │ ├── Parser.java │ ├── Tester.java │ ├── VCaptured.java │ ├── Var.java │ ├── commands │ │ ├── BuildCommand.java │ │ ├── Command.java │ │ ├── FormatCommand.java │ │ └── RunCommand.java │ ├── emitters │ │ ├── Emitter.java │ │ ├── Goto.java │ │ ├── LoadAVar.java │ │ ├── Nothing.java │ │ └── Null.java │ ├── handlers │ │ ├── CaptureVHandler.java │ │ ├── GenHandler.java │ │ └── Handler.java │ ├── mfilters │ │ ├── AFilter.java │ │ ├── BridgeFilter.java │ │ ├── MFilter.java │ │ └── MethodCall.java │ └── tokens │ │ ├── AGetToken.java │ │ ├── ALenToken.java │ │ ├── ASetToken.java │ │ ├── ArrayConstructorToken.java │ │ ├── ArrayToken.java │ │ ├── AsToken.java │ │ ├── BeginToken.java │ │ ├── BlockToken.java │ │ ├── BlockToken2.java │ │ ├── CToken.java │ │ ├── CallToken.java │ │ ├── ClassToken.java │ │ ├── ColonToken.java │ │ ├── CommentToken.java │ │ ├── CompareToken.java │ │ ├── ConstToken.java │ │ ├── ConstructorToken.java │ │ ├── DefaultToken.java │ │ ├── DefineToken.java │ │ ├── EmptyToken.java │ │ ├── FieldToken.java │ │ ├── GenericToken.java │ │ ├── GotoToken.java │ │ ├── IfToken.java │ │ ├── ImList.java │ │ ├── IncludeToken.java │ │ ├── InstanceToken.java │ │ ├── LabelToken.java │ │ ├── LambdaFnToken.java │ │ ├── LambdaToken.java │ │ ├── LexedParsedToken.java │ │ ├── LexedToken.java │ │ ├── MacroIncludeToken.java │ │ ├── NToken.java │ │ ├── NumOpToken.java │ │ ├── ObjectToken.java │ │ ├── ParsedToken.java │ │ ├── QuoteToken.java │ │ ├── QuoteToken2.java │ │ ├── ReturnToken.java │ │ ├── SToken.java │ │ ├── SetToken.java │ │ ├── ShiftToken.java │ │ ├── SingleQuoteToken.java │ │ ├── SpecialBeginToken.java │ │ ├── SynchronizedToken.java │ │ ├── ThrowToken.java │ │ ├── Token.java │ │ ├── TryToken.java │ │ ├── TypeToken.java │ │ ├── UnquoteToken.java │ │ └── VToken.java │ └── std │ ├── Function0.java │ ├── Function1.java │ ├── Function10.java │ ├── Function2.java │ ├── Function3.java │ ├── Function4.java │ ├── Function5.java │ ├── Function6.java │ ├── Function7.java │ ├── Function8.java │ ├── Function9.java │ ├── Tuple2.java │ └── Tuple3.java ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── kawa-patch ├── lib ├── asm.jar ├── commons-cli-1.3.1.jar ├── commons-io-2.5.jar ├── commons-lang-3.4.jar └── kawa.jar ├── plugin ├── build.gradle └── src │ └── main │ └── groovy │ └── sjava │ └── gradle │ ├── SjavaCompile.groovy │ └── SjavaPlugin.groovy ├── sjava ├── sjava.bat ├── sjava.jar └── std ├── FunctionN.sjava ├── TupleN.sjava └── macros.sjava /.gitignore: -------------------------------------------------------------------------------- 1 | bin/ 2 | generated-java/**/*.class 3 | .gradle/ 4 | build/ 5 | plugin/.gradle/ 6 | plugin/build/ 7 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | 3 | jdk: oraclejdk8 4 | 5 | os: linux 6 | 7 | script: ./gradlew diff tester java_sources java_compile 8 | 9 | install: true 10 | -------------------------------------------------------------------------------- /MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Main-Class: sjava.compiler.Main 3 | Class-Path: lib/asm.jar lib/kawa.jar lib/commons-lang-3.4.jar lib/commons-io-2.5.jar lib/commons-cli-1.3.1.jar 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # sJava - Java dialect using S-expressions [![Build Status](https://travis-ci.org/tombousso/sJava.svg?branch=master)](https://travis-ci.org/tombousso/sJava) 2 | Here's a hello world program in sJava (examples/helloworld.sjava): 3 | 4 | (define-class Main () public 5 | ((main args String[]) void public static 6 | (System:out:println "Hello world") 7 | ) 8 | ) 9 | 10 | and in Java: 11 | 12 | public class Main { 13 | public static void main(String[] args) { 14 | System.out.println("Hello world"); 15 | } 16 | } 17 | 18 | A more complex example of an sJava program including generics, autoboxing/unboxing, star imports, and type inference (examples/generics.sjava): 19 | 20 | (import java.util.*) 21 | (define-class Main () public 22 | ((main args String[]) void public static 23 | (define al (ArrayList{Integer})) ;constructor 24 | (al:add 3) 25 | (al:add 4) 26 | (System:out:println (+ (al:get 0) (al:get 1))) ;prints 7 27 | ) 28 | ) 29 | 30 | 31 | The sJava compiler outputs Java bytecode in classfiles just like the Java compiler. 32 | 33 | ### sJava features 34 | * hygenic compile-time macros 35 | * lambdas 36 | * autoboxing/unboxing 37 | * type inference 38 | * if statements/conditionals (short circuit) 39 | * arrays 40 | * generics (full support except wildcards) 41 | * loops 42 | * classes/methods/fields 43 | * a collection of useful "standard" macros (forEach, concat(enate), inc(rement), etc.) 44 | * most other things you'd except from a Java-like langauge 45 | 46 | ## Walkthrough! 47 | 48 | ### Requirements 49 | Java 8 - `java` 50 | 51 | ### Hierarchy (optional) 52 | 53 | ├── build.gradle (Gradle build script for the compiler and examples) 54 | ├── compiler/ 55 | │ ├── commands.sjava (BuildCommand, RunCommand, FormatCommand, etc.) 56 | │ ├── emitters.sjava 57 | │ ├── handlers.sjava (Bulk of the compilation code. compile methods in a Handler act on Tokens using double dispatch) 58 | │ ├── Main.sjava (Lexer, Parser, various structures, CLI entry, statics) 59 | │ ├── mfilters.sjava (Figuring out which methods to call) 60 | │ └── tokens.sjava 61 | ├── bin/ 62 | ├── examples/ 63 | │ ├── generics.sjava (A test program) 64 | │ ├── generics.expected.txt (The expected output) 65 | │ └── ... 66 | ├── lib/ 67 | │ ├── asm.jar 68 | │ ├── commons-cli-1.3.1.jar 69 | │ ├── commons-io-2.5.jar 70 | │ ├── commons-lang-3.4.jar 71 | │ └── kawa.jar 72 | ├── std/ (The standard library) 73 | │ ├── **.sjava 74 | │ └── macros.sjava (The standard macros) 75 | ├── sjava.jar (JAR version of *compiler* and *std*) 76 | ├── sjava (Unix script for *sjava.jar*) 77 | ├── sjava.bat (Windows script for *sjava.jar*) 78 | └── generated-java/ (Auto generated Java version of *compiler* using fernflower) 79 | 80 | ### Steps 81 | Once you've downloaded/cloned this repo open a terminal in its root directory. 82 | (On Windows use `sjava` instead of `./sjava`): 83 | 84 | > ./sjava 85 | usage: sjava [command] [arguments] 86 | 87 | Commands: 88 | 89 | build 90 | run 91 | fmt 92 | 93 | > ./sjava run 94 | usage: sjava run [files] 95 | 96 | To run `examples/tictactoe.sjava`, which uses a JavaFX GUI: 97 | 98 | > ./sjava run examples.tictactoe.Main examples/tictactoe.sjava 99 | 100 | Check out the code, it's about 200 lines. 101 | The `run` command compiles sJava code and runs it from memory. 102 | To build `compiler` from source and update your `sjava.jar` (On Windows use `gradlew` instead of `./gradlew`): 103 | 104 | > ./gradlew compilerJar 105 | 106 | If everything works you should notice a couple of new folders in your `bin/` directory including `bin/main/`, which contains the classfiles of `compiler` and `std`. 107 | Have a look in `bin/main/sjava/compiler/tokens/` if you're interested in the different Token types which are used during compilation. 108 | To run all of the tests in `examples/`: 109 | 110 | > ./gradlew tester 111 | doubledispatch: PASSED 112 | formatterTest: PASSED 113 | generics: PASSED 114 | ... 115 | 116 | This will compile all of the examples and check the ones which have expected outputs. 117 | You can run the `tictactoe` example again (this time the classes are already compiled in `bin/examples/tictactoe`): 118 | 119 | > ./gradlew run_tictactoe 120 | 121 | To run `examples/macro.sjava`: 122 | 123 | > ./gradlew run_macro 124 | Compiled at 21:16:37 08/27/2016 125 | Compile time dice roll result: 3 126 | Runtime random number up to 1000: 745 127 | > ./gradlew run_macro 128 | Compiled at 21:16:37 08/27/2016 129 | Compile time dice roll result: 3 130 | Runtime random number up to 1000: 131 131 | 132 | The date is the same in both runs because Gradle didn't recompile `macro.sjava`, since it didn't change. 133 | And finally to run `doubledispatch`: 134 | 135 | > ./gradlew run_doubledispatch 136 | Visitor1 received a String: a 137 | Visitor1 received a String: b 138 | Visitor1 received an Integer: 1 139 | Visitor1 received an Integer: 2 140 | 141 | Visitor2 received a String: a 142 | Visitor2 received a String: b 143 | Visitor2 received an Integer: 1 144 | Visitor2 received an Integer: 2 145 | 146 | If you have a look at `examples/doubledispatch.sjava` you will notice that it uses several macros, including `println` and `forEach`. 147 | The most interesting macro is called on line 28, `doubleDispatch`. This macro roughly expands to: 148 | 149 | (cond 150 | ((instance? o String) 151 | (this:visit (as String o)) 152 | ) 153 | ((instance? o Integer) 154 | (this:visit (as Integer o)) 155 | ) 156 | ) 157 | 158 | `cond` itself is actually a macro. 159 | All of these macros are defined in `std/macros.sjava`. 160 | 161 | ### More on macros 162 | In Java for-each loops and string concatenation are built in to the compiler. In sJava features like these are implemented as "standard macros" (`forEach` and `concat`) in `std/macros.sjava`, and they are available to all programs. 163 | 164 | Compile-time macros in sJava are very powerful. For example the `forEach` macro is able to ask the compiler at compile-time about the type of the object which the user is trying to iterate over. It checks if the type is an `ArrayType`, and if so it will create code which loops by incrementing a counter. Otherwise it will assume the user is trying to iterate over an `Iterable` and try to create an `Iterator`. 165 | 166 | The `concat` macro will automatically call `Arrays:toString` when passed in `ArrayType`s. 167 | 168 | You can create a `printTest.sjava` file: 169 | 170 | (define-class Main () public 171 | ((main args String[]) void public static 172 | (println "Counting to 3: " (int[] 1 2 3)) 173 | ) 174 | ) 175 | 176 | And run it: 177 | 178 | > ./sjava run Main printTest.sjava 179 | Counting to 3: [1, 2, 3] 180 | 181 | Or build then run: 182 | 183 | > ./sjava build printTest.sjava 184 | > java Main 185 | Counting to 3: [1, 2, 3] 186 | 187 | The `println` macro takes in a variable number of arguments and passes them all to `concat`, so you can see the `Arrays:toString` functionality in action. 188 | 189 | More features can be found in `examples/test.sjava`, in other examples, and in `compiler/**.sjava`. 190 | 191 | If you've followed the walkthrough all the way until here, congrats! Let me know if you have any thoughts. The compiler still has some bugs I'm sure but overall it works reasonably well. If there's an error in compilation it will at least tell you which line is problematic, but parsing errors aren't handled right now. 192 | 193 | ### Just for fun 194 | `fernflower.jar` is a crazy decompiler which can actually convert the bytecode of `compiler` into proper Java code! 195 | 196 | > ./gradlew java_sources 197 | 198 | And now that the Java files have been created: 199 | 200 | > ./gradlew java_compile 201 | 202 | If there are no errors then the diff ran successfully meaning that the Java version of `compiler` successfully compiled `compiler`. 203 | 204 | ## More explanations 205 | 206 | ### Kawa 207 | sJava borrows a lot from Kawa which is a Scheme implementation for the JVM. [Kawa](http://www.gnu.org/software/kawa/) is a really cool dynamic language (first class functions, macros, etc.) which can interact with traditional statically typed Java code. The first compiler for sJava was written in Kawa. 208 | 209 | ### Todo 210 | * verify sJava code and print friendly error messages 211 | * field initializers 212 | * fix everything :P 213 | 214 | ### Compiler 215 | #### gnu.bytecode 216 | Kawa is a Scheme implementation, but it is also a great framework with lots of useful libraries. The sJava compiler uses [gnu.bytecode](http://www.gnu.org/software/kawa/api/gnu/bytecode/package-summary.html) which is a library for generating Java bytecode in the form of classfiles (the link includes an example). gnu.bytecode is very useful because it simplifies bytecode generation and throws exceptions when your compiler does stuff that doesn't make sense. 217 | 218 | #### Stages 219 | The compiler has roughly 3 stages for compiling sJava code: 220 | 221 | * Create a ClassType object for each class which is defined in the sJava source file and handle imports 222 | * Add methods to the ClassType objects which have been created 223 | * Compile the method bodies 224 | 225 | Steps 1 and 2 have to be separate because a method in a class defined at the top of the file might want to return an instance of a class defined at the bottom of the file, for example. 226 | 227 | Most parts of the compilation are quite straightforward, however some parts are a bit tricky. 228 | 229 | #### If statements/conditionals 230 | In Java bytecode (and x86 assembler), conditionals like 231 | 232 | (define a (> 5 3)) 233 | 234 | will be compiled using branches: 235 | 236 | 0: iconst_5 237 | 1: iconst_3 238 | 2: if_icmple 9 239 | 5: iconst_1 240 | 6: goto 10 241 | 9: iconst_0 242 | 10: istore_1 243 | 11: return 244 | 245 | Instructions 0 and 1 push 5 and 3 onto the stack. Then the if_icmple instruction will determine that 5 is not less than or equal to 3 and so it will **not** jump to instruction 9. Therefore a one (true) will be pushed onto the stack and the goto will skip over instruction 9, which pushes a zero (false), into instruction 10 which stores true in a, the variable. 246 | 247 | The define above is equivalent to: 248 | 249 | (define a (if (> 5 3) true false)) 250 | 251 | Notice that the opposite comparison is used in the bytecode (less than or equal to instead of greater than). If you're wondering why, consider: 252 | 253 | (if (> 5 3) 254 | (System:out:println "Hello world") 255 | ) 256 | 257 | and the Java bytecode (shortened): 258 | 259 | 0: iconst_5 260 | 1: iconst_3 261 | 2: if_icmple 13 262 | System.out.println("Hello world"); 263 | 13: return 264 | 265 | Now that the branch doesn't have an "else", using the greather than instruction (if_icmpgt) instead of less than or equal to (if_icmple) would be quite awkward: 266 | 267 | 0: iconst_5 268 | 1: iconst_3 269 | 2: if_icmpgt 8 270 | 5: goto 16 271 | 8: System.out.println("Hello world"); 272 | 16: return 273 | 274 | ##### Implementation 275 | 276 | Ifs and conditionals are implemented using a recursive method (emitIf_). The method's parameters include a comparison operator, whether to inverse the comparison operator, the code for the true case, and the code for else (can be null). 277 | 278 | A not (!) in a conditional triggers a recursive call with the inverse comparator argument inversed. 279 | 280 | Short circuit ands (&&) and ors (||) are handled using De Morgan's laws, !(a && b) == (!a || !b) and !(a || b) == (!a && !b). 281 | 282 | This means that if the inverse argument is true and the comparison operator is && or the inverse argument is false and the comparison operator is ||, then an **or** is emitted (returns true when the first comparison results in a true, else false). 283 | 284 | If the inverse argument is true and the comparison operator is || or the inverse argument is false and the comparison operator is &&, then an **and** is emitted (returns false when the first comparison results in a false, else true). 285 | 286 | If the inverse comparator argument is true when a conditional needs to be emitted, the condition is inversed. 287 | 288 | Sounds a bit confusing but it works through the magic of recursion :) 289 | 290 | ### Final thoughts 291 | gnu.bytecode makes it easy to create classfiles and the JVM will do many optimizations as it's JITing so the bytecode doesn't really need much optimization. Also there are bytecode optimizers like ProGuard which can help with performance. Unlike the CLR which was designed by Microsoft to be the platform for many languages, the JVM was originally designed only for Java (no standard assembly language or assembler, etc), and so it seems like there are less languages which target the JVM. 292 | 293 | In case you're interested here is the decompiled bytecode of generics.sjava (javap -c) with added comments: 294 | 295 | public class Main { 296 | public static void main(java.lang.String[]); 297 | Code: 298 | 0: new #2 // class java/util/ArrayList 299 | 3: dup 300 | 4: invokespecial #6 // Method java/util/ArrayList."":()V 301 | 7: astore_1 //Constructing the ArrayList 302 | 8: aload_1 303 | 9: iconst_3 304 | 10: invokestatic #12 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; 305 | 13: invokevirtual #16 // Method java/util/ArrayList.add:(Ljava/lang/Object;)Z 306 | 16: pop //Adding the first number to the list 307 | 17: aload_1 308 | 18: iconst_4 309 | 19: invokestatic #12 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; 310 | 22: invokevirtual #16 // Method java/util/ArrayList.add:(Ljava/lang/Object;)Z 311 | 25: pop //Adding the second number to the list 312 | 26: getstatic #22 // Field java/lang/System.out:Ljava/io/PrintStream; 313 | 29: aload_1 314 | 30: iconst_0 315 | 31: invokevirtual #26 // Method java/util/ArrayList.get:(I)Ljava/lang/Object; 316 | 34: checkcast #8 // class java/lang/Integer 317 | 37: invokevirtual #32 // Method java/lang/Number.intValue:()I 318 | //Getting the first number 319 | 40: aload_1 320 | 41: iconst_1 321 | 42: invokevirtual #26 // Method java/util/ArrayList.get:(I)Ljava/lang/Object; 322 | 45: checkcast #8 // class java/lang/Integer 323 | 48: invokevirtual #32 // Method java/lang/Number.intValue:()I 324 | //Getting the second number 325 | 51: iadd //Adding the numbers 326 | 52: invokevirtual #38 // Method java/io/PrintStream.println:(I)V 327 | //Printing 328 | 55: return 329 | } 330 | 331 | Here's a version of genercs.sjava in Java: 332 | 333 | public class Main { 334 | public static void main(String[] args) 335 | { 336 | java.util.ArrayList nums = new java.util.ArrayList(); 337 | nums.add(3); 338 | nums.add(4); 339 | System.out.println(nums.get(0) + nums.get(1)); 340 | } 341 | } 342 | 343 | The bytecode which the Java compiler outputs for that Java code is actually identical to the bytecode which the sJava compiler outputs for generics.sjava :) 344 | 345 | Now that you've read all about this language I'm sure that you can't wait to write all your code in sJava ;) 346 | 347 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | jcenter() 4 | } 5 | 6 | dependencies { 7 | classpath "com.stehno.vanilla:vanilla-core:0.4.0" 8 | } 9 | } 10 | 11 | ext.JARS = fileTree(dir: "lib", include: ["*.jar"]) 12 | 13 | def same(a, b) { 14 | def diffs = new com.stehno.vanilla.io.DirectoryDifferenceCollector().scan(a, b) 15 | return diffs.filesOnlyInA.isEmpty() && diffs.filesOnlyInB.isEmpty() && diffs.modifiedFiles.isEmpty() 16 | } 17 | 18 | class SJavaCompile extends AbstractCompile { 19 | String targetCompatibility = "1.8" 20 | String sourceCompatibility = "1.8" 21 | @InputFiles 22 | def compilerClasspath = project.files("bin/main") + project.ext.JARS 23 | @OutputDirectory 24 | File destinationDir 25 | @InputFiles 26 | FileCollection classpath = project.files() 27 | @TaskAction 28 | void compile() { 29 | SJavaCompile.compile(project, classpath, source, destinationDir, compilerClasspath) 30 | } 31 | static def compile(project, classpath_, source, destinationDir, compilerClasspath) { 32 | def classpath__ = compilerClasspath + classpath_ 33 | project.javaexec { 34 | classpath = classpath__ 35 | main = "sjava.compiler.Main" 36 | args = ["build"] + source + ["-d", destinationDir] 37 | } 38 | } 39 | } 40 | 41 | def STD_MACROS = files("std/macros.sjava").collect { it.getCanonicalPath() } 42 | def STD_LIB = files("std/FunctionN.sjava", "std/TupleN.sjava").collect { it.getCanonicalPath() } 43 | 44 | task compiler(type: SJavaCompile) { 45 | doFirst { file("bin/main").deleteDir() } 46 | inputs.files(STD_MACROS) 47 | source = fileTree("compiler") + STD_LIB 48 | compilerClasspath = files("sjava.jar") + project.ext.JARS 49 | destinationDir = file("bin/main") 50 | } 51 | 52 | task compilerJar(type: Zip, dependsOn: [compiler]) { 53 | archiveName = "${projectDir}/sjava.jar" 54 | from(file("MANIFEST.MF"), { into("META-INF") }) 55 | from(fileTree("bin/main/sjava/compiler"), { into("sjava/compiler") }) 56 | from(fileTree("bin/main/sjava/std"), { into("sjava/std") }) 57 | } 58 | 59 | task compiler2(type: SJavaCompile, dependsOn: [compiler]) { 60 | doFirst { file("bin/compiler2").deleteDir() } 61 | inputs.files(STD_MACROS) 62 | source = fileTree("compiler") + STD_LIB 63 | destinationDir = file("bin/compiler2") 64 | } 65 | 66 | task compiler3(type: SJavaCompile, dependsOn: [compiler]) { 67 | doFirst { file("bin/compiler3").deleteDir() } 68 | inputs.files(STD_MACROS) 69 | source = fileTree("compiler") + STD_LIB 70 | destinationDir = file("bin/compiler3") 71 | } 72 | 73 | task diff(dependsOn: [compiler2, compiler3]) { 74 | doLast { 75 | def good = same(file("bin/compiler2"), file("bin/compiler3")) 76 | println("Result: " + (good ? "identical" : "different")) 77 | if (!good) throw new Exception() 78 | } 79 | } 80 | 81 | task java_sources(type: JavaExec, dependsOn: [compiler]) { 82 | doFirst { 83 | file("generated-java").deleteDir() 84 | file("generated-java/sjava/compiler").mkdirs() 85 | file("generated-java/sjava/sjava").mkdirs() 86 | } 87 | main = "-jar" 88 | args = [ 89 | file("fernflower.jar"), 90 | "-nls=1", 91 | "-ind= ", 92 | "-dgs=1", 93 | file("bin/main/"), 94 | file("generated-java/") 95 | ] 96 | } 97 | 98 | task java_compile(type: JavaCompile, dependsOn: [diff]) { 99 | outputs.upToDateWhen { false } 100 | source = fileTree(dir: "generated-java", include: "**/*.java") 101 | destinationDir = file("generated-java") 102 | classpath = JARS 103 | sourceCompatibility = "1.8" 104 | targetCompatibility = "1.8" 105 | doLast { 106 | file("bin/compilerJava").deleteDir() 107 | SJavaCompile.compile( 108 | project, 109 | files(), 110 | fileTree("compiler") + STD_LIB, 111 | file("bin/compilerJava"), 112 | files("generated-java") + project.ext.JARS 113 | ) 114 | def works = same(file("bin/compiler2"), file("bin/compilerJava")) 115 | println("java version works: " + works) 116 | if (!works) throw new Exception() 117 | } 118 | } 119 | 120 | def buildTasks = [] 121 | 122 | file("examples").listFiles().each { f -> 123 | if(f.name.endsWith(".sjava")) { 124 | def root = f.name.substring(0, f.name.indexOf(".")) 125 | buildTasks += task "build_${root}"(type: SJavaCompile, dependsOn: [compiler]) { 126 | source = f 127 | destinationDir = file("bin") 128 | } 129 | task "run_${root}"(type: JavaExec, dependsOn: ["build_${root}"]) { 130 | main = "examples.${root}.Main" 131 | classpath = JARS + files("bin", "bin/main") 132 | } 133 | } else if (f.isDirectory()) { 134 | def root = f.name 135 | buildTasks += task "build_${root}"(type: SJavaCompile, dependsOn: [compiler]) { 136 | source = fileTree(f) 137 | destinationDir = file("bin") 138 | } 139 | task "run_${root}"(type: JavaExec, dependsOn: ["build_${root}"]) { 140 | main = "examples.${root}.Main" 141 | classpath = JARS + files("bin", "bin/main") 142 | } 143 | } 144 | } 145 | 146 | task tester(type: JavaExec, dependsOn: buildTasks) { 147 | main = "sjava.compiler.Tester" 148 | classpath = JARS + files("bin/main") + files("bin") 149 | } 150 | -------------------------------------------------------------------------------- /compiler/avars.sjava: -------------------------------------------------------------------------------- 1 | (package sjava.compiler) 2 | 3 | (import sjava.compiler.handlers.*) 4 | 5 | (import gnu.bytecode.*) 6 | 7 | (define-class AVar () public 8 | (type Type public) 9 | (( type Type) void 10 | (super:) 11 | (set this:type type) 12 | ) 13 | ((load code CodeAttr) Type public this:type) 14 | ((store code CodeAttr) void public ()) 15 | ) 16 | 17 | (define-class CastVar (AVar) public 18 | (v AVar public) 19 | (( v AVar t Type) void public 20 | (super: t) 21 | (set this:v v) 22 | ) 23 | ((load code CodeAttr) Type public 24 | (GenHandler:castMaybe code (this:v:load code) this:type) 25 | ) 26 | ((store code CodeAttr) void public 27 | (this:v:store code) 28 | ) 29 | ) 30 | 31 | (define-class Var (AVar) public 32 | (var Variable) 33 | (( var Variable type Type) void public 34 | (super: type) 35 | (set this:var var) 36 | ) 37 | ((load code CodeAttr) Type public 38 | (define output (!= code null)) 39 | (if output (code:emitLoad this:var)) 40 | this:type 41 | ) 42 | ((store code CodeAttr) void public 43 | (define output (!= code null)) 44 | (if output (code:emitStore this:var)) 45 | ) 46 | ) 47 | 48 | (define-class Arg (AVar) public 49 | (n int public) 50 | (level int public) 51 | (( type Type n int level int) void public 52 | (super: type) 53 | (set this:n n) 54 | (set this:level level) 55 | ) 56 | ((load code CodeAttr) Type public 57 | (define output (!= code null)) 58 | (if output (code:emitLoad (code:getArg this:n))) 59 | this:type 60 | ) 61 | ((store code CodeAttr) void public 62 | (define output (!= code null)) 63 | (if output (code:emitStore (code:getArg this:n))) 64 | ) 65 | ) 66 | 67 | (define-class VCaptured (AVar) public 68 | (field Field public) 69 | (avar AVar public) 70 | (( avar AVar field Field) void public 71 | (super: avar:type) 72 | (set this:avar avar) 73 | (set this:field field) 74 | ) 75 | ((load code CodeAttr) Type public 76 | (define output (!= code null)) 77 | (if output (code:emitPushThis)) 78 | (if output (code:emitGetField this:field)) 79 | this:type 80 | ) 81 | ((store code CodeAttr) void public 82 | (throw (RuntimeException)) 83 | ) 84 | ) 85 | -------------------------------------------------------------------------------- /compiler/commands.sjava: -------------------------------------------------------------------------------- 1 | (package sjava.compiler.commands) 2 | 3 | (import sjava.compiler.*) 4 | 5 | (import java.util.*) 6 | (import gnu.bytecode.*) 7 | (import java.io.*) 8 | (import org.apache.commons.cli.*) 9 | 10 | (define-class Command () public abstract 11 | (parser DefaultParser public) 12 | (options Options public) 13 | (() void 14 | (super:) 15 | (set this:parser (DefaultParser)) 16 | (set this:options (Options)) 17 | (this:options:addOption (chain (Option:builder "h") (longOpt "help") (build))) 18 | ) 19 | ((name) String public abstract) 20 | ((helpHeader) String "") 21 | ((helpFooter) String "") 22 | ((helpArgs) String abstract) 23 | ((printHelp) void public 24 | ((HelpFormatter):printHelp (concat "sjava " (this:name) " " (this:helpArgs)) (this:helpHeader) this:options (this:helpFooter)) 25 | ) 26 | ((parse args String[]) CommandLine public 27 | (try 28 | (this:parser:parse this:options args) 29 | (e ParseException (throw (RuntimeException e))) 30 | ) 31 | ) 32 | ((run commandLine CommandLine args List{String}) void public abstract) 33 | ) 34 | 35 | (define-class BuildCommand (Command) public 36 | (() void public 37 | (super:) 38 | (this:options:addOption (chain (Option:builder "d") (hasArg) (desc "Output directory for classfiles") (build))) 39 | ) 40 | ((name) String public "build") 41 | ((helpArgs) String "[options] [files]") 42 | ((run commandLine CommandLine args List{String}) void public 43 | (define fileNames args) 44 | (if (= (fileNames:size) 0) 45 | (this:printHelp) 46 | (begin 47 | (define dir (if (commandLine:hasOption "d") (commandLine:getOptionValue "d") ".")) 48 | 49 | (define files 50 | (Arrays:asList 51 | (mapA path fileNames 52 | (File path) 53 | ) 54 | ) 55 | ) 56 | (Main:compile files dir) 57 | ) 58 | ) 59 | ) 60 | ) 61 | 62 | (define-class RunCommand (Command) public 63 | (() void public 64 | (super:) 65 | ) 66 | ((name) String public "run") 67 | ((helpArgs) String " [files]") 68 | ((run commandLine CommandLine args List{String}) void public 69 | (if (< (args:size) 2) 70 | (this:printHelp) 71 | (try 72 | (begin 73 | (define fileNames (args:subList 1 (args:size))) 74 | 75 | (define files 76 | (Arrays:asList 77 | (mapA path fileNames 78 | (File path) 79 | ) 80 | ) 81 | ) 82 | (define fileScopes (Main:compile files)) 83 | (define cl (Main:getClassLoader)) 84 | (define found ClassInfo null) 85 | (forEach fs fileScopes 86 | (forEach ci fs:newClasses 87 | (if ((ci:c:getName):equals (args:get 0)) 88 | (set found ci) 89 | ) 90 | (ci:addToClassLoader cl) 91 | ) 92 | ) 93 | (if (= found null) 94 | (println (args:get 0) " not found") 95 | (((found:getClazz cl):getMethod "main" (class String[])):invoke null null) 96 | ) 97 | ) 98 | (e Throwable (e:printStackTrace)) 99 | ) 100 | ) 101 | ) 102 | ) 103 | 104 | (define-class FormatCommand (Command) public 105 | (() void public 106 | (super:) 107 | ) 108 | ((name) String public "fmt") 109 | ((helpArgs) String "[files]") 110 | ((run commandLine CommandLine args List{String}) void public 111 | (define fileNames args) 112 | (if (= (fileNames:size) 0) 113 | (this:printHelp) 114 | (try 115 | (begin 116 | (forEach name fileNames 117 | (define f (File name)) 118 | (define in (org.apache.commons.io.FileUtils:readFileToString f)) 119 | (define out (sjava.compiler.Formatter:formatCode in)) 120 | (if (! (in:equals out)) 121 | (begin 122 | (println "Overwriting " name) 123 | (org.apache.commons.io.FileUtils:writeStringToFile f out) 124 | ) 125 | ) 126 | ) 127 | ) 128 | (e Throwable (e:printStackTrace)) 129 | ) 130 | ) 131 | ) 132 | ) 133 | -------------------------------------------------------------------------------- /compiler/emitters.sjava: -------------------------------------------------------------------------------- 1 | (package sjava.compiler.emitters) 2 | 3 | (import sjava.compiler.*) 4 | (import sjava.compiler.handlers.*) 5 | 6 | (import java.util.*) 7 | (import gnu.bytecode.*) 8 | 9 | (define-class Emitter () public abstract 10 | (() void public 11 | (super:) 12 | ) 13 | ((emit h GenHandler code CodeAttr needed Type) Type public abstract) 14 | ((emitAll emitters List{Emitter} h GenHandler code CodeAttr needed Object) Type[] public static 15 | (define types (Type[] len:(emitters:size))) 16 | (forEach (emitter i) emitters 17 | (if (!= emitter null) 18 | (begin 19 | (aset types i 20 | (emitter:emit h code 21 | (if (instance? needed Type[]) 22 | (aget (as Type[] needed) i) 23 | (as Type needed) 24 | ) 25 | ) 26 | ) 27 | ) 28 | ) 29 | ) 30 | types 31 | ) 32 | ) 33 | 34 | (define-class Goto (Emitter) public 35 | (label Label public) 36 | (( label Label) void public 37 | (super:) 38 | (set this:label label) 39 | ) 40 | ((emit h GenHandler code CodeAttr needed Type) Type public 41 | (define output (!= code null)) 42 | (if (&& output (code:reachableHere)) (code:emitGoto this:label)) 43 | Type:voidType 44 | ) 45 | ) 46 | 47 | (define-class Null (Emitter) 48 | (() void (super:)) 49 | ((emit h GenHandler code CodeAttr needed Type) Type public 50 | (if (!= code null) (code:emitPushNull)) 51 | Type:nullType 52 | ) 53 | ) 54 | 55 | (define-class LoadAVar (Emitter) public 56 | (avar AVar) 57 | (( avar AVar) void public 58 | (super:) 59 | (set this:avar avar) 60 | ) 61 | ((emit h GenHandler code CodeAttr needed Type) Type public 62 | (this:avar:load code) 63 | ) 64 | ) 65 | 66 | ;(define-class Emitters (Emitter) public 67 | ; (emitters List{Emitter} public) 68 | ; (( emitters Emitter[]) void public (super:) (set this:emitters (Arrays:asList emitters))) 69 | ; (( emitters List) void public (super:) (set this:emitters emitters)) 70 | ; ((emit h GenHandler code CodeAttr needed Type) Type[] public 71 | ; (Emitter:emitAll this:emitters h code needed) 72 | ; ) 73 | ;) 74 | 75 | ;(define-class Add1 (Emitter) public 76 | ; (e Emitter) 77 | ; (( e Emitter) void public 78 | ; (super:) 79 | ; (set this:e e) 80 | ; ) 81 | ; ((emit h GenHandler code CodeAttr needed Type) Type public 82 | ; (define output (!= code null)) 83 | ; (this:e:emit h code Type:intType) 84 | ; (if output (code:emitPushInt 1)) 85 | ; (if output (code:emitAdd Type:intType)) 86 | ; Type:intType 87 | ; ) 88 | ;) 89 | 90 | (define-class Nothing (Emitter) public 91 | (inst Nothing static public) 92 | (() void static 93 | (set Nothing:inst (Nothing)) 94 | ) 95 | (() void private 96 | (super:) 97 | ) 98 | ((emit h GenHandler code CodeAttr needed Type) Type public 99 | Type:voidType 100 | ) 101 | ) 102 | -------------------------------------------------------------------------------- /compiler/mfilters.sjava: -------------------------------------------------------------------------------- 1 | (package sjava.compiler.mfilters) 2 | 3 | (import sjava.compiler.*) 4 | 5 | (import java.util.*) 6 | (import gnu.bytecode.*) 7 | 8 | (define-class MethodCall () public 9 | (m Method public) 10 | (t Type public) 11 | (tvs Map{TypeVariable Type} public) 12 | (types Type[] public) 13 | (( m Method t Type tvs Map{TypeVariable Type} types Type[]) void 14 | (super:) 15 | (set this:m m) 16 | (set this:t t) 17 | (set this:tvs tvs) 18 | (set this:types types) 19 | ) 20 | ((moreSpecific o MethodCall) bool 21 | (define as (this:m:getGenericParameterTypes)) 22 | (define bs (o:m:getGenericParameterTypes)) 23 | (define n (Math:min (alen as) (alen bs))) 24 | (define good false) 25 | (for ((i 0)) (< i n) (inc i) 26 | (define a (Main:resolveType this:tvs this:t (aget as i))) 27 | (define b (Main:resolveType o:tvs o:t (aget bs i))) 28 | (define comp (Main:compare b a)) 29 | (if (= comp 1) 30 | (set good true) 31 | (if (< comp 0) 32 | (return false) 33 | ) 34 | ) 35 | ) 36 | (if (&& (! good) (< (alen bs) (alen as))) 37 | false 38 | true 39 | ) 40 | ) 41 | ((mostSpecific methods List{MethodCall}) bool 42 | (forEach method methods 43 | (if (! (this:moreSpecific method)) 44 | (return false) 45 | ) 46 | ) 47 | true 48 | ) 49 | ((toString) String public 50 | (this:m:toString) 51 | ) 52 | ) 53 | 54 | (define-class AFilter () public abstract 55 | (pt Type) 56 | (foundSigs HashSet{String}) 57 | (( pt Type) void 58 | (super:) 59 | (set this:pt pt) 60 | (set this:foundSigs (HashSet)) 61 | ) 62 | ((select method Method generic Type) void abstract) 63 | ((search t Type) void 64 | (define m ((as ClassType (t:getRawType)):getDeclaredMethods)) 65 | (while (!= m null) 66 | (define msig (concat (m:getName) (m:getSignature))) 67 | (if (! (this:foundSigs:contains msig)) 68 | (begin 69 | (this:foundSigs:add msig) 70 | (this:select m t) 71 | ) 72 | ) 73 | (set m (m:getNext)) 74 | ) 75 | ) 76 | ((searchAll) void public 77 | (if (instance? this:pt ArrayType) 78 | (this:searchArray) 79 | (forEach t (Main:superTypes this:pt) 80 | (this:search t) 81 | ) 82 | ) 83 | ) 84 | ((searchDeclared) void public 85 | (this:search this:pt) 86 | ) 87 | ((searchArray) void 88 | (this:search Type:objectType) 89 | ) 90 | ) 91 | 92 | (define-class BridgeFilter (AFilter) public 93 | (m Method) 94 | (( m Method) void public 95 | (super: (m:getDeclaringClass)) 96 | (set this:m m) 97 | ) 98 | ((select method Method generic Type) void 99 | (define p1 (this:m:getGenericParameterTypes)) 100 | (define p2 (method:getGenericParameterTypes)) 101 | (define r1 (this:m:getReturnType)) 102 | (define r2 (method:getReturnType)) 103 | (if 104 | (&& 105 | ((method:getName):equals (this:m:getName)) 106 | (= (alen p1) (alen p2)) 107 | (! (Type:isSame generic this:pt)) 108 | ) 109 | (begin 110 | (define n (alen p1)) 111 | (define diff (! (Type:isSame (r1:getRawType) (r2:getRawType)))) 112 | (define overrides true) 113 | (for ((i 0)) (&& overrides (!= i n)) (inc i) 114 | (if 115 | (&& 116 | (! diff) 117 | (! (Type:isSame ((aget p1 i):getRawType) ((aget p2 i):getRawType))) 118 | ) 119 | (set diff true) 120 | ) 121 | (set overrides (Type:isSame (Main:resolveType generic (aget p1 i)) (Main:resolveType generic (aget p2 i)))) 122 | ) 123 | (if (&& diff overrides) 124 | (Main:generateBridgeMethod this:m p2 r2) 125 | ) 126 | ) 127 | ) 128 | ) 129 | ) 130 | 131 | (define-class MFilter (AFilter) public 132 | (methods ArrayList{MethodCall}) 133 | (name String) 134 | (types Type[]) 135 | (static_ bool) 136 | (( name String types Type[] pt Type static_ bool) void public 137 | (super: pt) 138 | (set this:methods (ArrayList)) 139 | (set this:name name) 140 | (set this:types types) 141 | (set this:static_ static_) 142 | ) 143 | ((select method Method generic Type) void 144 | (define c (method:getDeclaringClass)) 145 | (if 146 | (&& 147 | ((method:getName):equals this:name) 148 | (= (method:getStaticFlag) this:static_) 149 | (|| 150 | (! (c:isInterface)) 151 | ((as ClassType (generic:getRawType)):isInterface) 152 | (! (method:isAbstract)) 153 | ) 154 | (= 0 (& (method:getModifiers) Access:SYNTHETIC)) 155 | ) 156 | (begin 157 | (define mc (MFilter:isCompatible method generic this:types)) 158 | (if (!= mc null) 159 | (this:methods:add mc) 160 | ) 161 | ) 162 | ) 163 | ) 164 | ((getMethodCall) MethodCall public 165 | (forEach method this:methods 166 | (if (method:mostSpecific this:methods) 167 | (return method) 168 | ) 169 | ) 170 | null 171 | ) 172 | ((getMethod) Method public 173 | (define mc (this:getMethodCall)) 174 | (if (= mc null) 175 | null 176 | mc:m 177 | ) 178 | ) 179 | ((isCompatible method Method generic Type types Type[]) MethodCall public static 180 | (define varargs (!= (& (method:getModifiers) Access:TRANSIENT) 0)) 181 | (define na (alen types)) 182 | (define params (method:getGenericParameterTypes)) 183 | (define np (alen params)) 184 | (if (|| (= na np) (&& varargs (>= na (- np 1)))) 185 | (begin 186 | (define arrayNeeded 187 | (&& 188 | varargs 189 | (|| 190 | (= na (- np 1)) 191 | (!= (Main:arrayDim (aget params (- np 1))) (Main:arrayDim (aget types (- np 1)))) 192 | ) 193 | ) 194 | ) 195 | (define reals 196 | (if arrayNeeded 197 | (begin 198 | (define ntypes (Type[] len:np)) 199 | (define default (= na (- np 1))) 200 | (System:arraycopy types 0 ntypes 0 (- np 1)) 201 | (aset ntypes (- np 1) 202 | (if default 203 | (aget params (- np 1)) 204 | (ArrayType (aget types (- np 1))) ;can be more specific 205 | ) 206 | ) 207 | ntypes 208 | ) 209 | types 210 | ) 211 | ) 212 | (define tparams 213 | (if ((method:getName):equals "") 214 | (begin 215 | (define ctparams ((as ClassType (generic:getRawType)):getTypeParameters)) 216 | (define mtparams (method:getTypeParameters)) 217 | (cond 218 | ((= ctparams null) 219 | mtparams 220 | ) 221 | ((= mtparams null) 222 | ctparams 223 | ) 224 | (true 225 | (define o (TypeVariable[] len:(+ (alen ctparams) (alen mtparams)))) 226 | (System:arraycopy ctparams 0 o 0 (alen ctparams)) 227 | (System:arraycopy mtparams 0 o (alen ctparams) (alen mtparams)) 228 | o 229 | ) 230 | ) 231 | ) 232 | (method:getTypeParameters) 233 | ) 234 | ) 235 | (define tvs (Main:unresolveTvs tparams params reals)) 236 | (define stop false) 237 | (for ((i 0)) (! (|| stop (= i (alen types)))) (inc i) 238 | (define at 239 | (Main:resolveType tvs generic 240 | (if 241 | (&& 242 | arrayNeeded 243 | (>= i (- np 1)) 244 | ) 245 | (as ArrayType (aget params (- np 1))):elements 246 | (aget params i) 247 | ) 248 | ) 249 | ) 250 | (define level (Main:compare at (aget types i))) 251 | (if (|| (< level 0) (&& (= (aget types i) Type:nullType) (instance? at PrimType))) 252 | (set stop true) 253 | ) 254 | ) 255 | (if (! stop) 256 | (MethodCall method generic tvs types) 257 | null 258 | ) 259 | ) 260 | null 261 | ) 262 | ) 263 | ) 264 | -------------------------------------------------------------------------------- /examples/doubledispatch.expected.txt: -------------------------------------------------------------------------------- 1 | Visitor1 received a String: a 2 | Visitor1 received a String: b 3 | Visitor1 received an Integer: 1 4 | Visitor1 received an Integer: 2 5 | 6 | Visitor2 received a String: a 7 | Visitor2 received a String: b 8 | Visitor2 received an Integer: 1 9 | Visitor2 received an Integer: 2 10 | -------------------------------------------------------------------------------- /examples/doubledispatch.sjava: -------------------------------------------------------------------------------- 1 | (package examples.doubledispatch) 2 | 3 | (define-class Main () public 4 | ((main args String[]) void public static 5 | (define objects (Object[] "a" "b" 1 2)) 6 | 7 | (define v1 (Visitor1)) 8 | (forEach o objects 9 | (v1:visit o) 10 | ) 11 | 12 | (println) 13 | 14 | (define v2 (Visitor2)) 15 | (forEach o objects 16 | (v2:visit o) 17 | ) 18 | ) 19 | ) 20 | 21 | (define-class Visitor () abstract 22 | (() void 23 | (super:) 24 | ) 25 | ((visit s String) void abstract) 26 | ((visit n Integer) void abstract) 27 | ((visit o Object) void 28 | (doubleDispatch (this:visit _) o) 29 | ) 30 | ) 31 | 32 | (define-class Visitor1 (Visitor) 33 | (() void 34 | (super:) 35 | ) 36 | ((visit s String) void 37 | (println "Visitor1 received a String: " s) 38 | ) 39 | ((visit n Integer) void 40 | (println "Visitor1 received an Integer: " n) 41 | ) 42 | ) 43 | 44 | (define-class Visitor2 (Visitor) 45 | (() void 46 | (super:) 47 | ) 48 | ((visit s String) void 49 | (println "Visitor2 received a String: " s) 50 | ) 51 | ((visit n Integer) void 52 | (println "Visitor2 received an Integer: " n) 53 | ) 54 | ) 55 | -------------------------------------------------------------------------------- /examples/formatterTest.expected.txt: -------------------------------------------------------------------------------- 1 | (include 2 | `((abc) 3 | a 4 | ) 5 | ((abc """a""")) 6 | `() 7 | ) 8 | (if 9 | (|| 10 | (|| 11 | false 12 | ) 13 | false 14 | ) 15 | true 16 | ) 17 | --- 18 | ( 19 | (abc 20 | def 21 | ):ghi 22 | 456 789 23 | ) 24 | --- 25 | -------------------------------------------------------------------------------- /examples/formatterTest.sjava: -------------------------------------------------------------------------------- 1 | (package examples.formatterTest) 2 | 3 | (define-class Main () public 4 | ((main args String[]) void public static 5 | (static:printFormatted 6 | """ 7 | 8 | (include 9 | `( 10 | ( 11 | abc 12 | ) 13 | a 14 | )( (abc\"""a\""" 15 | ) ) 16 | `() 17 | )(if ( 18 | 19 | || (|| 20 | false 21 | ) 22 | false) 23 | true 24 | )""" 25 | ) 26 | (Main:printFormatted 27 | """ 28 | (( 29 | abc 30 | def 31 | ):ghi 456 789) 32 | 33 | """ 34 | ) 35 | ) 36 | ((printFormatted code String) void static 37 | (println (sjava.compiler.Formatter:formatCode code) "---") 38 | ) 39 | ) 40 | -------------------------------------------------------------------------------- /examples/generics.expected.txt: -------------------------------------------------------------------------------- 1 | 7 2 | -------------------------------------------------------------------------------- /examples/generics.sjava: -------------------------------------------------------------------------------- 1 | (package examples.generics) 2 | 3 | (import java.util.*) 4 | (define-class Main () public 5 | ((main args String[]) void public static 6 | (define al (ArrayList{Integer})) ;constructor 7 | (al:add 3) 8 | (al:add 4) 9 | (System:out:println (+ (al:get 0) (al:get 1))) ;prints 7 10 | ) 11 | ) 12 | -------------------------------------------------------------------------------- /examples/helloworld.sjava: -------------------------------------------------------------------------------- 1 | (package examples.helloworld) 2 | 3 | (define-class Main () public 4 | ((main args String[]) void public static 5 | (System:out:println "Hello world") 6 | ) 7 | ) 8 | -------------------------------------------------------------------------------- /examples/intf.expected.txt: -------------------------------------------------------------------------------- 1 | ClassType examples.intf.A 2 | ClassType java.lang.Object 3 | ClassType java.lang.CharSequence 4 | -------------------------------------------------------------------------------- /examples/intf.sjava: -------------------------------------------------------------------------------- 1 | (package examples.intf) 2 | 3 | (define-class A () interface) 4 | 5 | (define-class B () interface) 6 | 7 | (define-class K (A) interface) 8 | 9 | (define-class L (A) interface) 10 | 11 | (define-class M (A B) interface) 12 | 13 | (define-class N (A B) interface) 14 | 15 | (define-class O (N) interface) 16 | 17 | (define-class Main () public 18 | ((main args String[]) void public static 19 | (println 20 | (include 21 | `,(concat 22 | (type 23 | `(begin 24 | (define k K) 25 | (define l L) 26 | (if true k l) 27 | ) 28 | ) 29 | "\n" 30 | (type 31 | `(begin 32 | (define m M) 33 | (define o O) 34 | (if true m o) 35 | ) 36 | ) 37 | "\n" 38 | (type 39 | `(begin 40 | (if true (as CharSequence "") "") 41 | ) 42 | ) 43 | ) 44 | ) 45 | ) 46 | ) 47 | ) 48 | -------------------------------------------------------------------------------- /examples/lol.expected.txt: -------------------------------------------------------------------------------- 1 | 3 2 | 3 3 | 315 4 | 3 5 | -------------------------------------------------------------------------------- /examples/lol.sjava: -------------------------------------------------------------------------------- 1 | (package examples.lol) 2 | 3 | (define-class Main () public 4 | ((main args String[]) void public static 5 | (define x 3) 6 | ( 7 | (lambda () 8 | (begin 9 | (println x) 10 | (println x) 11 | ) 12 | ( 13 | (lambda () 14 | (print x) 15 | (println ((aget ((Thread:currentThread):getStackTrace) 1):getLineNumber)) 16 | (println x) 17 | ) 18 | ) 19 | ) 20 | ) 21 | ) 22 | ) 23 | -------------------------------------------------------------------------------- /examples/macro.sjava: -------------------------------------------------------------------------------- 1 | (package examples.macro) 2 | 3 | (define-macro (getTimestamp f) 4 | `,((java.text.SimpleDateFormat (as sjava.compiler.tokens.SToken f):val):format (java.util.Date)) 5 | ) 6 | (define-macro (timestwo expr) 7 | `(begin 8 | (define x 0) 9 | (set x 2) 10 | (* ,expr x) 11 | ) 12 | ) 13 | (define-macro (rand n) 14 | `(Integer:toString ((java.util.Random):nextInt ,n)) 15 | ) 16 | 17 | (define-class Main () public 18 | ((main args String[]) void public static 19 | (define i -1) 20 | (repeat 2 (println i)) 21 | 22 | (println "Compiled at " (getTimestamp "HH:mm:ss MM/dd/yyyy")) 23 | (println 24 | "Compile time dice roll result: " 25 | (include 26 | ;inline macro 27 | (begin 28 | (System:out:println "Compile time") 29 | `,(+ ((java.util.Random):nextInt 6) 1) 30 | ) 31 | ) 32 | ) 33 | (println ("Runtime random number up to 1000: ":concat (rand 1000))) 34 | 35 | (define x 3) 36 | (inc x) 37 | (println (timestwo x)) 38 | ) 39 | ) 40 | -------------------------------------------------------------------------------- /examples/scope.expected.txt: -------------------------------------------------------------------------------- 1 | 0 2 | 1 3 | 2 4 | 3 5 | 4 6 | 0 7 | 1 8 | 2 9 | 3 10 | 4 11 | -------------------------------------------------------------------------------- /examples/scope.sjava: -------------------------------------------------------------------------------- 1 | (package examples.scope) 2 | 3 | (define-class Main () public 4 | ((main args String[]) void public static 5 | (define i 0) 6 | (label a) 7 | (if (= i 2) 8 | (goto end) 9 | ) 10 | (begin 11 | (define i 0) 12 | (label a) 13 | (if (!= i 5) 14 | (begin 15 | (System:out:println i) 16 | (set i (+ i 1)) 17 | (goto a) 18 | ) 19 | ) 20 | ) 21 | (inc i) 22 | (goto a) 23 | (label end) 24 | ) 25 | ) 26 | -------------------------------------------------------------------------------- /examples/test.expected.txt: -------------------------------------------------------------------------------- 1 | ABCa 2 | ABC 3 | DEF 4 | ABC 5 | DEF 6 | 0:ABC 7 | 1:DEF 8 | true 9 | 15 10 | 3 == 3 11 | AA 12 | 3 == 3 13 | AA 14 | 3 15 | 2 16 | 2 17 | 2 18 | -1 19 | 6 20 | [9, 8, 9] 21 | [1, 2, 3] 22 | 3 23 | [1, 0, -1] 24 | [1, 0, 2] 25 | (1, 2) 26 | true 27 | 3 28 | abc 29 | 5:wow 30 | 5:wow 31 | 5:wow 32 | [3, l, m, n, 7] 33 | [99, 0, 0] 34 | [[0, 0], [0, 0], [0, 0]] 35 | true 36 | 6 37 | 6 38 | -------------------------------------------------------------------------------- /examples/test.sjava: -------------------------------------------------------------------------------- 1 | (package examples.test) 2 | 3 | (import java.util.*) 4 | (import java.util.stream.*) 5 | (import java.util.function.*) 6 | (import java.nio.file.*) 7 | (import gnu.bytecode.*) 8 | (import java.io.*) 9 | 10 | (define-class AlString (ArrayList{String}) 11 | (() void 12 | (super:) 13 | ) 14 | ) 15 | 16 | (define-class Ref{E} () 17 | (val E) 18 | ;(( a int val E c String) void 19 | ; (super:) 20 | ; (set this:val val) 21 | ;) 22 | (ctor! (a int 'val c String) 23 | (super:) 24 | ) 25 | ;((getVal) E 26 | ; this:val 27 | ;) 28 | (get! val) 29 | ;((setVal val E) void 30 | ; (set this:val val) 31 | ;) 32 | (set! val) 33 | ) 34 | 35 | (define-class Main () public 36 | (l AlString static) 37 | ((main args String[]) void public static 38 | (set static:l (AlString)) 39 | (static:l:add "ABC") 40 | (static:l:add "DEF") 41 | (System:out:println (((static:l:iterator):next):concat "a")) 42 | (forEach s static:l (System:out:println s)) 43 | (forEach s (static:l:toArray) (System:out:println s)) 44 | (forEach (s i) static:l (println i ":" s)) 45 | 46 | (define n (Ref{Integer} 0 4000 "")) 47 | (define i (Integer 4000)) 48 | (System:out:println (= i (n:getVal))) 49 | (n:setVal 5) 50 | (System:out:println (* 3 (n:getVal))) 51 | 52 | (define x 1) 53 | (inc x 5) 54 | (inc x) 55 | (dec x 4) 56 | 57 | (define runnable 58 | (object (Runnable) 59 | ((run) void public 60 | (System:out:println (concat x " == " 3)) 61 | (System:out:println "AA") 62 | ) 63 | ) 64 | ) 65 | (runnable) 66 | (runnable:run) 67 | 68 | (define add 69 | (lambda BinOp (c d) 70 | (+ c d) 71 | ) 72 | ) 73 | (System:out:println (add 1 2)) 74 | 75 | (define mul1 76 | (lambda Function2{Integer Integer Integer} (c d) 77 | (* c d) 78 | ) 79 | ) 80 | (System:out:println (mul1 1 2)) 81 | 82 | (define mul2 83 | (object (Function2{Integer Integer Integer}) 84 | ((apply c Integer d Integer) Integer 85 | (* c d) 86 | ) 87 | ) 88 | ) 89 | (System:out:println (mul2 1 2)) 90 | 91 | (define mul3 92 | (lambda (c Integer d Integer) 93 | (* c d) 94 | ) 95 | ) 96 | (System:out:println (mul3 1 2)) 97 | 98 | (define sub 99 | (object (BinOp) 100 | ((calc c int d int) int public 101 | (- c d) 102 | ) 103 | ) 104 | ) 105 | (System:out:println (sub 1 2)) 106 | 107 | (define list (Arrays:asList 5 9 3 8 2 9)) 108 | (System:out:println (+ (list:get 0) 1)) 109 | (define stream 110 | ((list:stream):filter 111 | (lambda Predicate{Integer} (i) 112 | (> i 5) 113 | ) 114 | ) 115 | ) 116 | (define collector (Collectors:toList)) 117 | (define filtered (stream:collect collector)) 118 | (println filtered) 119 | 120 | (define a (int[] 1 2 3)) 121 | (println a) 122 | 123 | ((lambdaWrap System:out:println Object) 3) 124 | 125 | (println (mapA x (int[] 0 1 2) (static:toggle1 x))) 126 | 127 | (println (mapA x (int[] 0 1 2) (Main:toggle2 x))) 128 | 129 | (let ((x 1) (y 2)) 130 | (println "(" x ", " y ")") 131 | ) 132 | 133 | (println (instance? "a" Object)) 134 | 135 | (println 136 | (synchronized "a" 137 | 3 138 | ) 139 | ) 140 | 141 | (include `(System:out:println "abc")) 142 | 143 | (System:out:format "%d:%s\n" (Object[] 5 "wow")) 144 | (System:out:format "%d:%s\n" 5 "wow") 145 | (System:out:format "5:wow\n") 146 | 147 | (println 148 | (with (ArrayList) 149 | (add 3) 150 | (add "k") 151 | (add 4) 152 | (add "m") 153 | (add "n") 154 | (add 7) 155 | (set 1 "l") 156 | (remove 2) 157 | ) 158 | ) 159 | 160 | (println (int[3] 99)) 161 | (println (Arrays:deepToString (int[3][2]))) 162 | 163 | (define a Object 3) 164 | (if (&& (instance? a Comparable) (instance? a Object)) 165 | (println (> (a:compareTo 2) 0)) 166 | ) 167 | (if (|| (! (instance? a Integer)) (! (instance? a Object))) 168 | (println 2) 169 | (println (* a 2)) 170 | ) 171 | (if (! (instance? a Integer)) 172 | (println 2) 173 | (println (* a 2)) 174 | ) 175 | ) 176 | ((toggle1 x int) int static 177 | (cond 178 | ((= x 0) 179 | 1 180 | ) 181 | ((= x 1) 182 | 0 183 | ) 184 | (true 185 | -1 186 | ) 187 | ) 188 | ) 189 | ((toggle2 x int) int static 190 | (cond 191 | ((= x 0) 192 | (set x 1) 193 | ) 194 | ((= x 1) 195 | (set x 0) 196 | ) 197 | ) 198 | x 199 | ) 200 | ) 201 | 202 | (define-class BinOp () public interface abstract 203 | ((calc a int b int) int public abstract) 204 | ) 205 | -------------------------------------------------------------------------------- /examples/tictactoe.sjava: -------------------------------------------------------------------------------- 1 | (package examples.tictactoe) 2 | 3 | (import java.util.*) 4 | (import javafx.application.*) 5 | (import javafx.stage.*) 6 | (import javafx.scene.*) 7 | (import javafx.scene.canvas.*) 8 | (import javafx.scene.input.*) 9 | (import javafx.scene.text.*) 10 | (import javafx.scene.paint.*) 11 | (import javafx.animation.*) 12 | (import javafx.event.*) 13 | 14 | (define-class Main () public 15 | ((main args String[]) void public static 16 | (set App:userPlayer 1) 17 | (Application:launch (class App)) 18 | ) 19 | ) 20 | 21 | (define-class App (Application) public 22 | (gc GraphicsContext static) 23 | (mouseX int static) 24 | (mouseY int static) 25 | (board int[][] static) 26 | (wh int static) 27 | (cell int static) 28 | (turn int static) 29 | (userPlayer int static) 30 | (win bool static) 31 | (turns int static) 32 | (() void public 33 | (super:) 34 | ) 35 | ((start stage Stage) void 36 | (App:reset) 37 | (set App:wh 512) 38 | (set App:cell (/ App:wh 3)) 39 | (stage:setTitle "Tic Tac Toe") 40 | (stage:setResizable false) 41 | (define root (Group)) 42 | (define canvas (Canvas App:wh App:wh)) 43 | ((root:getChildren):add canvas) 44 | (set App:gc (canvas:getGraphicsContext2D)) 45 | (define scene (Scene root)) 46 | (stage:setScene scene) 47 | (stage:sizeToScene) 48 | ( 49 | (object (AnimationTimer) 50 | ((handle currentTime long) void 51 | (App:gc:clearRect 0 0 App:wh App:wh) 52 | (App:gc:setStroke Color:BLACK) 53 | 54 | (App:gc:setLineWidth 1) 55 | (App:gc:strokeLine (+ App:cell 0.5) 0 (+ App:cell 0.5) App:wh) 56 | (App:gc:strokeLine (+ (* 2 App:cell) 0.5) 0 (+ (* 2 App:cell) 0.5) App:wh) 57 | (App:gc:strokeLine 0 (+ App:cell 0.5) App:wh (+ App:cell 0.5)) 58 | (App:gc:strokeLine 0 (+ (* 2 App:cell) 0.5) App:wh (+ (* 2 App:cell) 0.5)) 59 | 60 | (for ((x 0)) (< x 3) (inc x) 61 | (for ((y 0)) (< y 3) (inc y) 62 | (App:draw x y (aget App:board x y)) 63 | ) 64 | ) 65 | 66 | (App:gc:setStroke Color:GREENYELLOW) 67 | (if (&& (! App:win) (< App:mouseX 3) (< App:mouseY 3) (= (aget App:board App:mouseX App:mouseY) 0)) 68 | (App:draw App:mouseX App:mouseY App:turn) 69 | ) 70 | ) 71 | ):start 72 | ) 73 | (scene:setOnKeyPressed 74 | (lambda EventHandler{KeyEvent} (event) 75 | (if (= (event:getCode) KeyCode:ESCAPE) 76 | (stage:close) 77 | ) 78 | ) 79 | ) 80 | (scene:setOnMouseMoved 81 | (lambda EventHandler{MouseEvent} (event) 82 | (set App:mouseX (/ (event:getX) App:cell)) 83 | (set App:mouseY (/ (event:getY) App:cell)) 84 | ) 85 | ) 86 | (scene:setOnMouseClicked 87 | (lambda EventHandler{MouseEvent} (event) 88 | (if App:win 89 | (App:reset) 90 | (if (= (aget App:board App:mouseX App:mouseY) 0) 91 | (begin 92 | (App:play App:mouseX App:mouseY) 93 | (App:bestMove) 94 | (define n (App:check)) 95 | (if (!= n 0) 96 | (begin 97 | (println (if (= n 1) "X" "O") " won! Click to start a new game.") 98 | (set App:win true) 99 | ) 100 | ) 101 | (if (= App:turns 9) 102 | (begin 103 | (println "Tie! Click to start a new game.") 104 | (set App:win true) 105 | ) 106 | ) 107 | ) 108 | ) 109 | ) 110 | ) 111 | ) 112 | (stage:show) 113 | ) 114 | ((draw cx int cy int w int) void static 115 | (App:gc:setLineWidth 10) 116 | (define hcell (/ App:cell 2)) 117 | (define ox (+ (* cx App:cell) hcell)) 118 | (define oy (+ (* cy App:cell) hcell)) 119 | (define off (- hcell 30)) 120 | (if (= w 1) 121 | (begin 122 | (App:gc:strokeLine (- ox off) (- oy off) (+ ox off) (+ oy off)) 123 | (App:gc:strokeLine (+ ox off) (- oy off) (- ox off) (+ oy off)) 124 | ) 125 | ) 126 | (if (= w 2) 127 | (App:gc:strokeOval (- ox off) (- oy off) (* off 2) (* off 2)) 128 | ) 129 | ) 130 | ((good a int b int c int) bool static 131 | (&& (!= a 0) (= a b c)) 132 | ) 133 | ((check) int static 134 | (cond 135 | ((App:good (aget App:board 0 0) (aget App:board 0 1) (aget App:board 0 2)) 136 | (aget App:board 0 0) 137 | ) 138 | ((App:good (aget App:board 1 0) (aget App:board 1 1) (aget App:board 1 2)) 139 | (aget App:board 1 0) 140 | ) 141 | ((App:good (aget App:board 2 0) (aget App:board 2 1) (aget App:board 2 2)) 142 | (aget App:board 2 0) 143 | ) 144 | ((App:good (aget App:board 0 0) (aget App:board 1 0) (aget App:board 2 0)) 145 | (aget App:board 0 0) 146 | ) 147 | ((App:good (aget App:board 0 1) (aget App:board 1 1) (aget App:board 2 1)) 148 | (aget App:board 0 1) 149 | ) 150 | ((App:good (aget App:board 0 2) (aget App:board 1 2) (aget App:board 2 2)) 151 | (aget App:board 0 2) 152 | ) 153 | ((App:good (aget App:board 0 0) (aget App:board 1 1) (aget App:board 2 2)) 154 | (aget App:board 0 0) 155 | ) 156 | ((App:good (aget App:board 2 0) (aget App:board 1 1) (aget App:board 0 2)) 157 | (aget App:board 2 0) 158 | ) 159 | (true 0) 160 | ) 161 | ) 162 | ;returns the score of this position for player 163 | ((dfs player int depth int) int static 164 | (define n (App:check)) 165 | (cond 166 | ((= n player) ;player wins 167 | depth 168 | ) 169 | ((!= n 0) ;player loses 170 | (- depth) 171 | ) 172 | (true 173 | (define score -9999) 174 | (for ((x 0)) (< x 3) (inc x) 175 | (for ((y 0)) (< y 3) (inc y) 176 | (when (= (aget App:board x y) 0) 177 | (aset App:board x y player) 178 | (set score 179 | (Math:max 180 | score 181 | (- 182 | (static:dfs 183 | (if (= player 1) 2 1) 184 | (- depth 1) 185 | ) 186 | ) 187 | ) 188 | ) 189 | (aset App:board x y 0) 190 | ) 191 | ) 192 | ) 193 | (if (= score -9999) 0 score) 194 | ) 195 | ) 196 | ) 197 | ((bestMove) void static 198 | (define best -9999) 199 | (define bx 0) 200 | (define by 0) 201 | (for ((x 0)) (< x 3) (inc x) 202 | (for ((y 0)) (< y 3) (inc y) 203 | (if (= (aget App:board x y) 0) 204 | (begin 205 | (aset App:board x y App:turn) 206 | (define n (- (App:dfs (if (= App:turn 1) 2 1) 10))) 207 | (if (> n best) 208 | (begin 209 | (set best n) 210 | (set bx x) 211 | (set by y) 212 | ) 213 | ) 214 | (aset App:board x y 0) 215 | ) 216 | ) 217 | ) 218 | ) 219 | (if (!= App:turns 9) 220 | (App:play bx by) 221 | ) 222 | ) 223 | ((reset) void static 224 | (set App:win false) 225 | (set App:board (int[][] (int[] 0 0 0) (int[] 0 0 0) (int[] 0 0 0))) 226 | (set App:turn 1) 227 | (set App:turns 0) 228 | (if (= App:userPlayer 2) 229 | (App:bestMove) 230 | ) 231 | ) 232 | ((play x int y int) void static 233 | (aset App:board x y App:turn) 234 | (set App:turn (if (= App:turn 1) 2 1)) 235 | (inc App:turns) 236 | ) 237 | ) 238 | -------------------------------------------------------------------------------- /examples/wow.expected.txt: -------------------------------------------------------------------------------- 1 | WOW 2 | abc 3 | . 4 | -------------------------------------------------------------------------------- /examples/wow/a.sjava: -------------------------------------------------------------------------------- 1 | (package examples.wow) 2 | 3 | (import examples.wow.x.y) 4 | 5 | (define-class Main () public 6 | ((main args String[]) void public static 7 | (System:out:println "WOW") 8 | (y:wow) 9 | ) 10 | ) 11 | -------------------------------------------------------------------------------- /examples/wow/x/y.sjava: -------------------------------------------------------------------------------- 1 | (package examples.wow.x) 2 | 3 | (define-class y () public 4 | ((wow) void public static 5 | (System:out:println "abc") 6 | (y:wow2) 7 | ) 8 | ((wow2) void public static 9 | (System:out:println ".") 10 | ) 11 | ) 12 | -------------------------------------------------------------------------------- /fernflower.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tombousso/sJava/d926a3efee11415e18820707617da75725c0c215/fernflower.jar -------------------------------------------------------------------------------- /generated-java/sjava/compiler/AVar.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler; 2 | 3 | import gnu.bytecode.CodeAttr; 4 | import gnu.bytecode.Type; 5 | 6 | public class AVar { 7 | public Type type; 8 | 9 | AVar(Type type) { 10 | this.type = type; 11 | } 12 | 13 | public Type load(CodeAttr code) { 14 | return this.type; 15 | } 16 | 17 | public void store(CodeAttr code) { 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/Arg.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler; 2 | 3 | import gnu.bytecode.CodeAttr; 4 | import gnu.bytecode.Type; 5 | import sjava.compiler.AVar; 6 | 7 | public class Arg extends AVar { 8 | public int n; 9 | public int level; 10 | 11 | public Arg(Type type, int n, int level) { 12 | super(type); 13 | this.n = n; 14 | this.level = level; 15 | } 16 | 17 | public Type load(CodeAttr code) { 18 | boolean output = code != null; 19 | if(output) { 20 | code.emitLoad(code.getArg(this.n)); 21 | } 22 | 23 | return super.type; 24 | } 25 | 26 | public void store(CodeAttr code) { 27 | boolean output = code != null; 28 | if(output) { 29 | code.emitStore(code.getArg(this.n)); 30 | } 31 | 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/CastVar.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler; 2 | 3 | import gnu.bytecode.CodeAttr; 4 | import gnu.bytecode.Type; 5 | import sjava.compiler.AVar; 6 | import sjava.compiler.handlers.GenHandler; 7 | 8 | public class CastVar extends AVar { 9 | public AVar v; 10 | 11 | public CastVar(AVar v, Type t) { 12 | super(t); 13 | this.v = v; 14 | } 15 | 16 | public Type load(CodeAttr code) { 17 | return GenHandler.castMaybe(code, this.v.load(code), super.type); 18 | } 19 | 20 | public void store(CodeAttr code) { 21 | this.v.store(code); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/ClassInfo.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler; 2 | 3 | import gnu.bytecode.Access; 4 | import gnu.bytecode.AnnotationEntry; 5 | import gnu.bytecode.ArrayClassLoader; 6 | import gnu.bytecode.ArrayType; 7 | import gnu.bytecode.ClassType; 8 | import gnu.bytecode.ParameterizedType; 9 | import gnu.bytecode.RuntimeAnnotationsAttr; 10 | import gnu.bytecode.Type; 11 | import gnu.bytecode.TypeVariable; 12 | import java.io.File; 13 | import java.io.IOException; 14 | import java.util.ArrayList; 15 | import java.util.Collection; 16 | import java.util.HashMap; 17 | import java.util.Iterator; 18 | import java.util.LinkedHashMap; 19 | import java.util.List; 20 | import org.apache.commons.io.FileUtils; 21 | import sjava.compiler.AMethodInfo; 22 | import sjava.compiler.Arg; 23 | import sjava.compiler.FileScope; 24 | import sjava.compiler.Main; 25 | import sjava.compiler.MethodInfo; 26 | import sjava.compiler.handlers.GenHandler; 27 | import sjava.compiler.tokens.ArrayToken; 28 | import sjava.compiler.tokens.BlockToken; 29 | import sjava.compiler.tokens.GenericToken; 30 | import sjava.compiler.tokens.ImList; 31 | import sjava.compiler.tokens.LexedParsedToken; 32 | import sjava.compiler.tokens.SingleQuoteToken; 33 | import sjava.compiler.tokens.Token; 34 | import sjava.compiler.tokens.VToken; 35 | import sjava.std.Tuple2; 36 | 37 | public class ClassInfo { 38 | public FileScope fs; 39 | public ClassType c; 40 | BlockToken supers; 41 | ImList toks; 42 | public List methods; 43 | public List anonClasses; 44 | Class rc; 45 | HashMap tvs; 46 | byte[] classfile; 47 | 48 | public ClassInfo(FileScope fs, ClassType c) { 49 | this.fs = fs; 50 | this.c = c; 51 | this.methods = new ArrayList(); 52 | this.anonClasses = new ArrayList(); 53 | if(c != null) { 54 | this.c.setClassfileVersion(ClassType.JDK_1_8_VERSION); 55 | this.c.setSuper(Type.javalangObjectType); 56 | TypeVariable[] args = c.getTypeParameters(); 57 | if(args != null) { 58 | this.tvs = new HashMap(); 59 | TypeVariable[] array = args; 60 | 61 | for(int notused = 0; notused != array.length; ++notused) { 62 | TypeVariable tv = array[notused]; 63 | if(tv instanceof TypeVariable) { 64 | this.tvs.put(tv.getName(), tv); 65 | } 66 | } 67 | } 68 | } 69 | 70 | } 71 | 72 | public ClassInfo(FileScope fs, String name) { 73 | this(fs, new ClassType(name)); 74 | } 75 | 76 | byte[] getClassfile() { 77 | if(this.classfile == null) { 78 | this.classfile = this.c.writeToArray(); 79 | } 80 | 81 | return this.classfile; 82 | } 83 | 84 | public void addToClassLoader(ArrayClassLoader cl) { 85 | cl.addClass(this.c.getName(), this.getClassfile()); 86 | List iterable = this.anonClasses; 87 | Iterator it = iterable.iterator(); 88 | 89 | for(int notused = 0; it.hasNext(); ++notused) { 90 | ClassInfo anon = (ClassInfo)it.next(); 91 | anon.addToClassLoader(cl); 92 | } 93 | 94 | } 95 | 96 | public Class getClazz(ArrayClassLoader cl) { 97 | Class c = (Class)null; 98 | 99 | try { 100 | c = cl.loadClass(this.c.getName()); 101 | return c; 102 | } catch (ClassNotFoundException var4) { 103 | throw new RuntimeException(var4); 104 | } 105 | } 106 | 107 | public Class getClazz() { 108 | if(this.rc == null) { 109 | ArrayClassLoader cl = Main.getClassLoader(); 110 | this.addToClassLoader(cl); 111 | this.rc = this.getClazz(cl); 112 | } 113 | 114 | return this.rc; 115 | } 116 | 117 | public void writeFiles(String dir) { 118 | StringBuilder sb = new StringBuilder(); 119 | sb.append(dir); 120 | sb.append("/"); 121 | sb.append(this.fs.package_.replace(".", "/")); 122 | String pre = sb.toString(); 123 | (new File(pre)).mkdirs(); 124 | 125 | try { 126 | StringBuilder sb1 = new StringBuilder(); 127 | sb1.append(pre); 128 | sb1.append(this.c.getSimpleName()); 129 | sb1.append(".class"); 130 | FileUtils.writeByteArrayToFile(new File(sb1.toString()), this.getClassfile()); 131 | } catch (IOException var10) { 132 | throw new RuntimeException(var10); 133 | } 134 | 135 | List iterable = this.anonClasses; 136 | Iterator it = iterable.iterator(); 137 | 138 | for(int notused = 0; it.hasNext(); ++notused) { 139 | ClassInfo anon = (ClassInfo)it.next(); 140 | anon.writeFiles(dir); 141 | } 142 | 143 | } 144 | 145 | Type getType(String name, boolean allowNew) { 146 | boolean abs = name.contains("."); 147 | Object var10000; 148 | if(this.tvs != null && this.tvs.containsKey(name)) { 149 | var10000 = (TypeVariable)this.tvs.get(name); 150 | } else if(Main.constTypes.containsKey(name)) { 151 | var10000 = (Type)Main.constTypes.get(name); 152 | } else if(allowNew && this.fs.cs.locals.containsKey(name)) { 153 | var10000 = (ClassType)this.fs.cs.locals.get(name); 154 | } else if(allowNew && !abs && this.fs.cs.locals.containsKey(this.fs.package_.concat(name))) { 155 | var10000 = (ClassType)this.fs.cs.locals.get(this.fs.package_.concat(name)); 156 | } else if(this.fs.imports.containsKey(name)) { 157 | String fullName = (String)this.fs.imports.get(name); 158 | if(allowNew && this.fs.cs.locals.containsKey(fullName)) { 159 | var10000 = (ClassType)this.fs.cs.locals.get(fullName); 160 | } else { 161 | if(!this.fs.cs.classExists(fullName)) { 162 | throw new RuntimeException(); 163 | } 164 | 165 | var10000 = Type.getType(fullName); 166 | } 167 | } else { 168 | ArrayList matches = new ArrayList(); 169 | ArrayList iterable = this.fs.starImports; 170 | Iterator it = iterable.iterator(); 171 | 172 | for(int notused = 0; it.hasNext(); ++notused) { 173 | String starImport = (String)it.next(); 174 | String fullName1 = starImport.concat(name); 175 | if(allowNew && this.fs.cs.locals.containsKey(fullName1)) { 176 | matches.add((ClassType)this.fs.cs.locals.get(fullName1)); 177 | } else if(this.fs.cs.classExists(fullName1)) { 178 | matches.add(Type.getType(fullName1)); 179 | } 180 | } 181 | 182 | if(matches.size() == 1) { 183 | var10000 = (Type)matches.get(0); 184 | } else { 185 | if(matches.size() > 1) { 186 | StringBuilder sb = new StringBuilder(); 187 | sb.append("Too many types match: "); 188 | sb.append(matches); 189 | throw new RuntimeException(sb.toString()); 190 | } 191 | 192 | var10000 = this.fs.cs.classExists(name)?Type.getType(name):(Type)null; 193 | } 194 | } 195 | 196 | return (Type)var10000; 197 | } 198 | 199 | public Type getType(Token tok, boolean allowNew) { 200 | Object var10000; 201 | if(tok instanceof GenericToken) { 202 | GenericToken tok1 = (GenericToken)tok; 203 | ClassType c = (ClassType)this.getType(((VToken)tok1.tok).val, allowNew).getRawType(); 204 | ImList collection = tok1.toks; 205 | Type[] out = new Type[collection.size()]; 206 | Iterator it = collection.iterator(); 207 | 208 | for(int i = 0; it.hasNext(); ++i) { 209 | LexedParsedToken param = (LexedParsedToken)it.next(); 210 | out[i] = this.getType((Token)param, allowNew); 211 | } 212 | 213 | var10000 = new ParameterizedType(c, out); 214 | } else if(tok instanceof ArrayToken) { 215 | ArrayToken tok2 = (ArrayToken)tok; 216 | var10000 = new ArrayType(this.getType((Token)((LexedParsedToken)tok2.toks.get(0)), allowNew)); 217 | } else if(tok instanceof VToken) { 218 | VToken tok3 = (VToken)tok; 219 | var10000 = this.getType(tok3.val, allowNew); 220 | } else { 221 | var10000 = (Type)null; 222 | } 223 | 224 | return (Type)var10000; 225 | } 226 | 227 | public Type getType(Token tok) { 228 | return this.getType(tok, true); 229 | } 230 | 231 | public void compileDef(BlockToken tok) { 232 | if(tok instanceof BlockToken) { 233 | LexedParsedToken first = (LexedParsedToken)tok.toks.get(0); 234 | if(first instanceof BlockToken) { 235 | LinkedHashMap scope = new LinkedHashMap(); 236 | Tuple2 tup = Main.extractModifiers(tok.toks, 2); 237 | Integer mods = (Integer)tup._1; 238 | Integer i = (Integer)tup._2; 239 | int n = (mods.intValue() & Access.STATIC) == 0?1:0; 240 | ClassType[] exceptions = (ClassType[])null; 241 | 242 | ArrayList annotations; 243 | for(annotations = new ArrayList(); i.intValue() != tok.toks.size() && (LexedParsedToken)tok.toks.get(i.intValue()) instanceof SingleQuoteToken; i = Integer.valueOf(i.intValue() + 1)) { 244 | ImList toks = ((BlockToken)((LexedParsedToken)((SingleQuoteToken)((LexedParsedToken)tok.toks.get(i.intValue()))).toks.get(0))).toks; 245 | VToken first1 = (VToken)((LexedParsedToken)toks.get(0)); 246 | if(!first1.val.equals("throws")) { 247 | annotations.add(new AnnotationEntry((ClassType)this.getType(first1))); 248 | } else { 249 | ImList collection = toks.skip(1); 250 | ClassType[] out = new ClassType[collection.size()]; 251 | Iterator it = collection.iterator(); 252 | 253 | for(int i1 = 0; it.hasNext(); ++i1) { 254 | LexedParsedToken tok1 = (LexedParsedToken)it.next(); 255 | out[i1] = (ClassType)this.getType(tok1); 256 | } 257 | 258 | exceptions = out; 259 | } 260 | } 261 | 262 | List types = Main.getParams(this, (BlockToken)first, scope, 1, n); 263 | AMethodInfo mi = this.addMethod(((VToken)((LexedParsedToken)((BlockToken)first).toks.get(0))).val, types, this.getType((LexedParsedToken)tok.toks.get(1)), mods.intValue(), tok.toks.skip(i.intValue()), scope); 264 | if(exceptions != null) { 265 | mi.method.setExceptions(exceptions); 266 | } 267 | 268 | Iterator it1 = annotations.iterator(); 269 | 270 | for(int notused = 0; it1.hasNext(); ++notused) { 271 | AnnotationEntry annotation = (AnnotationEntry)it1.next(); 272 | RuntimeAnnotationsAttr.maybeAddAnnotation(mi.method, annotation); 273 | } 274 | } else { 275 | String name = ((VToken)first).val; 276 | if(!name.endsWith("!")) { 277 | Tuple2 tup1 = Main.extractModifiers(tok.toks, 2); 278 | Integer mods1 = (Integer)tup1._1; 279 | Integer i2 = (Integer)tup1._2; 280 | Type t = this.getType((LexedParsedToken)tok.toks.get(1)); 281 | this.c.addField(name, t, mods1.intValue()); 282 | } 283 | } 284 | } 285 | 286 | } 287 | 288 | void compileDefs() { 289 | ClassType c = this.c; 290 | ImList iterable = this.supers.toks; 291 | Iterator it = iterable.iterator(); 292 | 293 | for(int notused = 0; it.hasNext(); ++notused) { 294 | LexedParsedToken var5 = (LexedParsedToken)it.next(); 295 | Type related = this.getType(var5); 296 | if(related.isInterface()) { 297 | c.addInterface(related); 298 | } else { 299 | c.setSuper(related); 300 | } 301 | } 302 | 303 | ImList iterable1 = this.toks; 304 | Iterator it1 = iterable1.iterator(); 305 | 306 | for(int notused1 = 0; it1.hasNext(); ++notused1) { 307 | LexedParsedToken tok = (LexedParsedToken)it1.next(); 308 | this.compileDef((BlockToken)tok); 309 | } 310 | 311 | } 312 | 313 | public void compileMethods() { 314 | List iterable = this.methods; 315 | Iterator it = iterable.iterator(); 316 | 317 | for(int notused = 0; it.hasNext(); ++notused) { 318 | AMethodInfo mi = (AMethodInfo)it.next(); 319 | mi.compileMethodBody(new GenHandler(mi)); 320 | } 321 | 322 | } 323 | 324 | void runClassMacros() { 325 | ImList iterable = this.toks; 326 | Iterator it = iterable.iterator(); 327 | 328 | for(int notused = 0; it.hasNext(); ++notused) { 329 | LexedParsedToken tok = (LexedParsedToken)it.next(); 330 | if(tok instanceof BlockToken && (LexedParsedToken)((BlockToken)tok).toks.get(0) instanceof VToken && ((VToken)((LexedParsedToken)((BlockToken)tok).toks.get(0))).val.endsWith("!")) { 331 | this.runClassMacro((BlockToken)tok); 332 | } 333 | } 334 | 335 | } 336 | 337 | void runClassMacro(BlockToken tok) { 338 | String name = ((VToken)((LexedParsedToken)tok.toks.get(0))).val; 339 | name = name.substring(0, name.length() - 1); 340 | Type[] pre = new Type[]{Main.getCompilerType("ClassInfo")}; 341 | GenHandler.callMacro(pre, tok.toks.skip(1), name, this.fs.cs.classMacroNames, new Object[]{this}); 342 | } 343 | 344 | public AMethodInfo addMethod(String name, List params, Type ret, int mods, ImList toks, LinkedHashMap scope, boolean addThis) { 345 | if(addThis && (mods & Access.STATIC) == 0) { 346 | scope.put("this", new Arg(this.c, 0, 0)); 347 | } 348 | 349 | MethodInfo out = new MethodInfo(this, toks, scope, name, params, ret, mods); 350 | this.methods.add(out); 351 | return out; 352 | } 353 | 354 | public AMethodInfo addMethod(String name, List params, Type ret, int mods, ImList toks, LinkedHashMap scope) { 355 | return this.addMethod(name, params, ret, mods, toks, scope, true); 356 | } 357 | 358 | public AMethodInfo addMethod(String name, Type ret, int mods, ImList toks, LinkedHashMap scope) { 359 | ArrayList params = new ArrayList(); 360 | Collection iterable = scope.values(); 361 | Iterator it = iterable.iterator(); 362 | 363 | for(int notused = 0; it.hasNext(); ++notused) { 364 | Arg arg = (Arg)it.next(); 365 | params.add(arg.type); 366 | } 367 | 368 | return this.addMethod(name, params, ret, mods, toks, scope); 369 | } 370 | } 371 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/ClassMacroMethodInfo.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler; 2 | 3 | import gnu.bytecode.Type; 4 | import java.util.LinkedHashMap; 5 | import java.util.List; 6 | import sjava.compiler.AMethodInfo; 7 | import sjava.compiler.Arg; 8 | import sjava.compiler.ClassInfo; 9 | import sjava.compiler.tokens.ImList; 10 | import sjava.compiler.tokens.LexedParsedToken; 11 | 12 | public class ClassMacroMethodInfo extends AMethodInfo { 13 | ClassMacroMethodInfo(ClassInfo ci, ImList toks, LinkedHashMap firstScope, String name, List params, Type ret, int mods) { 14 | super(ci, toks, firstScope, name, params, ret, mods); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/CompileScope.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler; 2 | 3 | import gnu.bytecode.ArrayClassLoader; 4 | import gnu.bytecode.ClassType; 5 | import java.util.HashMap; 6 | import java.util.List; 7 | import sjava.compiler.MacroInfo; 8 | import sjava.compiler.Main; 9 | 10 | public class CompileScope { 11 | HashMap locals = new HashMap(); 12 | public HashMap> macroNames = new HashMap(); 13 | HashMap> classMacroNames = new HashMap(); 14 | ArrayClassLoader mcl = Main.getClassLoader(); 15 | HashMap found = new HashMap(); 16 | int macroIndex = 0; 17 | 18 | boolean classExists(String name) { 19 | boolean var10000; 20 | if(this.found.containsKey(name)) { 21 | var10000 = ((Boolean)this.found.get(name)).booleanValue(); 22 | } else { 23 | boolean b; 24 | try { 25 | Main.class.getClassLoader().loadClass(name); 26 | b = true; 27 | } catch (ClassNotFoundException var5) { 28 | b = false; 29 | } catch (NoClassDefFoundError var6) { 30 | b = false; 31 | } 32 | 33 | this.found.put(name, Boolean.valueOf(b)); 34 | var10000 = b; 35 | } 36 | 37 | return var10000; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/FileScope.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler; 2 | 3 | import gnu.bytecode.Access; 4 | import gnu.bytecode.ArrayType; 5 | import gnu.bytecode.ClassType; 6 | import gnu.bytecode.Type; 7 | import gnu.bytecode.TypeVariable; 8 | import java.util.ArrayList; 9 | import java.util.Arrays; 10 | import java.util.HashMap; 11 | import java.util.Iterator; 12 | import java.util.LinkedHashMap; 13 | import java.util.List; 14 | import java.util.Map; 15 | import sjava.compiler.AMethodInfo; 16 | import sjava.compiler.Arg; 17 | import sjava.compiler.ClassInfo; 18 | import sjava.compiler.CompileScope; 19 | import sjava.compiler.MacroInfo; 20 | import sjava.compiler.Main; 21 | import sjava.compiler.handlers.GenHandler; 22 | import sjava.compiler.tokens.BlockToken; 23 | import sjava.compiler.tokens.GenericToken; 24 | import sjava.compiler.tokens.ImList; 25 | import sjava.compiler.tokens.IncludeToken; 26 | import sjava.compiler.tokens.LexedParsedToken; 27 | import sjava.compiler.tokens.Token; 28 | import sjava.compiler.tokens.VToken; 29 | 30 | public class FileScope { 31 | public CompileScope cs; 32 | public String path; 33 | ImList toks; 34 | HashMap imports; 35 | ArrayList starImports; 36 | public MacroInfo includes; 37 | public List newClasses; 38 | String package_; 39 | 40 | FileScope(CompileScope cs, String path, ImList toks) { 41 | this.cs = cs; 42 | this.path = path; 43 | this.toks = toks; 44 | this.imports = new HashMap(); 45 | this.starImports = new ArrayList(); 46 | this.starImports.add("java.lang."); 47 | this.starImports.add("sjava.std."); 48 | this.newClasses = new ArrayList(); 49 | this.package_ = toks.size() > 0 && (LexedParsedToken)toks.get(0) instanceof BlockToken && (LexedParsedToken)((BlockToken)((LexedParsedToken)toks.get(0))).toks.get(0) instanceof VToken && ((VToken)((LexedParsedToken)((BlockToken)((LexedParsedToken)toks.get(0))).toks.get(0))).val.equals("package")?((VToken)((LexedParsedToken)((BlockToken)((LexedParsedToken)toks.get(0))).toks.get(1))).val.concat("."):""; 50 | MacroInfo includes = new MacroInfo(this, "Includes"); 51 | this.includes = includes; 52 | includes.c.setModifiers(Access.PUBLIC); 53 | } 54 | 55 | ClassType getNewType(Token tok) { 56 | ClassType var10000; 57 | if(tok instanceof GenericToken) { 58 | GenericToken tok1 = (GenericToken)tok; 59 | ClassType c = new ClassType(this.package_.concat(((VToken)tok1.tok).val)); 60 | TypeVariable[] tparams = new TypeVariable[tok1.toks.size()]; 61 | ImList iterable = tok1.toks; 62 | Iterator it = iterable.iterator(); 63 | 64 | for(int i = 0; it.hasNext(); ++i) { 65 | LexedParsedToken param = (LexedParsedToken)it.next(); 66 | String name = ((VToken)param).val; 67 | TypeVariable tv = new TypeVariable(name); 68 | tparams[i] = tv; 69 | } 70 | 71 | c.setTypeParameters(tparams); 72 | var10000 = c; 73 | } else if(tok instanceof VToken) { 74 | VToken tok2 = (VToken)tok; 75 | var10000 = new ClassType(this.package_.concat(tok2.val)); 76 | } else { 77 | var10000 = (ClassType)null; 78 | } 79 | 80 | return var10000; 81 | } 82 | 83 | void compileRoot(List macros) { 84 | ImList iterable = this.toks; 85 | Iterator it = iterable.iterator(); 86 | 87 | for(int notused = 0; it.hasNext(); ++notused) { 88 | LexedParsedToken tok = (LexedParsedToken)it.next(); 89 | this.compileRoot(macros, (BlockToken)tok); 90 | } 91 | 92 | } 93 | 94 | boolean getMacroParams(List out, BlockToken params, Map scope) { 95 | boolean varargs = false; 96 | int o = out.size(); 97 | ImList iterable = params.toks.skip(1); 98 | Iterator it = iterable.iterator(); 99 | 100 | for(int i = 0; it.hasNext(); ++i) { 101 | LexedParsedToken tok = (LexedParsedToken)it.next(); 102 | Object t = Main.getCompilerType("tokens.LexedParsedToken"); 103 | String name = ((VToken)tok).val; 104 | if(name.contains("@")) { 105 | name = name.replace("@", ""); 106 | t = new ArrayType((Type)t); 107 | varargs = true; 108 | } 109 | 110 | out.add((Type)t); 111 | scope.put(name, new Arg((Type)t, o + i, 0)); 112 | } 113 | 114 | return varargs; 115 | } 116 | 117 | void compileRoot(List macros, BlockToken tok) { 118 | LexedParsedToken first = (LexedParsedToken)tok.toks.get(0); 119 | if(first instanceof VToken) { 120 | if(((VToken)first).val.equals("define-class")) { 121 | ClassType c = this.getNewType((LexedParsedToken)tok.toks.get(1)); 122 | String name = c.getName(); 123 | ClassInfo ci = new ClassInfo(this, c); 124 | ci.supers = (BlockToken)((LexedParsedToken)tok.toks.get(2)); 125 | this.newClasses.add(ci); 126 | this.cs.locals.put(name, ci.c); 127 | boolean run = true; 128 | int i = 3; 129 | 130 | while(run && i != tok.toks.size()) { 131 | run = Main.compileClassMod((LexedParsedToken)tok.toks.get(i), ci.c); 132 | if(run) { 133 | ++i; 134 | } 135 | } 136 | 137 | ci.toks = tok.toks.skip(i); 138 | } else if(((VToken)first).val.equals("import")) { 139 | String var9 = ((VToken)((LexedParsedToken)tok.toks.get(1))).val; 140 | if(var9.endsWith("*")) { 141 | this.starImports.add(var9.substring(0, var9.length() - 1)); 142 | } else { 143 | this.imports.put(var9.substring(var9.lastIndexOf(".") + 1), var9); 144 | } 145 | } else if(((VToken)first).val.equals("define-macro")) { 146 | LinkedHashMap scope = new LinkedHashMap(); 147 | BlockToken params = (BlockToken)((LexedParsedToken)tok.toks.get(1)); 148 | String name1 = ((VToken)((LexedParsedToken)params.toks.get(0))).val; 149 | ArrayList types = new ArrayList(Arrays.asList(new Type[]{Main.getCompilerType("AMethodInfo"), Type.intType, Main.getCompilerType("handlers.GenHandler")})); 150 | int mods = Access.PUBLIC | Access.STATIC; 151 | scope.put("mi", new Arg(Main.getCompilerType("AMethodInfo"), 0, 0)); 152 | boolean varargs = this.getMacroParams(types, params, scope); 153 | if(varargs) { 154 | mods |= Access.TRANSIENT; 155 | } 156 | 157 | StringBuilder sb = new StringBuilder(); 158 | sb.append("Macros"); 159 | sb.append(this.cs.macroIndex); 160 | String cname = sb.toString(); 161 | ++this.cs.macroIndex; 162 | MacroInfo macroi = new MacroInfo(this, cname); 163 | macroi.c.setModifiers(Access.PUBLIC); 164 | macroi.addMethod(name1, types, Main.getCompilerType("tokens.LexedParsedToken"), mods, tok.toks.skip(2), scope); 165 | if(this.cs.macroNames.containsKey(name1)) { 166 | ((List)this.cs.macroNames.get(name1)).add(macroi); 167 | } else { 168 | this.cs.macroNames.put(name1, new ArrayList(Arrays.asList(new Object[]{macroi}))); 169 | } 170 | 171 | macros.add(macroi); 172 | } else if(((VToken)first).val.equals("define-class-macro")) { 173 | LinkedHashMap scope1 = new LinkedHashMap(); 174 | BlockToken params1 = (BlockToken)((LexedParsedToken)tok.toks.get(1)); 175 | String name2 = ((VToken)((LexedParsedToken)params1.toks.get(0))).val; 176 | ArrayList types1 = new ArrayList(Arrays.asList(new Type[]{Main.getCompilerType("ClassInfo")})); 177 | int mods1 = Access.PUBLIC | Access.STATIC; 178 | scope1.put("ci", new Arg(Main.getCompilerType("ClassInfo"), 0, 0)); 179 | boolean varargs1 = this.getMacroParams(types1, params1, scope1); 180 | if(varargs1) { 181 | mods1 |= Access.TRANSIENT; 182 | } 183 | 184 | String cname1 = "Macros"; 185 | MacroInfo macroi1 = new MacroInfo(this, cname1); 186 | macroi1.c.setModifiers(Access.PUBLIC); 187 | macroi1.addClassMacroMethod(name2, types1, Type.voidType, mods1, tok.toks.skip(2), scope1); 188 | if(this.cs.classMacroNames.containsKey(name2)) { 189 | ((List)this.cs.classMacroNames.get(name2)).add(macroi1); 190 | } else { 191 | this.cs.classMacroNames.put(name2, new ArrayList(Arrays.asList(new Object[]{macroi1}))); 192 | } 193 | } else if(!((VToken)first).val.equals("package")) { 194 | throw new RuntimeException(((VToken)first).val); 195 | } 196 | } 197 | 198 | } 199 | 200 | void compileDefs() { 201 | List iterable = this.newClasses; 202 | Iterator it = iterable.iterator(); 203 | 204 | for(int notused = 0; it.hasNext(); ++notused) { 205 | ClassInfo ci = (ClassInfo)it.next(); 206 | ci.compileDefs(); 207 | } 208 | 209 | } 210 | 211 | void runClassMacros() { 212 | List iterable = this.newClasses; 213 | Iterator it = iterable.iterator(); 214 | 215 | for(int notused = 0; it.hasNext(); ++notused) { 216 | ClassInfo ci = (ClassInfo)it.next(); 217 | ci.runClassMacros(); 218 | } 219 | 220 | } 221 | 222 | public void compileInclude(IncludeToken tok) { 223 | String name = "$".concat(Integer.toString(this.includes.c.getMethodCount())); 224 | LinkedHashMap scope = new LinkedHashMap(); 225 | scope.put("mi", new Arg(Main.getCompilerType("AMethodInfo"), 0, 0)); 226 | Type[] params = new Type[]{Main.getCompilerType("AMethodInfo"), Type.intType, Main.getCompilerType("handlers.GenHandler")}; 227 | AMethodInfo mi = this.includes.addMethod(name, Arrays.asList(params), Main.getCompilerType("tokens.LexedParsedToken"), Access.PUBLIC | Access.STATIC, tok.toks, scope); 228 | mi.compileMethodBody(new GenHandler(mi)); 229 | tok.mi = mi; 230 | } 231 | } 232 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/Formatter.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler; 2 | 3 | import java.util.Iterator; 4 | import sjava.compiler.Lexer; 5 | import sjava.compiler.Main; 6 | import sjava.compiler.Parser; 7 | import sjava.compiler.tokens.ArrayToken; 8 | import sjava.compiler.tokens.BlockToken; 9 | import sjava.compiler.tokens.ColonToken; 10 | import sjava.compiler.tokens.CommentToken; 11 | import sjava.compiler.tokens.GenericToken; 12 | import sjava.compiler.tokens.ImList; 13 | import sjava.compiler.tokens.LexedParsedToken; 14 | import sjava.compiler.tokens.QuoteToken; 15 | import sjava.compiler.tokens.SingleQuoteToken; 16 | import sjava.compiler.tokens.UnquoteToken; 17 | 18 | public class Formatter { 19 | public static String formatCode(String code) { 20 | StringBuilder sb = new StringBuilder(); 21 | sb.append(formatToks(Main.parse(code, new Lexer(), new Parser(false)))); 22 | sb.append('\n'); 23 | return sb.toString(); 24 | } 25 | 26 | static int formatToks(LexedParsedToken block, int tabs, String before, String after, StringBuffer sb, ImList toks) { 27 | sb.append(before); 28 | int line = 0; 29 | boolean prevMultiline = false; 30 | Iterator it = toks.iterator(); 31 | 32 | for(int i = 0; it.hasNext(); ++i) { 33 | LexedParsedToken tok = (LexedParsedToken)it.next(); 34 | boolean indent = false; 35 | int toLine = tok.line; 36 | boolean multiline = tok.firstLine() != tok.lastLine(); 37 | if(i == 0) { 38 | if(multiline) { 39 | toLine = line + 1; 40 | indent = true; 41 | } else { 42 | toLine = line; 43 | } 44 | } else if(tok.line == line && multiline) { 45 | toLine = tok.line + 1; 46 | indent = true; 47 | } else { 48 | if(tok.line == line) { 49 | if(prevMultiline) { 50 | ++toLine; 51 | } else { 52 | sb.append(" "); 53 | } 54 | } 55 | 56 | indent = tok.line != block.line; 57 | } 58 | 59 | line = formatTok(tok, line, toLine, tabs + (indent?1:0), sb); 60 | prevMultiline = multiline; 61 | } 62 | 63 | if(block.firstLine() != block.lastLine()) { 64 | sb.append("\n"); 65 | 66 | for(int i1 = tabs; i1 > 0; --i1) { 67 | sb.append("\t"); 68 | } 69 | } 70 | 71 | sb.append(after); 72 | line = block.endLine; 73 | return line; 74 | } 75 | 76 | static String formatToks(ImList toks) { 77 | StringBuffer sb = new StringBuffer(); 78 | int line = toks.size() != 0?((LexedParsedToken)toks.get(0)).line:1; 79 | Iterator it = toks.iterator(); 80 | 81 | for(int i = 0; it.hasNext(); ++i) { 82 | LexedParsedToken tok = (LexedParsedToken)it.next(); 83 | int off = tok.line == line && i != 0?1:0; 84 | line = formatTok(tok, line, tok.line + off, 0, sb); 85 | } 86 | 87 | return sb.toString(); 88 | } 89 | 90 | static int formatTok(LexedParsedToken tok, int line, int toLine, int tabs, StringBuffer sb) { 91 | for(int i = toLine - line; i > 0; --i) { 92 | sb.append("\n"); 93 | } 94 | 95 | if(toLine != line) { 96 | for(int i1 = tabs; i1 > 0; --i1) { 97 | sb.append("\t"); 98 | } 99 | } 100 | 101 | line = tok.line; 102 | if(tok instanceof BlockToken) { 103 | BlockToken tok1 = (BlockToken)tok; 104 | formatToks(tok1, tabs, "(", ")", sb, tok1.toks); 105 | } else if(tok instanceof GenericToken) { 106 | GenericToken tok2 = (GenericToken)tok; 107 | formatTok(tok2.tok, line, line, tabs, sb); 108 | formatToks(tok2, tabs, "{", "}", sb, tok2.toks); 109 | } else if(tok instanceof ArrayToken) { 110 | ArrayToken tok3 = (ArrayToken)tok; 111 | formatTok((LexedParsedToken)tok3.toks.get(0), line, line, tabs, sb); 112 | formatToks(tok3, tabs, "[", "]", sb, tok3.toks.skip(1)); 113 | } else if(tok instanceof ColonToken) { 114 | ColonToken tok4 = (ColonToken)tok; 115 | line = formatTok(tok4.left, line, line, tabs, sb); 116 | sb.append(":"); 117 | formatTok(tok4.right, line, line, tabs, sb); 118 | } else if(tok instanceof SingleQuoteToken) { 119 | SingleQuoteToken tok5 = (SingleQuoteToken)tok; 120 | sb.append("\'"); 121 | formatTok((LexedParsedToken)tok5.toks.get(0), line, line, tabs, sb); 122 | } else if(tok instanceof QuoteToken) { 123 | QuoteToken tok6 = (QuoteToken)tok; 124 | sb.append("`"); 125 | formatTok((LexedParsedToken)tok6.toks.get(0), line, line, tabs, sb); 126 | } else if(tok instanceof UnquoteToken) { 127 | UnquoteToken tok7 = (UnquoteToken)tok; 128 | sb.append(tok7.var?",$":","); 129 | formatTok((LexedParsedToken)tok7.toks.get(0), line, line, tabs, sb); 130 | } else if(tok instanceof CommentToken) { 131 | CommentToken tok8 = (CommentToken)tok; 132 | sb.append(";"); 133 | sb.append(tok8.val); 134 | } else { 135 | sb.append(tok.toString()); 136 | } 137 | 138 | return tok.endLine; 139 | } 140 | 141 | public static int checkFormatted(String code) { 142 | String formatted = formatCode(code); 143 | int line = 1; 144 | int len = Math.min(code.length(), formatted.length()); 145 | 146 | for(int i = 0; i < len; ++i) { 147 | if(code.charAt(i) != formatted.charAt(i)) { 148 | return line; 149 | } 150 | 151 | if(code.charAt(i) == 10) { 152 | ++line; 153 | } 154 | } 155 | 156 | return code.length() != formatted.length()?line:-1; 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/Lexer.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import org.apache.commons.lang3.StringEscapeUtils; 6 | import sjava.compiler.Main; 7 | import sjava.compiler.tokens.CToken; 8 | import sjava.compiler.tokens.CommentToken; 9 | import sjava.compiler.tokens.ConstToken; 10 | import sjava.compiler.tokens.LexedParsedToken; 11 | import sjava.compiler.tokens.LexedToken; 12 | import sjava.compiler.tokens.NToken; 13 | import sjava.compiler.tokens.SToken; 14 | import sjava.compiler.tokens.VToken; 15 | 16 | public class Lexer { 17 | String code; 18 | int i; 19 | int len; 20 | String s; 21 | int line; 22 | 23 | int getprec() { 24 | int p = -1; 25 | 26 | for(int l = Main.ML; p == -1 && l != 0; --l) { 27 | if(this.i + l <= this.len) { 28 | this.s = this.peek(0, l); 29 | if(Main.s2prec.containsKey(this.s)) { 30 | p = ((Integer)Main.s2prec.get(this.s)).intValue(); 31 | } 32 | } 33 | } 34 | 35 | return p; 36 | } 37 | 38 | String peek(int n, int l) { 39 | return this.code.substring(this.i + n, this.i + n + l); 40 | } 41 | 42 | char peek(int n) { 43 | return this.code.charAt(this.i + n); 44 | } 45 | 46 | char peek() { 47 | return this.peek(0); 48 | } 49 | 50 | void skip(int n) { 51 | for(int i = 0; i < n; ++i) { 52 | if(this.peek() == 10) { 53 | ++this.line; 54 | } 55 | 56 | ++this.i; 57 | } 58 | 59 | } 60 | 61 | void skip() { 62 | this.skip(1); 63 | } 64 | 65 | void nextTok() { 66 | while(this.i != this.len && this.getprec() == -1 && !Character.isWhitespace(this.peek())) { 67 | this.skip(1); 68 | } 69 | 70 | } 71 | 72 | LexedToken token() { 73 | while(this.i != this.len && this.getprec() == -1 && Character.isWhitespace(this.peek())) { 74 | this.skip(1); 75 | } 76 | 77 | int p = this.getprec(); 78 | int oline = this.line; 79 | Object var10000; 80 | if(p == -1) { 81 | char c = this.i == this.len?0:this.peek(); 82 | int oi = this.i; 83 | if(c != 35) { 84 | if(Character.isDigit(c) || c == 45 && Character.isDigit(this.peek(1))) { 85 | this.nextTok(); 86 | var10000 = new NToken(this.line, this.code.substring(oi, this.i)); 87 | } else { 88 | this.nextTok(); 89 | String s = this.code.substring(oi, this.i); 90 | var10000 = s.equals("")?(LexedToken)null:(!s.equals("null") && !s.equals("true") && !s.equals("false")?new VToken(this.line, s):new ConstToken(this.line, s)); 91 | } 92 | } else { 93 | while(this.peek() != 32 && this.peek() != 41) { 94 | this.skip(1); 95 | } 96 | 97 | String schar = this.code.substring(oi + 2, this.i); 98 | var10000 = new CToken(this.line, schar.length() == 1?Character.valueOf(schar.charAt(0)):(Character)Main.specialChars.get(schar)); 99 | } 100 | } else { 101 | this.skip(this.s.length()); 102 | int oi1 = this.i; 103 | if(!this.s.equals("\"\"\"")) { 104 | if(!this.s.equals("\"")) { 105 | if(!this.s.equals(";")) { 106 | var10000 = new LexedToken(this.line, p, this.s); 107 | } else { 108 | while(this.i != this.len && this.peek() != 10) { 109 | this.skip(); 110 | } 111 | 112 | var10000 = new CommentToken(this.line, this.code.substring(oi1, this.i)); 113 | } 114 | } else { 115 | while(this.peek() != 34) { 116 | if(this.peek() == 92) { 117 | this.skip(2); 118 | } else { 119 | this.skip(); 120 | } 121 | } 122 | 123 | this.skip(); 124 | var10000 = new SToken(this.line, StringEscapeUtils.unescapeJava(this.code.substring(oi1, this.i - 1)), false); 125 | } 126 | } else { 127 | while(true) { 128 | while(!this.peek(0, 3).equals("\"\"\"")) { 129 | if(this.peek(0, 7).equals("\\\"\"\"\"\"\"")) { 130 | this.skip(4); 131 | } else if(!this.peek(0, 5).equals("\\\\\"\"\"") && !this.peek(0, 5).equals("\\\"\"\"\"")) { 132 | if(this.peek(0, 4).equals("\\\"\"\"")) { 133 | this.skip(4); 134 | } else { 135 | this.skip(); 136 | } 137 | } else { 138 | this.skip(2); 139 | } 140 | } 141 | 142 | String str = this.code.substring(oi1, this.i).replace("\\\"\"\"", "\"\"\""); 143 | if(str.endsWith("\\\\")) { 144 | StringBuilder sb = new StringBuilder(); 145 | sb.append(str.substring(0, str.length() - 2)); 146 | sb.append("\\"); 147 | str = sb.toString(); 148 | } else if(str.endsWith("\\\"")) { 149 | StringBuilder sb1 = new StringBuilder(); 150 | sb1.append(str.substring(0, str.length() - 2)); 151 | sb1.append("\""); 152 | str = sb1.toString(); 153 | } 154 | 155 | this.skip(3); 156 | var10000 = new SToken(oline, str, true); 157 | break; 158 | } 159 | } 160 | } 161 | 162 | Object out = var10000; 163 | if(out != null) { 164 | ((LexedParsedToken)out).endLine = this.line; 165 | } 166 | 167 | return (LexedToken)out; 168 | } 169 | 170 | List lex(String code) { 171 | this.code = code; 172 | this.i = 0; 173 | this.len = code.length(); 174 | this.line = 1; 175 | ArrayList out = new ArrayList(); 176 | 177 | while(this.i != this.len) { 178 | LexedToken tok = this.token(); 179 | if(tok != null) { 180 | out.add(tok); 181 | } 182 | } 183 | 184 | return out; 185 | } 186 | } 187 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/MacroInfo.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler; 2 | 3 | import gnu.bytecode.Type; 4 | import java.util.LinkedHashMap; 5 | import java.util.List; 6 | import sjava.compiler.AMethodInfo; 7 | import sjava.compiler.ClassInfo; 8 | import sjava.compiler.ClassMacroMethodInfo; 9 | import sjava.compiler.FileScope; 10 | import sjava.compiler.tokens.ImList; 11 | import sjava.compiler.tokens.LexedParsedToken; 12 | import sjava.compiler.tokens.Token; 13 | 14 | public class MacroInfo extends ClassInfo { 15 | MacroInfo(FileScope fs, String name) { 16 | super(fs, name); 17 | } 18 | 19 | public Type getType(Token tok) { 20 | return super.getType(tok, false); 21 | } 22 | 23 | public AMethodInfo addClassMacroMethod(String name, List params, Type ret, int mods, ImList toks, LinkedHashMap scope) { 24 | ClassMacroMethodInfo out = new ClassMacroMethodInfo(this, toks, scope, name, params, ret, mods); 25 | super.methods.add(out); 26 | return out; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/MethodInfo.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler; 2 | 3 | import gnu.bytecode.Method; 4 | import gnu.bytecode.Type; 5 | import java.util.LinkedHashMap; 6 | import java.util.List; 7 | import sjava.compiler.AMethodInfo; 8 | import sjava.compiler.Arg; 9 | import sjava.compiler.ClassInfo; 10 | import sjava.compiler.tokens.ImList; 11 | import sjava.compiler.tokens.LexedParsedToken; 12 | 13 | public class MethodInfo extends AMethodInfo { 14 | public MethodInfo(ClassInfo ci, ImList toks, LinkedHashMap firstScope, Method method) { 15 | super(ci, toks, firstScope, method); 16 | } 17 | 18 | MethodInfo(ClassInfo ci, ImList toks, LinkedHashMap firstScope, String name, List params, Type ret, int mods) { 19 | super(ci, toks, firstScope, name, params, ret, mods); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/Parser.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | import java.util.List; 6 | import sjava.compiler.tokens.ArrayToken; 7 | import sjava.compiler.tokens.BlockToken; 8 | import sjava.compiler.tokens.ColonToken; 9 | import sjava.compiler.tokens.CommentToken; 10 | import sjava.compiler.tokens.GenericToken; 11 | import sjava.compiler.tokens.ImList; 12 | import sjava.compiler.tokens.LexedParsedToken; 13 | import sjava.compiler.tokens.LexedToken; 14 | import sjava.compiler.tokens.QuoteToken; 15 | import sjava.compiler.tokens.SingleQuoteToken; 16 | import sjava.compiler.tokens.UnquoteToken; 17 | 18 | public class Parser { 19 | List toks; 20 | int i; 21 | boolean ignoreComments; 22 | 23 | public Parser(boolean ignoreComments) { 24 | this.ignoreComments = ignoreComments; 25 | } 26 | 27 | public Parser() { 28 | this(true); 29 | } 30 | 31 | LexedToken next() { 32 | LexedToken ret = (LexedToken)this.toks.get(this.i); 33 | ++this.i; 34 | return ret; 35 | } 36 | 37 | LexedToken peek(int n) { 38 | return (LexedToken)this.toks.get(this.i + n); 39 | } 40 | 41 | ImList subToks(String end) { 42 | ArrayList toks = new ArrayList(); 43 | 44 | while(!this.peek(0).what.equals(end)) { 45 | LexedParsedToken t = this.parse(0); 46 | if(t != null) { 47 | toks.add(t); 48 | } 49 | } 50 | 51 | this.next(); 52 | return new ImList(toks); 53 | } 54 | 55 | LexedParsedToken parse(int prec) { 56 | LexedToken t = this.next(); 57 | String w = t.what; 58 | Object var10000; 59 | if(w.equals("(")) { 60 | ImList toks = this.subToks(")"); 61 | var10000 = new BlockToken(t.line, toks); 62 | } else if(!w.equals("\'") && !w.equals("`") && !w.equals(",$") && !w.equals(",")) { 63 | if(this.ignoreComments && t instanceof CommentToken) { 64 | return (LexedParsedToken)null; 65 | } 66 | 67 | var10000 = t; 68 | } else { 69 | ImList al = new ImList(Arrays.asList(new Object[]{this.parse(0)})); 70 | var10000 = !w.equals(",") && !w.equals(",$")?(w.equals("\'")?new SingleQuoteToken(t.line, al):new QuoteToken(t.line, al)):new UnquoteToken(t.line, al, w.equals(",$")); 71 | } 72 | 73 | Object left = var10000; 74 | if(((LexedParsedToken)left).endLine == 0) { 75 | ((LexedParsedToken)left).endLine = this.peek(-1).line; 76 | } 77 | 78 | boolean cont = true; 79 | 80 | while(cont && this.i != this.toks.size() && this.prec() > prec) { 81 | String w1 = this.peek(0).what; 82 | if(w1.equals(":")) { 83 | this.next(); 84 | LexedParsedToken right = this.parse(1); 85 | left = new ColonToken(t.line, (LexedParsedToken)left, right); 86 | } else if(w1.equals("{")) { 87 | this.next(); 88 | ImList toks1 = this.subToks("}"); 89 | left = new GenericToken(t.line, (LexedParsedToken)left, toks1); 90 | } else if(w1.equals("[")) { 91 | this.next(); 92 | ArrayList toks2 = new ArrayList(this.subToks("]")); 93 | toks2.add(0, left); 94 | left = new ArrayToken(t.line, new ImList(toks2)); 95 | } else { 96 | cont = false; 97 | } 98 | 99 | if(cont) { 100 | ((LexedParsedToken)left).endLine = this.peek(-1).line; 101 | } 102 | } 103 | 104 | return (LexedParsedToken)left; 105 | } 106 | 107 | int prec() { 108 | return this.peek(0).prec; 109 | } 110 | 111 | ImList parseAll(List toks) { 112 | this.i = 0; 113 | this.toks = toks; 114 | ArrayList out = new ArrayList(); 115 | 116 | while(this.i != this.toks.size()) { 117 | LexedParsedToken t = this.parse(0); 118 | if(t != null) { 119 | out.add(t); 120 | } 121 | } 122 | 123 | return new ImList(out); 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/Tester.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler; 2 | 3 | import java.io.ByteArrayOutputStream; 4 | import java.io.File; 5 | import java.io.FileFilter; 6 | import java.io.PrintStream; 7 | import org.apache.commons.io.FileUtils; 8 | import org.apache.commons.io.filefilter.WildcardFileFilter; 9 | 10 | public class Tester { 11 | public static void main(String[] args) { 12 | byte exit = 0; 13 | 14 | try { 15 | File dir = new File("examples/"); 16 | WildcardFileFilter fileFilter = new WildcardFileFilter("*.expected.txt"); 17 | File[] files = dir.listFiles((FileFilter)fileFilter); 18 | System.setProperty("line.separator", "\n"); 19 | File[] array = files; 20 | 21 | for(int notused = 0; notused != array.length; ++notused) { 22 | File file = array[notused]; 23 | String fname = file.getName(); 24 | String name = fname.substring(0, fname.indexOf(".")); 25 | StringBuilder sb = new StringBuilder(); 26 | sb.append("examples."); 27 | sb.append(name); 28 | sb.append(".Main"); 29 | Class c = Class.forName(sb.toString()); 30 | ByteArrayOutputStream baos = new ByteArrayOutputStream(); 31 | PrintStream ps = new PrintStream(baos); 32 | PrintStream old = System.out; 33 | System.setOut(ps); 34 | c.getMethod("main", new Class[]{String[].class}).invoke((Object)null, new Object[]{null}); 35 | ps.flush(); 36 | System.setOut(old); 37 | String expected = FileUtils.readFileToString(file); 38 | String out = baos.toString(); 39 | boolean passed = out.equals(expected); 40 | PrintStream var10000 = System.out; 41 | StringBuilder sb1 = new StringBuilder(); 42 | sb1.append(name); 43 | sb1.append(": "); 44 | sb1.append(passed?"PASSED":"FAILED"); 45 | var10000.println(sb1.toString()); 46 | if(!passed) { 47 | exit = 1; 48 | } 49 | } 50 | } catch (Throwable var20) { 51 | var20.printStackTrace(); 52 | System.exit(1); 53 | } 54 | 55 | System.exit(exit); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/VCaptured.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler; 2 | 3 | import gnu.bytecode.CodeAttr; 4 | import gnu.bytecode.Field; 5 | import gnu.bytecode.Type; 6 | import sjava.compiler.AVar; 7 | 8 | public class VCaptured extends AVar { 9 | public Field field; 10 | public AVar avar; 11 | 12 | public VCaptured(AVar avar, Field field) { 13 | super(avar.type); 14 | this.avar = avar; 15 | this.field = field; 16 | } 17 | 18 | public Type load(CodeAttr code) { 19 | boolean output = code != null; 20 | if(output) { 21 | code.emitPushThis(); 22 | } 23 | 24 | if(output) { 25 | code.emitGetField(this.field); 26 | } 27 | 28 | return super.type; 29 | } 30 | 31 | public void store(CodeAttr code) { 32 | throw new RuntimeException(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/Var.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler; 2 | 3 | import gnu.bytecode.CodeAttr; 4 | import gnu.bytecode.Type; 5 | import gnu.bytecode.Variable; 6 | import sjava.compiler.AVar; 7 | 8 | public class Var extends AVar { 9 | Variable var; 10 | 11 | public Var(Variable var, Type type) { 12 | super(type); 13 | this.var = var; 14 | } 15 | 16 | public Type load(CodeAttr code) { 17 | boolean output = code != null; 18 | if(output) { 19 | code.emitLoad(this.var); 20 | } 21 | 22 | return super.type; 23 | } 24 | 25 | public void store(CodeAttr code) { 26 | boolean output = code != null; 27 | if(output) { 28 | code.emitStore(this.var); 29 | } 30 | 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/commands/BuildCommand.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.commands; 2 | 3 | import java.io.File; 4 | import java.util.Arrays; 5 | import java.util.Iterator; 6 | import java.util.List; 7 | import org.apache.commons.cli.CommandLine; 8 | import org.apache.commons.cli.Option; 9 | import sjava.compiler.Main; 10 | import sjava.compiler.commands.Command; 11 | 12 | public class BuildCommand extends Command { 13 | public BuildCommand() { 14 | super.options.addOption(Option.builder("d").hasArg().desc("Output directory for classfiles").build()); 15 | } 16 | 17 | public String name() { 18 | return "build"; 19 | } 20 | 21 | String helpArgs() { 22 | return "[options] [files]"; 23 | } 24 | 25 | public void run(CommandLine commandLine, List args) { 26 | if(args.size() == 0) { 27 | this.printHelp(); 28 | } else { 29 | String dir = commandLine.hasOption("d")?commandLine.getOptionValue("d"):"."; 30 | File[] out = new File[args.size()]; 31 | Iterator it = args.iterator(); 32 | 33 | for(int i = 0; it.hasNext(); ++i) { 34 | String path = (String)it.next(); 35 | out[i] = new File(path); 36 | } 37 | 38 | List files = Arrays.asList(out); 39 | Main.compile(files, dir); 40 | } 41 | 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/commands/Command.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.commands; 2 | 3 | import java.util.List; 4 | import org.apache.commons.cli.CommandLine; 5 | import org.apache.commons.cli.DefaultParser; 6 | import org.apache.commons.cli.HelpFormatter; 7 | import org.apache.commons.cli.Option; 8 | import org.apache.commons.cli.Options; 9 | import org.apache.commons.cli.ParseException; 10 | 11 | public abstract class Command { 12 | public DefaultParser parser = new DefaultParser(); 13 | public Options options = new Options(); 14 | 15 | Command() { 16 | this.options.addOption(Option.builder("h").longOpt("help").build()); 17 | } 18 | 19 | String helpHeader() { 20 | return ""; 21 | } 22 | 23 | String helpFooter() { 24 | return ""; 25 | } 26 | 27 | public void printHelp() { 28 | HelpFormatter var10000 = new HelpFormatter(); 29 | StringBuilder sb = new StringBuilder(); 30 | sb.append("sjava "); 31 | sb.append(this.name()); 32 | sb.append(" "); 33 | sb.append(this.helpArgs()); 34 | var10000.printHelp(sb.toString(), this.helpHeader(), this.options, this.helpFooter()); 35 | } 36 | 37 | public CommandLine parse(String[] args) { 38 | try { 39 | CommandLine var2 = this.parser.parse(this.options, args); 40 | return var2; 41 | } catch (ParseException var4) { 42 | throw new RuntimeException(var4); 43 | } 44 | } 45 | 46 | public abstract String name(); 47 | 48 | abstract String helpArgs(); 49 | 50 | public abstract void run(CommandLine var1, List var2); 51 | } 52 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/commands/FormatCommand.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.commands; 2 | 3 | import java.io.File; 4 | import java.io.PrintStream; 5 | import java.util.Iterator; 6 | import java.util.List; 7 | import org.apache.commons.cli.CommandLine; 8 | import org.apache.commons.io.FileUtils; 9 | import sjava.compiler.Formatter; 10 | import sjava.compiler.commands.Command; 11 | 12 | public class FormatCommand extends Command { 13 | public String name() { 14 | return "fmt"; 15 | } 16 | 17 | String helpArgs() { 18 | return "[files]"; 19 | } 20 | 21 | public void run(CommandLine commandLine, List args) { 22 | List fileNames = args; 23 | if(args.size() == 0) { 24 | this.printHelp(); 25 | } else { 26 | try { 27 | Iterator it = fileNames.iterator(); 28 | 29 | for(int notused = 0; it.hasNext(); ++notused) { 30 | String name = (String)it.next(); 31 | File f = new File(name); 32 | String in = FileUtils.readFileToString(f); 33 | String out = Formatter.formatCode(in); 34 | if(!in.equals(out)) { 35 | PrintStream var10000 = System.out; 36 | StringBuilder sb = new StringBuilder(); 37 | sb.append("Overwriting "); 38 | sb.append(name); 39 | var10000.println(sb.toString()); 40 | FileUtils.writeStringToFile(f, out); 41 | } 42 | } 43 | } catch (Throwable var13) { 44 | var13.printStackTrace(); 45 | } 46 | } 47 | 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/commands/RunCommand.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.commands; 2 | 3 | import gnu.bytecode.ArrayClassLoader; 4 | import java.io.File; 5 | import java.io.PrintStream; 6 | import java.util.Arrays; 7 | import java.util.Collection; 8 | import java.util.Iterator; 9 | import java.util.List; 10 | import org.apache.commons.cli.CommandLine; 11 | import sjava.compiler.ClassInfo; 12 | import sjava.compiler.FileScope; 13 | import sjava.compiler.Main; 14 | import sjava.compiler.commands.Command; 15 | 16 | public class RunCommand extends Command { 17 | public String name() { 18 | return "run"; 19 | } 20 | 21 | String helpArgs() { 22 | return " [files]"; 23 | } 24 | 25 | public void run(CommandLine commandLine, List args) { 26 | if(args.size() < 2) { 27 | this.printHelp(); 28 | } else { 29 | try { 30 | List fileNames = args.subList(1, args.size()); 31 | File[] out = new File[fileNames.size()]; 32 | Iterator it = fileNames.iterator(); 33 | 34 | for(int i = 0; it.hasNext(); ++i) { 35 | String path = (String)it.next(); 36 | out[i] = new File(path); 37 | } 38 | 39 | List files = Arrays.asList(out); 40 | List fileScopes = Main.compile((Collection)files); 41 | ArrayClassLoader cl = Main.getClassLoader(); 42 | ClassInfo found = (ClassInfo)null; 43 | Iterator it1 = fileScopes.iterator(); 44 | 45 | for(int notused = 0; it1.hasNext(); ++notused) { 46 | FileScope fs = (FileScope)it1.next(); 47 | List iterable = fs.newClasses; 48 | Iterator it2 = iterable.iterator(); 49 | 50 | for(int notused1 = 0; it2.hasNext(); ++notused1) { 51 | ClassInfo ci = (ClassInfo)it2.next(); 52 | if(ci.c.getName().equals((String)args.get(0))) { 53 | found = ci; 54 | } 55 | 56 | ci.addToClassLoader(cl); 57 | } 58 | } 59 | 60 | if(found == null) { 61 | PrintStream var10000 = System.out; 62 | StringBuilder sb = new StringBuilder(); 63 | sb.append((String)args.get(0)); 64 | sb.append(" not found"); 65 | var10000.println(sb.toString()); 66 | } else { 67 | found.getClazz(cl).getMethod("main", new Class[]{String[].class}).invoke((Object)null, new Object[]{null}); 68 | } 69 | } catch (Throwable var24) { 70 | var24.printStackTrace(); 71 | } 72 | } 73 | 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/emitters/Emitter.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.emitters; 2 | 3 | import gnu.bytecode.CodeAttr; 4 | import gnu.bytecode.Type; 5 | import java.util.Iterator; 6 | import java.util.List; 7 | import sjava.compiler.handlers.GenHandler; 8 | 9 | public abstract class Emitter { 10 | public static Type[] emitAll(List emitters, GenHandler h, CodeAttr code, Object needed) { 11 | Type[] types = new Type[emitters.size()]; 12 | Iterator it = emitters.iterator(); 13 | 14 | for(int i = 0; it.hasNext(); ++i) { 15 | Emitter emitter = (Emitter)it.next(); 16 | if(emitter != null) { 17 | types[i] = emitter.emit(h, code, needed instanceof Type[]?((Type[])needed)[i]:(Type)needed); 18 | } 19 | } 20 | 21 | return types; 22 | } 23 | 24 | public abstract Type emit(GenHandler var1, CodeAttr var2, Type var3); 25 | } 26 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/emitters/Goto.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.emitters; 2 | 3 | import gnu.bytecode.CodeAttr; 4 | import gnu.bytecode.Label; 5 | import gnu.bytecode.Type; 6 | import sjava.compiler.emitters.Emitter; 7 | import sjava.compiler.handlers.GenHandler; 8 | 9 | public class Goto extends Emitter { 10 | public Label label; 11 | 12 | public Goto(Label label) { 13 | this.label = label; 14 | } 15 | 16 | public Type emit(GenHandler h, CodeAttr code, Type needed) { 17 | boolean output = code != null; 18 | if(output && code.reachableHere()) { 19 | code.emitGoto(this.label); 20 | } 21 | 22 | return Type.voidType; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/emitters/LoadAVar.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.emitters; 2 | 3 | import gnu.bytecode.CodeAttr; 4 | import gnu.bytecode.Type; 5 | import sjava.compiler.AVar; 6 | import sjava.compiler.emitters.Emitter; 7 | import sjava.compiler.handlers.GenHandler; 8 | 9 | public class LoadAVar extends Emitter { 10 | AVar avar; 11 | 12 | public LoadAVar(AVar avar) { 13 | this.avar = avar; 14 | } 15 | 16 | public Type emit(GenHandler h, CodeAttr code, Type needed) { 17 | return this.avar.load(code); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/emitters/Nothing.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.emitters; 2 | 3 | import gnu.bytecode.CodeAttr; 4 | import gnu.bytecode.Type; 5 | import sjava.compiler.emitters.Emitter; 6 | import sjava.compiler.handlers.GenHandler; 7 | 8 | public class Nothing extends Emitter { 9 | public static Nothing inst = new Nothing(); 10 | 11 | public Type emit(GenHandler h, CodeAttr code, Type needed) { 12 | return Type.voidType; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/emitters/Null.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.emitters; 2 | 3 | import gnu.bytecode.CodeAttr; 4 | import gnu.bytecode.Type; 5 | import sjava.compiler.emitters.Emitter; 6 | import sjava.compiler.handlers.GenHandler; 7 | 8 | class Null extends Emitter { 9 | public Type emit(GenHandler h, CodeAttr code, Type needed) { 10 | if(code != null) { 11 | code.emitPushNull(); 12 | } 13 | 14 | return Type.nullType; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/handlers/CaptureVHandler.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.handlers; 2 | 3 | import gnu.bytecode.Access; 4 | import gnu.bytecode.CodeAttr; 5 | import gnu.bytecode.Field; 6 | import gnu.bytecode.Type; 7 | import java.util.Map; 8 | import sjava.compiler.AMethodInfo; 9 | import sjava.compiler.AVar; 10 | import sjava.compiler.VCaptured; 11 | import sjava.compiler.handlers.GenHandler; 12 | import sjava.compiler.tokens.VToken; 13 | 14 | class CaptureVHandler extends GenHandler { 15 | AMethodInfo enc; 16 | Map captured; 17 | int n; 18 | 19 | CaptureVHandler(AMethodInfo mi, AMethodInfo enc, Map captured) { 20 | super(mi); 21 | this.enc = enc; 22 | this.captured = captured; 23 | } 24 | 25 | void assignField(VCaptured vcaptured, CodeAttr code) { 26 | boolean output = code != null; 27 | if(output && vcaptured.field == null) { 28 | Field var4 = super.mi.ci.c.addField("captured$".concat(Integer.toString(this.n)), vcaptured.type, Access.SYNTHETIC); 29 | ++this.n; 30 | vcaptured.field = var4; 31 | this.captured.put(vcaptured.avar, var4); 32 | } 33 | 34 | } 35 | 36 | public Type compile(VToken tok, Type needed) { 37 | boolean output = super.code != null; 38 | AVar found = super.mi.getVar(tok); 39 | if(found instanceof VCaptured) { 40 | this.assignField((VCaptured)found, super.code); 41 | } 42 | 43 | Type var10001; 44 | if(found == null) { 45 | AVar outer = this.enc.getVar(tok); 46 | if(outer == null) { 47 | throw new RuntimeException(tok.toString()); 48 | } 49 | 50 | VCaptured vcaptured = new VCaptured(outer, (Field)null); 51 | this.assignField(vcaptured, super.code); 52 | super.mi.putCapturedVar(tok, vcaptured); 53 | var10001 = vcaptured.load(super.code); 54 | } else { 55 | var10001 = found.load(super.code); 56 | } 57 | 58 | return this.castMaybe(var10001, needed); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/handlers/Handler.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.handlers; 2 | 3 | import gnu.bytecode.Type; 4 | import sjava.compiler.AMethodInfo; 5 | import sjava.compiler.tokens.AGetToken; 6 | import sjava.compiler.tokens.ALenToken; 7 | import sjava.compiler.tokens.ASetToken; 8 | import sjava.compiler.tokens.ArrayConstructorToken; 9 | import sjava.compiler.tokens.AsToken; 10 | import sjava.compiler.tokens.BeginToken; 11 | import sjava.compiler.tokens.CToken; 12 | import sjava.compiler.tokens.CallToken; 13 | import sjava.compiler.tokens.ClassToken; 14 | import sjava.compiler.tokens.CompareToken; 15 | import sjava.compiler.tokens.ConstToken; 16 | import sjava.compiler.tokens.ConstructorToken; 17 | import sjava.compiler.tokens.DefaultToken; 18 | import sjava.compiler.tokens.DefineToken; 19 | import sjava.compiler.tokens.EmptyToken; 20 | import sjava.compiler.tokens.FieldToken; 21 | import sjava.compiler.tokens.GotoToken; 22 | import sjava.compiler.tokens.IfToken; 23 | import sjava.compiler.tokens.ImList; 24 | import sjava.compiler.tokens.IncludeToken; 25 | import sjava.compiler.tokens.InstanceToken; 26 | import sjava.compiler.tokens.LabelToken; 27 | import sjava.compiler.tokens.MacroIncludeToken; 28 | import sjava.compiler.tokens.NToken; 29 | import sjava.compiler.tokens.NumOpToken; 30 | import sjava.compiler.tokens.ObjectToken; 31 | import sjava.compiler.tokens.QuoteToken2; 32 | import sjava.compiler.tokens.ReturnToken; 33 | import sjava.compiler.tokens.SToken; 34 | import sjava.compiler.tokens.SetToken; 35 | import sjava.compiler.tokens.ShiftToken; 36 | import sjava.compiler.tokens.SpecialBeginToken; 37 | import sjava.compiler.tokens.SynchronizedToken; 38 | import sjava.compiler.tokens.ThrowToken; 39 | import sjava.compiler.tokens.Token; 40 | import sjava.compiler.tokens.TryToken; 41 | import sjava.compiler.tokens.TypeToken; 42 | import sjava.compiler.tokens.VToken; 43 | 44 | public abstract class Handler { 45 | AMethodInfo mi; 46 | 47 | Handler(AMethodInfo mi) { 48 | this.mi = mi; 49 | } 50 | 51 | public Type[] compileAll(ImList toks, int i, int e, Object needed) { 52 | int l = toks.size(); 53 | Type[] types = new Type[e - i]; 54 | 55 | for(int j = i; j < e; ++j) { 56 | types[j - i] = this.compile((Token)toks.get(j), needed instanceof Type[]?((Type[])needed)[j - i]:(Type)needed); 57 | } 58 | 59 | return types; 60 | } 61 | 62 | public Type compile(Token tok, Type needed) { 63 | Type var10000; 64 | if(tok instanceof EmptyToken) { 65 | var10000 = this.compile((EmptyToken)tok, needed); 66 | } else if(tok instanceof SToken) { 67 | var10000 = this.compile((SToken)tok, needed); 68 | } else if(tok instanceof CToken) { 69 | var10000 = this.compile((CToken)tok, needed); 70 | } else if(tok instanceof NToken) { 71 | var10000 = this.compile((NToken)tok, needed); 72 | } else if(tok instanceof FieldToken) { 73 | var10000 = this.compile((FieldToken)tok, needed); 74 | } else if(tok instanceof QuoteToken2) { 75 | var10000 = this.compile((QuoteToken2)tok, needed); 76 | } else if(tok instanceof ConstToken) { 77 | var10000 = this.compile((ConstToken)tok, needed); 78 | } else if(tok instanceof VToken) { 79 | var10000 = this.compile((VToken)tok, needed); 80 | } else if(tok instanceof IncludeToken) { 81 | var10000 = this.compile((IncludeToken)tok, needed); 82 | } else if(tok instanceof ObjectToken) { 83 | var10000 = this.compile((ObjectToken)tok, needed); 84 | } else if(tok instanceof MacroIncludeToken) { 85 | var10000 = this.compile((MacroIncludeToken)tok, needed); 86 | } else if(tok instanceof BeginToken) { 87 | var10000 = this.compile((BeginToken)tok, needed); 88 | } else if(tok instanceof SpecialBeginToken) { 89 | var10000 = this.compile((SpecialBeginToken)tok, needed); 90 | } else if(tok instanceof LabelToken) { 91 | var10000 = this.compile((LabelToken)tok, needed); 92 | } else if(tok instanceof GotoToken) { 93 | var10000 = this.compile((GotoToken)tok, needed); 94 | } else if(tok instanceof DefineToken) { 95 | var10000 = this.compile((DefineToken)tok, needed); 96 | } else if(tok instanceof TryToken) { 97 | var10000 = this.compile((TryToken)tok, needed); 98 | } else if(tok instanceof InstanceToken) { 99 | var10000 = this.compile((InstanceToken)tok, needed); 100 | } else if(tok instanceof SetToken) { 101 | var10000 = this.compile((SetToken)tok, needed); 102 | } else if(tok instanceof ASetToken) { 103 | var10000 = this.compile((ASetToken)tok, needed); 104 | } else if(tok instanceof AGetToken) { 105 | var10000 = this.compile((AGetToken)tok, needed); 106 | } else if(tok instanceof ALenToken) { 107 | var10000 = this.compile((ALenToken)tok, needed); 108 | } else if(tok instanceof AsToken) { 109 | var10000 = this.compile((AsToken)tok, needed); 110 | } else if(tok instanceof NumOpToken) { 111 | var10000 = this.compile((NumOpToken)tok, needed); 112 | } else if(tok instanceof ShiftToken) { 113 | var10000 = this.compile((ShiftToken)tok, needed); 114 | } else if(tok instanceof IfToken) { 115 | var10000 = this.compile((IfToken)tok, needed); 116 | } else if(tok instanceof CompareToken) { 117 | var10000 = this.compile((CompareToken)tok, needed); 118 | } else if(tok instanceof ThrowToken) { 119 | var10000 = this.compile((ThrowToken)tok, needed); 120 | } else if(tok instanceof ClassToken) { 121 | var10000 = this.compile((ClassToken)tok, needed); 122 | } else if(tok instanceof SynchronizedToken) { 123 | var10000 = this.compile((SynchronizedToken)tok, needed); 124 | } else if(tok instanceof TypeToken) { 125 | var10000 = this.compile((TypeToken)tok, needed); 126 | } else if(tok instanceof ReturnToken) { 127 | var10000 = this.compile((ReturnToken)tok, needed); 128 | } else if(tok instanceof CallToken) { 129 | var10000 = this.compile((CallToken)tok, needed); 130 | } else if(tok instanceof DefaultToken) { 131 | var10000 = this.compile((DefaultToken)tok, needed); 132 | } else if(tok instanceof ConstructorToken) { 133 | var10000 = this.compile((ConstructorToken)tok, needed); 134 | } else { 135 | if(!(tok instanceof ArrayConstructorToken)) { 136 | StringBuilder sb = new StringBuilder(); 137 | sb.append("Double dispatch with "); 138 | sb.append(tok); 139 | throw new RuntimeException(sb.toString()); 140 | } 141 | 142 | var10000 = this.compile((ArrayConstructorToken)tok, needed); 143 | } 144 | 145 | return var10000; 146 | } 147 | 148 | public abstract Type compile(EmptyToken var1, Type var2); 149 | 150 | public abstract Type compile(SToken var1, Type var2); 151 | 152 | public abstract Type compile(CToken var1, Type var2); 153 | 154 | public abstract Type compile(NToken var1, Type var2); 155 | 156 | public abstract Type compile(FieldToken var1, Type var2); 157 | 158 | public abstract Type compile(QuoteToken2 var1, Type var2); 159 | 160 | public abstract Type compile(ConstToken var1, Type var2); 161 | 162 | public abstract Type compile(VToken var1, Type var2); 163 | 164 | public abstract Type compile(IncludeToken var1, Type var2); 165 | 166 | public abstract Type compile(ObjectToken var1, Type var2); 167 | 168 | public abstract Type compile(MacroIncludeToken var1, Type var2); 169 | 170 | public abstract Type compile(BeginToken var1, Type var2); 171 | 172 | public abstract Type compile(SpecialBeginToken var1, Type var2); 173 | 174 | public abstract Type compile(LabelToken var1, Type var2); 175 | 176 | public abstract Type compile(GotoToken var1, Type var2); 177 | 178 | public abstract Type compile(DefineToken var1, Type var2); 179 | 180 | public abstract Type compile(TryToken var1, Type var2); 181 | 182 | public abstract Type compile(InstanceToken var1, Type var2); 183 | 184 | public abstract Type compile(SetToken var1, Type var2); 185 | 186 | public abstract Type compile(ASetToken var1, Type var2); 187 | 188 | public abstract Type compile(AGetToken var1, Type var2); 189 | 190 | public abstract Type compile(ALenToken var1, Type var2); 191 | 192 | public abstract Type compile(AsToken var1, Type var2); 193 | 194 | public abstract Type compile(NumOpToken var1, Type var2); 195 | 196 | public abstract Type compile(ShiftToken var1, Type var2); 197 | 198 | public abstract Type compile(IfToken var1, Type var2); 199 | 200 | public abstract Type compile(CompareToken var1, Type var2); 201 | 202 | public abstract Type compile(ThrowToken var1, Type var2); 203 | 204 | public abstract Type compile(ClassToken var1, Type var2); 205 | 206 | public abstract Type compile(SynchronizedToken var1, Type var2); 207 | 208 | public abstract Type compile(TypeToken var1, Type var2); 209 | 210 | public abstract Type compile(ReturnToken var1, Type var2); 211 | 212 | public abstract Type compile(CallToken var1, Type var2); 213 | 214 | public abstract Type compile(DefaultToken var1, Type var2); 215 | 216 | public abstract Type compile(ConstructorToken var1, Type var2); 217 | 218 | public abstract Type compile(ArrayConstructorToken var1, Type var2); 219 | 220 | public abstract Type castMaybe(Type var1, Type var2); 221 | } 222 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/mfilters/AFilter.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.mfilters; 2 | 3 | import gnu.bytecode.ArrayType; 4 | import gnu.bytecode.ClassType; 5 | import gnu.bytecode.Method; 6 | import gnu.bytecode.Type; 7 | import java.util.HashSet; 8 | import java.util.Iterator; 9 | import java.util.LinkedHashSet; 10 | import sjava.compiler.Main; 11 | 12 | public abstract class AFilter { 13 | Type pt; 14 | HashSet foundSigs; 15 | 16 | AFilter(Type pt) { 17 | this.pt = pt; 18 | this.foundSigs = new HashSet(); 19 | } 20 | 21 | void search(Type t) { 22 | for(Method m = ((ClassType)t.getRawType()).getDeclaredMethods(); m != null; m = m.getNext()) { 23 | StringBuilder sb = new StringBuilder(); 24 | sb.append(m.getName()); 25 | sb.append(m.getSignature()); 26 | String msig = sb.toString(); 27 | if(!this.foundSigs.contains(msig)) { 28 | this.foundSigs.add(msig); 29 | this.select(m, t); 30 | } 31 | } 32 | 33 | } 34 | 35 | public void searchAll() { 36 | if(this.pt instanceof ArrayType) { 37 | this.searchArray(); 38 | } else { 39 | LinkedHashSet iterable = Main.superTypes(this.pt); 40 | Iterator it = iterable.iterator(); 41 | 42 | for(int notused = 0; it.hasNext(); ++notused) { 43 | Type t = (Type)it.next(); 44 | this.search(t); 45 | } 46 | } 47 | 48 | } 49 | 50 | public void searchDeclared() { 51 | this.search(this.pt); 52 | } 53 | 54 | void searchArray() { 55 | this.search(Type.objectType); 56 | } 57 | 58 | abstract void select(Method var1, Type var2); 59 | } 60 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/mfilters/BridgeFilter.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.mfilters; 2 | 3 | import gnu.bytecode.Method; 4 | import gnu.bytecode.Type; 5 | import sjava.compiler.Main; 6 | import sjava.compiler.mfilters.AFilter; 7 | 8 | public class BridgeFilter extends AFilter { 9 | Method m; 10 | 11 | public BridgeFilter(Method m) { 12 | super(m.getDeclaringClass()); 13 | this.m = m; 14 | } 15 | 16 | void select(Method method, Type generic) { 17 | Type[] p1 = this.m.getGenericParameterTypes(); 18 | Type[] p2 = method.getGenericParameterTypes(); 19 | Type r1 = this.m.getReturnType(); 20 | Type r2 = method.getReturnType(); 21 | if(method.getName().equals(this.m.getName()) && p1.length == p2.length && !Type.isSame(generic, super.pt)) { 22 | int n = p1.length; 23 | boolean diff = !Type.isSame(r1.getRawType(), r2.getRawType()); 24 | boolean overrides = true; 25 | 26 | for(int i = 0; overrides && i != n; ++i) { 27 | if(!diff && !Type.isSame(p1[i].getRawType(), p2[i].getRawType())) { 28 | diff = true; 29 | } 30 | 31 | overrides = Type.isSame(Main.resolveType(generic, p1[i]), Main.resolveType(generic, p2[i])); 32 | } 33 | 34 | if(diff && overrides) { 35 | Main.generateBridgeMethod(this.m, p2, r2); 36 | } 37 | } 38 | 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/mfilters/MFilter.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.mfilters; 2 | 3 | import gnu.bytecode.Access; 4 | import gnu.bytecode.ArrayType; 5 | import gnu.bytecode.ClassType; 6 | import gnu.bytecode.Method; 7 | import gnu.bytecode.PrimType; 8 | import gnu.bytecode.Type; 9 | import gnu.bytecode.TypeVariable; 10 | import java.util.ArrayList; 11 | import java.util.Iterator; 12 | import java.util.Map; 13 | import sjava.compiler.Main; 14 | import sjava.compiler.mfilters.AFilter; 15 | import sjava.compiler.mfilters.MethodCall; 16 | 17 | public class MFilter extends AFilter { 18 | ArrayList methods = new ArrayList(); 19 | String name; 20 | Type[] types; 21 | boolean static_; 22 | 23 | public MFilter(String name, Type[] types, Type pt, boolean static_) { 24 | super(pt); 25 | this.name = name; 26 | this.types = types; 27 | this.static_ = static_; 28 | } 29 | 30 | void select(Method method, Type generic) { 31 | ClassType c = method.getDeclaringClass(); 32 | if(method.getName().equals(this.name) && method.getStaticFlag() == this.static_ && (!c.isInterface() || ((ClassType)generic.getRawType()).isInterface() || !method.isAbstract()) && 0 == (method.getModifiers() & Access.SYNTHETIC)) { 33 | MethodCall mc = isCompatible(method, generic, this.types); 34 | if(mc != null) { 35 | this.methods.add(mc); 36 | } 37 | } 38 | 39 | } 40 | 41 | public MethodCall getMethodCall() { 42 | ArrayList iterable = this.methods; 43 | Iterator it = iterable.iterator(); 44 | 45 | for(int notused = 0; it.hasNext(); ++notused) { 46 | MethodCall method = (MethodCall)it.next(); 47 | if(method.mostSpecific(this.methods)) { 48 | return method; 49 | } 50 | } 51 | 52 | return (MethodCall)null; 53 | } 54 | 55 | public Method getMethod() { 56 | MethodCall mc = this.getMethodCall(); 57 | return mc == null?(Method)null:mc.m; 58 | } 59 | 60 | public static MethodCall isCompatible(Method method, Type generic, Type[] types) { 61 | boolean varargs = (method.getModifiers() & Access.TRANSIENT) != 0; 62 | int na = types.length; 63 | Type[] params = method.getGenericParameterTypes(); 64 | int np = params.length; 65 | MethodCall var21; 66 | if(na != np && (!varargs || na < np - 1)) { 67 | var21 = (MethodCall)null; 68 | } else { 69 | boolean arrayNeeded = varargs && (na == np - 1 || Main.arrayDim(params[np - 1]) != Main.arrayDim(types[np - 1])); 70 | Type[] var10000; 71 | if(arrayNeeded) { 72 | Type[] ntypes = new Type[np]; 73 | boolean var9 = na == np - 1; 74 | System.arraycopy(types, 0, ntypes, 0, np - 1); 75 | ntypes[np - 1] = (Type)(var9?params[np - 1]:new ArrayType(types[np - 1])); 76 | var10000 = ntypes; 77 | } else { 78 | var10000 = types; 79 | } 80 | 81 | Type[] reals = var10000; 82 | TypeVariable[] var20; 83 | if(method.getName().equals("")) { 84 | TypeVariable[] ctparams = ((ClassType)generic.getRawType()).getTypeParameters(); 85 | TypeVariable[] mtparams = method.getTypeParameters(); 86 | if(ctparams == null) { 87 | var20 = mtparams; 88 | } else if(mtparams == null) { 89 | var20 = ctparams; 90 | } else { 91 | TypeVariable[] o = new TypeVariable[ctparams.length + mtparams.length]; 92 | System.arraycopy(ctparams, 0, o, 0, ctparams.length); 93 | System.arraycopy(mtparams, 0, o, ctparams.length, mtparams.length); 94 | var20 = o; 95 | } 96 | } else { 97 | var20 = method.getTypeParameters(); 98 | } 99 | 100 | TypeVariable[] tparams = var20; 101 | Map tvs = Main.unresolveTvs(tparams, params, reals); 102 | boolean stop = false; 103 | 104 | for(int i = 0; !stop && i != types.length; ++i) { 105 | Type at = Main.resolveType(tvs, generic, arrayNeeded && i >= np - 1?((ArrayType)params[np - 1]).elements:params[i]); 106 | int level = Main.compare(at, types[i]); 107 | if(level < 0 || types[i] == Type.nullType && at instanceof PrimType) { 108 | stop = true; 109 | } 110 | } 111 | 112 | var21 = !stop?new MethodCall(method, generic, tvs, types):(MethodCall)null; 113 | } 114 | 115 | return var21; 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/mfilters/MethodCall.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.mfilters; 2 | 3 | import gnu.bytecode.Method; 4 | import gnu.bytecode.Type; 5 | import gnu.bytecode.TypeVariable; 6 | import java.util.Iterator; 7 | import java.util.List; 8 | import java.util.Map; 9 | import sjava.compiler.Main; 10 | 11 | public class MethodCall { 12 | public Method m; 13 | public Type t; 14 | public Map tvs; 15 | public Type[] types; 16 | 17 | MethodCall(Method m, Type t, Map tvs, Type[] types) { 18 | this.m = m; 19 | this.t = t; 20 | this.tvs = tvs; 21 | this.types = types; 22 | } 23 | 24 | boolean moreSpecific(MethodCall o) { 25 | Type[] as = this.m.getGenericParameterTypes(); 26 | Type[] bs = o.m.getGenericParameterTypes(); 27 | int n = Math.min(as.length, bs.length); 28 | boolean good = false; 29 | 30 | for(int i = 0; i < n; ++i) { 31 | Type a = Main.resolveType(this.tvs, this.t, as[i]); 32 | Type b = Main.resolveType(o.tvs, o.t, bs[i]); 33 | int comp = Main.compare(b, a); 34 | if(comp == 1) { 35 | good = true; 36 | } else if(comp < 0) { 37 | return false; 38 | } 39 | } 40 | 41 | return good || bs.length >= as.length; 42 | } 43 | 44 | boolean mostSpecific(List methods) { 45 | Iterator it = methods.iterator(); 46 | 47 | for(int notused = 0; it.hasNext(); ++notused) { 48 | MethodCall method = (MethodCall)it.next(); 49 | if(!this.moreSpecific(method)) { 50 | return false; 51 | } 52 | } 53 | 54 | return true; 55 | } 56 | 57 | public String toString() { 58 | return this.m.toString(); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/tokens/AGetToken.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.tokens; 2 | 3 | import sjava.compiler.tokens.ImList; 4 | import sjava.compiler.tokens.Token; 5 | 6 | public class AGetToken extends Token { 7 | public ImList toks; 8 | 9 | public AGetToken(int line, ImList toks) { 10 | super(line); 11 | this.toks = toks; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/tokens/ALenToken.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.tokens; 2 | 3 | import sjava.compiler.tokens.Token; 4 | 5 | public class ALenToken extends Token { 6 | public Token tok; 7 | 8 | public ALenToken(int line, Token tok) { 9 | super(line); 10 | this.tok = tok; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/tokens/ASetToken.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.tokens; 2 | 3 | import sjava.compiler.tokens.Token; 4 | 5 | public class ASetToken extends Token { 6 | public Token array; 7 | public Token index; 8 | public Token el; 9 | 10 | public ASetToken(int line, Token array, Token index, Token el) { 11 | super(line); 12 | this.array = array; 13 | this.index = index; 14 | this.el = el; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/tokens/ArrayConstructorToken.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.tokens; 2 | 3 | import gnu.bytecode.Type; 4 | import sjava.compiler.tokens.ImList; 5 | import sjava.compiler.tokens.Token; 6 | 7 | public class ArrayConstructorToken extends Token { 8 | public Type type; 9 | public ImList lens; 10 | public ImList toks; 11 | 12 | public ArrayConstructorToken(int line, Type type, ImList lens, ImList toks) { 13 | super(line); 14 | this.type = type; 15 | this.lens = lens; 16 | this.toks = toks; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/tokens/ArrayToken.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.tokens; 2 | 3 | import sjava.compiler.tokens.ImList; 4 | import sjava.compiler.tokens.LexedParsedToken; 5 | import sjava.compiler.tokens.ParsedToken; 6 | import sjava.compiler.tokens.Token; 7 | 8 | public class ArrayToken extends ParsedToken { 9 | public ImList toks; 10 | 11 | public ArrayToken(int line, ImList toks) { 12 | super(line); 13 | this.toks = new ImList(toks); 14 | } 15 | 16 | public String toString() { 17 | StringBuilder sb = new StringBuilder(); 18 | sb.append((LexedParsedToken)this.toks.get(0)); 19 | sb.append("["); 20 | sb.append(Token.toksString(this.toks.skip(1))); 21 | sb.append("]"); 22 | return sb.toString(); 23 | } 24 | 25 | public ArrayToken() { 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/tokens/AsToken.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.tokens; 2 | 3 | import gnu.bytecode.Type; 4 | import sjava.compiler.tokens.Token; 5 | 6 | public class AsToken extends Token { 7 | public Type type; 8 | public Token tok; 9 | 10 | public AsToken(int line, Type type, Token tok) { 11 | super(line); 12 | this.type = type; 13 | this.tok = tok; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/tokens/BeginToken.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.tokens; 2 | 3 | import sjava.compiler.tokens.BlockToken2; 4 | import sjava.compiler.tokens.ImList; 5 | import sjava.compiler.tokens.Token; 6 | 7 | public class BeginToken extends BlockToken2 { 8 | public BeginToken(int line, ImList toks) { 9 | super(line, toks); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/tokens/BlockToken.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.tokens; 2 | 3 | import sjava.compiler.tokens.ImList; 4 | import sjava.compiler.tokens.LexedParsedToken; 5 | import sjava.compiler.tokens.ParsedToken; 6 | import sjava.compiler.tokens.Token; 7 | 8 | public class BlockToken extends ParsedToken { 9 | public ImList toks; 10 | 11 | public BlockToken(int line, ImList toks) { 12 | super(line); 13 | this.toks = new ImList(toks); 14 | } 15 | 16 | public String toString() { 17 | StringBuilder sb = new StringBuilder(); 18 | sb.append("("); 19 | sb.append(Token.toksString(this.toks)); 20 | sb.append(")"); 21 | return sb.toString(); 22 | } 23 | 24 | public int firstLine() { 25 | return this.toks.size() == 0?super.line:((LexedParsedToken)this.toks.get(0)).firstLine(); 26 | } 27 | 28 | public int lastLine() { 29 | return this.toks.size() == 0?super.line:((LexedParsedToken)this.toks.get(this.toks.size() - 1)).lastLine(); 30 | } 31 | 32 | public BlockToken() { 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/tokens/BlockToken2.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.tokens; 2 | 3 | import java.util.HashMap; 4 | import sjava.compiler.tokens.ImList; 5 | import sjava.compiler.tokens.Token; 6 | 7 | public class BlockToken2 extends Token { 8 | public ImList toks; 9 | public HashMap labels; 10 | public boolean isTransformed; 11 | 12 | public BlockToken2(int line, ImList toks) { 13 | super(line); 14 | this.toks = toks; 15 | this.labels = new HashMap(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/tokens/CToken.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.tokens; 2 | 3 | import java.util.Iterator; 4 | import java.util.Set; 5 | import java.util.Map.Entry; 6 | import sjava.compiler.Main; 7 | import sjava.compiler.tokens.LexedToken; 8 | 9 | public class CToken extends LexedToken { 10 | public Character val; 11 | 12 | public CToken(int line, Character val) { 13 | super(line); 14 | this.val = val; 15 | } 16 | 17 | public String toString() { 18 | String c = this.val.toString(); 19 | Set iterable = Main.specialChars.entrySet(); 20 | Iterator it = iterable.iterator(); 21 | 22 | for(int notused = 0; it.hasNext(); ++notused) { 23 | Entry entry = (Entry)it.next(); 24 | if(this.val.equals((Character)entry.getValue())) { 25 | c = (String)entry.getKey(); 26 | } 27 | } 28 | 29 | StringBuilder sb = new StringBuilder(); 30 | sb.append("#\\"); 31 | sb.append(c); 32 | return sb.toString(); 33 | } 34 | 35 | public CToken() { 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/tokens/CallToken.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.tokens; 2 | 3 | import sjava.compiler.tokens.ImList; 4 | import sjava.compiler.tokens.Token; 5 | 6 | public class CallToken extends Token { 7 | public Token target; 8 | public String method; 9 | public ImList toks; 10 | 11 | public CallToken(int line, Token target, String method, ImList toks) { 12 | super(line); 13 | this.target = target; 14 | this.method = method; 15 | this.toks = toks; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/tokens/ClassToken.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.tokens; 2 | 3 | import gnu.bytecode.Type; 4 | import sjava.compiler.tokens.Token; 5 | 6 | public class ClassToken extends Token { 7 | public Type type; 8 | 9 | public ClassToken(int line, Type type) { 10 | super(line); 11 | this.type = type; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/tokens/ColonToken.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.tokens; 2 | 3 | import sjava.compiler.tokens.LexedParsedToken; 4 | import sjava.compiler.tokens.ParsedToken; 5 | 6 | public class ColonToken extends ParsedToken { 7 | public LexedParsedToken left; 8 | public LexedParsedToken right; 9 | 10 | public ColonToken(int line, LexedParsedToken left, LexedParsedToken right) { 11 | super(line); 12 | this.left = left; 13 | this.right = right; 14 | } 15 | 16 | public String toString() { 17 | StringBuilder sb = new StringBuilder(); 18 | sb.append(this.left); 19 | sb.append(":"); 20 | sb.append(this.right); 21 | return sb.toString(); 22 | } 23 | 24 | public int firstLine() { 25 | return this.left.firstLine(); 26 | } 27 | 28 | public ColonToken() { 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/tokens/CommentToken.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.tokens; 2 | 3 | import sjava.compiler.tokens.LexedToken; 4 | 5 | public class CommentToken extends LexedToken { 6 | public String val; 7 | 8 | public CommentToken(int line, String val) { 9 | super(line); 10 | this.val = val; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/tokens/CompareToken.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.tokens; 2 | 3 | import sjava.compiler.tokens.ImList; 4 | import sjava.compiler.tokens.Token; 5 | 6 | public class CompareToken extends Token { 7 | public String compare; 8 | public ImList toks; 9 | 10 | public CompareToken(int line, String compare, ImList toks) { 11 | super(line); 12 | this.compare = compare; 13 | this.toks = toks; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/tokens/ConstToken.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.tokens; 2 | 3 | import sjava.compiler.tokens.LexedToken; 4 | 5 | public class ConstToken extends LexedToken { 6 | public String val; 7 | 8 | public ConstToken(int line, String val) { 9 | super(line); 10 | this.val = val; 11 | } 12 | 13 | public String toString() { 14 | return this.val; 15 | } 16 | 17 | public ConstToken() { 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/tokens/ConstructorToken.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.tokens; 2 | 3 | import gnu.bytecode.Type; 4 | import sjava.compiler.tokens.ImList; 5 | import sjava.compiler.tokens.Token; 6 | 7 | public class ConstructorToken extends Token { 8 | public Type type; 9 | public ImList toks; 10 | 11 | public ConstructorToken(int line, Type type, ImList toks) { 12 | super(line); 13 | this.type = type; 14 | this.toks = toks; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/tokens/DefaultToken.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.tokens; 2 | 3 | import sjava.compiler.tokens.ImList; 4 | import sjava.compiler.tokens.Token; 5 | 6 | public class DefaultToken extends Token { 7 | public ImList toks; 8 | 9 | public DefaultToken(int line, ImList toks) { 10 | super(line); 11 | this.toks = toks; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/tokens/DefineToken.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.tokens; 2 | 3 | import gnu.bytecode.Type; 4 | import sjava.compiler.tokens.Token; 5 | import sjava.compiler.tokens.VToken; 6 | 7 | public class DefineToken extends Token { 8 | public VToken name; 9 | public Type type; 10 | public Token tok; 11 | 12 | public DefineToken(int line, VToken name, Type type, Token tok) { 13 | super(line); 14 | this.name = name; 15 | this.type = type; 16 | this.tok = tok; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/tokens/EmptyToken.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.tokens; 2 | 3 | import java.util.Collections; 4 | import sjava.compiler.tokens.BlockToken2; 5 | import sjava.compiler.tokens.ImList; 6 | 7 | public class EmptyToken extends BlockToken2 { 8 | public EmptyToken(int line) { 9 | super(line, new ImList(Collections.EMPTY_LIST)); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/tokens/FieldToken.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.tokens; 2 | 3 | import sjava.compiler.tokens.Token; 4 | 5 | public class FieldToken extends Token { 6 | public Token left; 7 | public String right; 8 | 9 | public FieldToken(int line, Token left, String right) { 10 | super(line); 11 | this.left = left; 12 | this.right = right; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/tokens/GenericToken.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.tokens; 2 | 3 | import sjava.compiler.tokens.ImList; 4 | import sjava.compiler.tokens.LexedParsedToken; 5 | import sjava.compiler.tokens.ParsedToken; 6 | import sjava.compiler.tokens.Token; 7 | 8 | public class GenericToken extends ParsedToken { 9 | public LexedParsedToken tok; 10 | public ImList toks; 11 | 12 | public GenericToken(int line, LexedParsedToken tok, ImList toks) { 13 | super(line); 14 | this.tok = tok; 15 | this.toks = toks; 16 | } 17 | 18 | public String toString() { 19 | StringBuilder sb = new StringBuilder(); 20 | sb.append(this.tok); 21 | sb.append("{"); 22 | sb.append(Token.toksString(this.toks)); 23 | sb.append("}"); 24 | return sb.toString(); 25 | } 26 | 27 | public GenericToken() { 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/tokens/GotoToken.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.tokens; 2 | 3 | import sjava.compiler.tokens.Token; 4 | 5 | public class GotoToken extends Token { 6 | public String label; 7 | 8 | public GotoToken(int line, String label) { 9 | super(line); 10 | this.label = label; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/tokens/IfToken.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.tokens; 2 | 3 | import sjava.compiler.tokens.ImList; 4 | import sjava.compiler.tokens.Token; 5 | 6 | public class IfToken extends Token { 7 | public ImList toks; 8 | 9 | public IfToken(int line, ImList toks) { 10 | super(line); 11 | this.toks = toks; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/tokens/ImList.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.tokens; 2 | 3 | import java.util.AbstractList; 4 | import java.util.ArrayList; 5 | import java.util.Collections; 6 | import java.util.Iterator; 7 | import java.util.List; 8 | 9 | public class ImList extends AbstractList { 10 | public static ImList EMPTY_LIST; 11 | List l; 12 | int i; 13 | int sz; 14 | 15 | static { 16 | EMPTY_LIST = new ImList(Collections.EMPTY_LIST); 17 | } 18 | 19 | public ImList(List l, int i, int sz) { 20 | this.l = Collections.unmodifiableList(l); 21 | this.i = i; 22 | this.sz = sz; 23 | if(i < 0 || sz < 0 || i + sz > l.size()) { 24 | throw new RuntimeException(); 25 | } 26 | } 27 | 28 | public ImList(List l, int i) { 29 | this(l, i, l.size()); 30 | } 31 | 32 | public ImList(List l) { 33 | this(l, 0); 34 | } 35 | 36 | public ImList skip(int k) { 37 | return new ImList(this.l, this.i + k, this.sz - k); 38 | } 39 | 40 | public ImList take(int k) { 41 | return new ImList(this.l, this.i, k); 42 | } 43 | 44 | public ImList skipLast(int k) { 45 | return new ImList(this.l, this.i, this.sz - k); 46 | } 47 | 48 | public T get(int i) { 49 | if(i >= 0 && i < this.sz) { 50 | return this.l.get(this.i + i); 51 | } else { 52 | throw new RuntimeException(); 53 | } 54 | } 55 | 56 | public ImList update(int i, T el) { 57 | if(i >= 0 && i < this.sz) { 58 | ArrayList l = new ArrayList(this.l); 59 | l.set(this.i + i, el); 60 | return new ImList(l, this.i, this.sz); 61 | } else { 62 | throw new RuntimeException(); 63 | } 64 | } 65 | 66 | public int size() { 67 | return this.sz; 68 | } 69 | 70 | public Iterator iterator() { 71 | return this.l.subList(this.i, this.i + this.sz).iterator(); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/tokens/IncludeToken.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.tokens; 2 | 3 | import sjava.compiler.AMethodInfo; 4 | import sjava.compiler.tokens.ImList; 5 | import sjava.compiler.tokens.LexedParsedToken; 6 | import sjava.compiler.tokens.Token; 7 | 8 | public class IncludeToken extends Token { 9 | public AMethodInfo mi; 10 | public Token ret; 11 | public ImList toks; 12 | 13 | public IncludeToken(int line, ImList toks) { 14 | super(line); 15 | this.toks = toks; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/tokens/InstanceToken.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.tokens; 2 | 3 | import gnu.bytecode.Type; 4 | import sjava.compiler.tokens.Token; 5 | 6 | public class InstanceToken extends Token { 7 | public Token tok; 8 | public Type type; 9 | 10 | public InstanceToken(int line, Token tok, Type type) { 11 | super(line); 12 | this.tok = tok; 13 | this.type = type; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/tokens/LabelToken.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.tokens; 2 | 3 | import sjava.compiler.tokens.Token; 4 | 5 | public class LabelToken extends Token { 6 | public String label; 7 | 8 | public LabelToken(int line, String label) { 9 | super(line); 10 | this.label = label; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/tokens/LambdaFnToken.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.tokens; 2 | 3 | import gnu.bytecode.Type; 4 | import java.util.LinkedHashMap; 5 | import java.util.List; 6 | import sjava.compiler.tokens.ImList; 7 | import sjava.compiler.tokens.LexedParsedToken; 8 | import sjava.compiler.tokens.ObjectToken; 9 | 10 | public class LambdaFnToken extends ObjectToken { 11 | public Type ret; 12 | public LinkedHashMap scope; 13 | public List params; 14 | 15 | public LambdaFnToken(int line, Type t, LinkedHashMap scope, List params, ImList toks) { 16 | super(line, t, ImList.EMPTY_LIST, toks); 17 | this.scope = scope; 18 | this.params = params; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/tokens/LambdaToken.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.tokens; 2 | 3 | import gnu.bytecode.Method; 4 | import gnu.bytecode.Type; 5 | import java.util.Collections; 6 | import java.util.LinkedHashMap; 7 | import java.util.List; 8 | import sjava.compiler.tokens.ImList; 9 | import sjava.compiler.tokens.LexedParsedToken; 10 | import sjava.compiler.tokens.ObjectToken; 11 | 12 | public class LambdaToken extends ObjectToken { 13 | public Method sam; 14 | public LinkedHashMap scope; 15 | public List params; 16 | 17 | public LambdaToken(int line, Type t, LinkedHashMap scope, List params, ImList toks, Method sam) { 18 | super(line, t, new ImList(Collections.EMPTY_LIST), toks); 19 | this.scope = scope; 20 | this.params = params; 21 | this.sam = sam; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/tokens/LexedParsedToken.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.tokens; 2 | 3 | import sjava.compiler.tokens.Token; 4 | 5 | public class LexedParsedToken extends Token { 6 | public int endLine; 7 | public transient Token transformed; 8 | 9 | public LexedParsedToken(int line) { 10 | super(line); 11 | } 12 | 13 | public int firstLine() { 14 | return super.line; 15 | } 16 | 17 | public int lastLine() { 18 | return this.endLine; 19 | } 20 | 21 | public String toStringParsed() { 22 | return this.toString(); 23 | } 24 | 25 | public LexedParsedToken() { 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/tokens/LexedToken.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.tokens; 2 | 3 | import sjava.compiler.tokens.LexedParsedToken; 4 | 5 | public class LexedToken extends LexedParsedToken { 6 | public transient int prec; 7 | public String what; 8 | 9 | public LexedToken(int line) { 10 | super(line); 11 | this.what = ""; 12 | } 13 | 14 | public LexedToken(int line, int prec, String what) { 15 | this(line); 16 | this.prec = prec; 17 | this.what = what; 18 | } 19 | 20 | public String toString() { 21 | return this.what; 22 | } 23 | 24 | public LexedToken() { 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/tokens/MacroIncludeToken.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.tokens; 2 | 3 | import sjava.compiler.tokens.ImList; 4 | import sjava.compiler.tokens.LexedParsedToken; 5 | import sjava.compiler.tokens.Token; 6 | 7 | public class MacroIncludeToken extends Token { 8 | public Token ret; 9 | public String name; 10 | public ImList toks; 11 | 12 | public MacroIncludeToken(int line, String name, ImList toks) { 13 | super(line); 14 | this.name = name; 15 | this.toks = toks; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/tokens/NToken.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.tokens; 2 | 3 | import org.apache.commons.lang3.math.NumberUtils; 4 | import sjava.compiler.tokens.LexedToken; 5 | 6 | public class NToken extends LexedToken { 7 | public Number val; 8 | public String sval; 9 | 10 | public NToken(int line, String sval) { 11 | super(line); 12 | this.sval = sval; 13 | if(sval.contains(".") && !Character.isLetter(sval.charAt(sval.length() - 1))) { 14 | StringBuilder sb = new StringBuilder(); 15 | sb.append(sval); 16 | sb.append("d"); 17 | sval = sb.toString(); 18 | } 19 | 20 | this.val = NumberUtils.createNumber(sval); 21 | } 22 | 23 | public String toString() { 24 | return this.sval; 25 | } 26 | 27 | public NToken() { 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/tokens/NumOpToken.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.tokens; 2 | 3 | import sjava.compiler.tokens.ImList; 4 | import sjava.compiler.tokens.Token; 5 | 6 | public class NumOpToken extends Token { 7 | public String op; 8 | public ImList toks; 9 | 10 | public NumOpToken(int line, String op, ImList toks) { 11 | super(line); 12 | this.op = op; 13 | this.toks = toks; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/tokens/ObjectToken.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.tokens; 2 | 3 | import gnu.bytecode.Type; 4 | import java.util.Collection; 5 | import sjava.compiler.AVar; 6 | import sjava.compiler.ClassInfo; 7 | import sjava.compiler.tokens.ImList; 8 | import sjava.compiler.tokens.LexedParsedToken; 9 | import sjava.compiler.tokens.Token; 10 | 11 | public class ObjectToken extends Token { 12 | public ClassInfo ci; 13 | public Collection captured; 14 | public Type t; 15 | public ImList toks; 16 | public ImList superArgs; 17 | 18 | public ObjectToken(int line, Type t, ImList superArgs, ImList toks) { 19 | super(line); 20 | this.t = t; 21 | this.superArgs = superArgs; 22 | this.toks = toks; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/tokens/ParsedToken.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.tokens; 2 | 3 | import sjava.compiler.tokens.LexedParsedToken; 4 | 5 | public class ParsedToken extends LexedParsedToken { 6 | public ParsedToken(int line) { 7 | super(line); 8 | } 9 | 10 | public ParsedToken() { 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/tokens/QuoteToken.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.tokens; 2 | 3 | import sjava.compiler.tokens.ImList; 4 | import sjava.compiler.tokens.LexedParsedToken; 5 | import sjava.compiler.tokens.ParsedToken; 6 | 7 | public class QuoteToken extends ParsedToken { 8 | public ImList toks; 9 | 10 | public QuoteToken(int line, ImList toks) { 11 | super(line); 12 | this.toks = toks; 13 | } 14 | 15 | public String toString() { 16 | StringBuilder sb = new StringBuilder(); 17 | sb.append("`"); 18 | sb.append((LexedParsedToken)this.toks.get(0)); 19 | return sb.toString(); 20 | } 21 | 22 | public QuoteToken() { 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/tokens/QuoteToken2.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.tokens; 2 | 3 | import sjava.compiler.tokens.Token; 4 | 5 | public class QuoteToken2 extends Token { 6 | public Token tok; 7 | 8 | public QuoteToken2(int line, Token tok) { 9 | super(line); 10 | this.tok = tok; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/tokens/ReturnToken.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.tokens; 2 | 3 | import sjava.compiler.tokens.Token; 4 | 5 | public class ReturnToken extends Token { 6 | public Token tok; 7 | 8 | public ReturnToken(int line, Token tok) { 9 | super(line); 10 | this.tok = tok; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/tokens/SToken.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.tokens; 2 | 3 | import org.apache.commons.lang3.StringEscapeUtils; 4 | import sjava.compiler.tokens.LexedToken; 5 | 6 | public class SToken extends LexedToken { 7 | public String val; 8 | public boolean tripleQuote; 9 | 10 | public SToken(int line, String val, boolean tripleQuote) { 11 | super(line); 12 | this.val = val; 13 | this.tripleQuote = tripleQuote; 14 | } 15 | 16 | public String toString() { 17 | String var10000; 18 | if(this.tripleQuote) { 19 | String escaped = this.val; 20 | if(escaped.endsWith("\"")) { 21 | StringBuilder sb = new StringBuilder(); 22 | sb.append(escaped.substring(0, escaped.length() - 1)); 23 | sb.append("\\\""); 24 | escaped = sb.toString(); 25 | } else if(escaped.endsWith("\\")) { 26 | StringBuilder sb1 = new StringBuilder(); 27 | sb1.append(escaped.substring(0, escaped.length() - 1)); 28 | sb1.append("\\\\"); 29 | escaped = sb1.toString(); 30 | } 31 | 32 | escaped = escaped.replace("\"\"\"", "\\\"\"\""); 33 | StringBuilder sb2 = new StringBuilder(); 34 | sb2.append("\"\"\""); 35 | sb2.append(escaped); 36 | sb2.append("\"\"\""); 37 | var10000 = sb2.toString(); 38 | } else { 39 | StringBuilder sb3 = new StringBuilder(); 40 | sb3.append("\""); 41 | sb3.append(StringEscapeUtils.escapeJava(this.val)); 42 | sb3.append("\""); 43 | var10000 = sb3.toString(); 44 | } 45 | 46 | return var10000; 47 | } 48 | 49 | public String toStringParsed() { 50 | return this.val; 51 | } 52 | 53 | public SToken() { 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/tokens/SetToken.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.tokens; 2 | 3 | import sjava.compiler.tokens.ImList; 4 | import sjava.compiler.tokens.Token; 5 | 6 | public class SetToken extends Token { 7 | public ImList toks; 8 | 9 | public SetToken(int line, ImList toks) { 10 | super(line); 11 | this.toks = toks; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/tokens/ShiftToken.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.tokens; 2 | 3 | import sjava.compiler.tokens.Token; 4 | 5 | public class ShiftToken extends Token { 6 | public boolean right; 7 | public Token tok; 8 | public Token amt; 9 | 10 | public ShiftToken(int line, Token tok, Token amt, boolean right) { 11 | super(line); 12 | this.tok = tok; 13 | this.amt = amt; 14 | this.right = right; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/tokens/SingleQuoteToken.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.tokens; 2 | 3 | import sjava.compiler.tokens.ImList; 4 | import sjava.compiler.tokens.LexedParsedToken; 5 | import sjava.compiler.tokens.ParsedToken; 6 | 7 | public class SingleQuoteToken extends ParsedToken { 8 | public ImList toks; 9 | 10 | public SingleQuoteToken(int line, ImList toks) { 11 | super(line); 12 | this.toks = toks; 13 | } 14 | 15 | public String toString() { 16 | StringBuilder sb = new StringBuilder(); 17 | sb.append("\'"); 18 | sb.append((LexedParsedToken)this.toks.get(0)); 19 | return sb.toString(); 20 | } 21 | 22 | public SingleQuoteToken() { 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/tokens/SpecialBeginToken.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.tokens; 2 | 3 | import sjava.compiler.tokens.BlockToken2; 4 | import sjava.compiler.tokens.ImList; 5 | import sjava.compiler.tokens.Token; 6 | 7 | public class SpecialBeginToken extends BlockToken2 { 8 | public SpecialBeginToken(int line, ImList toks) { 9 | super(line, toks); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/tokens/SynchronizedToken.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.tokens; 2 | 3 | import sjava.compiler.tokens.BlockToken2; 4 | import sjava.compiler.tokens.ImList; 5 | import sjava.compiler.tokens.Token; 6 | 7 | public class SynchronizedToken extends BlockToken2 { 8 | public SynchronizedToken(int line, ImList toks) { 9 | super(line, toks); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/tokens/ThrowToken.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.tokens; 2 | 3 | import sjava.compiler.tokens.Token; 4 | 5 | public class ThrowToken extends Token { 6 | public Token tok; 7 | 8 | public ThrowToken(int line, Token tok) { 9 | super(line); 10 | this.tok = tok; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/tokens/Token.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.tokens; 2 | 3 | import gnu.bytecode.CodeAttr; 4 | import gnu.bytecode.Type; 5 | import java.util.Iterator; 6 | import java.util.List; 7 | import sjava.compiler.emitters.Emitter; 8 | import sjava.compiler.handlers.GenHandler; 9 | 10 | public class Token extends Emitter { 11 | public int line; 12 | 13 | Token(int line) { 14 | this(); 15 | this.line = line; 16 | } 17 | 18 | public Type emit(GenHandler h, CodeAttr code, Type needed) { 19 | return h.compile(this, code, needed); 20 | } 21 | 22 | static String toksString(List l) { 23 | StringBuffer s = new StringBuffer(); 24 | Iterator it = l.iterator(); 25 | 26 | for(int i = 0; it.hasNext(); ++i) { 27 | Object tok = it.next(); 28 | s.append(tok); 29 | if(i != l.size() - 1) { 30 | s.append(" "); 31 | } 32 | } 33 | 34 | return s.toString(); 35 | } 36 | 37 | public Token() { 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/tokens/TryToken.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.tokens; 2 | 3 | import gnu.bytecode.Type; 4 | import sjava.compiler.tokens.ImList; 5 | import sjava.compiler.tokens.Token; 6 | import sjava.compiler.tokens.VToken; 7 | import sjava.std.Tuple3; 8 | 9 | public class TryToken extends Token { 10 | public Token tok; 11 | public ImList>> catches; 12 | public ImList finallyToks; 13 | 14 | public TryToken(int line, Token tok, ImList catches, ImList finallyToks) { 15 | super(line); 16 | this.tok = tok; 17 | this.catches = catches; 18 | this.finallyToks = finallyToks; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/tokens/TypeToken.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.tokens; 2 | 3 | import sjava.compiler.tokens.Token; 4 | 5 | public class TypeToken extends Token { 6 | public Token tok; 7 | 8 | public TypeToken(int line, Token tok) { 9 | super(line); 10 | this.tok = tok; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/tokens/UnquoteToken.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.tokens; 2 | 3 | import sjava.compiler.tokens.ImList; 4 | import sjava.compiler.tokens.LexedParsedToken; 5 | import sjava.compiler.tokens.ParsedToken; 6 | 7 | public class UnquoteToken extends ParsedToken { 8 | public boolean var; 9 | public ImList toks; 10 | 11 | public UnquoteToken(int line, ImList toks, boolean var) { 12 | super(line); 13 | this.toks = toks; 14 | this.var = var; 15 | } 16 | 17 | public String toString() { 18 | StringBuilder sb = new StringBuilder(); 19 | sb.append(this.var?",$":","); 20 | sb.append((LexedParsedToken)this.toks.get(0)); 21 | return sb.toString(); 22 | } 23 | 24 | public UnquoteToken() { 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /generated-java/sjava/compiler/tokens/VToken.java: -------------------------------------------------------------------------------- 1 | package sjava.compiler.tokens; 2 | 3 | import sjava.compiler.tokens.LexedToken; 4 | 5 | public class VToken extends LexedToken { 6 | public String val; 7 | public transient int macro; 8 | 9 | VToken(int line, String val, int macro) { 10 | super(line); 11 | this.val = val; 12 | this.macro = macro; 13 | } 14 | 15 | public VToken(int line, String val) { 16 | this(line, val, 0); 17 | } 18 | 19 | public String toString() { 20 | return this.val; 21 | } 22 | 23 | public VToken() { 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /generated-java/sjava/std/Function0.java: -------------------------------------------------------------------------------- 1 | package sjava.std; 2 | 3 | public interface Function0 { 4 | R apply(); 5 | } 6 | -------------------------------------------------------------------------------- /generated-java/sjava/std/Function1.java: -------------------------------------------------------------------------------- 1 | package sjava.std; 2 | 3 | public interface Function1 { 4 | R apply(A var1); 5 | } 6 | -------------------------------------------------------------------------------- /generated-java/sjava/std/Function10.java: -------------------------------------------------------------------------------- 1 | package sjava.std; 2 | 3 | public interface Function10 { 4 | R apply(A var1, B var2, C var3, D var4, E var5, F var6, G var7, H var8, I var9, J var10); 5 | } 6 | -------------------------------------------------------------------------------- /generated-java/sjava/std/Function2.java: -------------------------------------------------------------------------------- 1 | package sjava.std; 2 | 3 | public interface Function2 { 4 | R apply(A var1, B var2); 5 | } 6 | -------------------------------------------------------------------------------- /generated-java/sjava/std/Function3.java: -------------------------------------------------------------------------------- 1 | package sjava.std; 2 | 3 | public interface Function3 { 4 | R apply(A var1, B var2, C var3); 5 | } 6 | -------------------------------------------------------------------------------- /generated-java/sjava/std/Function4.java: -------------------------------------------------------------------------------- 1 | package sjava.std; 2 | 3 | public interface Function4 { 4 | R apply(A var1, B var2, C var3, D var4); 5 | } 6 | -------------------------------------------------------------------------------- /generated-java/sjava/std/Function5.java: -------------------------------------------------------------------------------- 1 | package sjava.std; 2 | 3 | public interface Function5 { 4 | R apply(A var1, B var2, C var3, D var4, E var5); 5 | } 6 | -------------------------------------------------------------------------------- /generated-java/sjava/std/Function6.java: -------------------------------------------------------------------------------- 1 | package sjava.std; 2 | 3 | public interface Function6 { 4 | R apply(A var1, B var2, C var3, D var4, E var5, F var6); 5 | } 6 | -------------------------------------------------------------------------------- /generated-java/sjava/std/Function7.java: -------------------------------------------------------------------------------- 1 | package sjava.std; 2 | 3 | public interface Function7 { 4 | R apply(A var1, B var2, C var3, D var4, E var5, F var6, G var7); 5 | } 6 | -------------------------------------------------------------------------------- /generated-java/sjava/std/Function8.java: -------------------------------------------------------------------------------- 1 | package sjava.std; 2 | 3 | public interface Function8 { 4 | R apply(A var1, B var2, C var3, D var4, E var5, F var6, G var7, H var8); 5 | } 6 | -------------------------------------------------------------------------------- /generated-java/sjava/std/Function9.java: -------------------------------------------------------------------------------- 1 | package sjava.std; 2 | 3 | public interface Function9 { 4 | R apply(A var1, B var2, C var3, D var4, E var5, F var6, G var7, H var8, I var9); 5 | } 6 | -------------------------------------------------------------------------------- /generated-java/sjava/std/Tuple2.java: -------------------------------------------------------------------------------- 1 | package sjava.std; 2 | 3 | public class Tuple2 { 4 | public A _1; 5 | public B _2; 6 | 7 | public Tuple2(A _1, B _2) { 8 | this._1 = _1; 9 | this._2 = _2; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /generated-java/sjava/std/Tuple3.java: -------------------------------------------------------------------------------- 1 | package sjava.std; 2 | 3 | public class Tuple3 { 4 | public A _1; 5 | public B _2; 6 | public C _3; 7 | 8 | public Tuple3(A _1, B _2, C _3) { 9 | this._1 = _1; 10 | this._2 = _2; 11 | this._3 = _3; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tombousso/sJava/d926a3efee11415e18820707617da75725c0c215/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | zipStoreBase=GRADLE_USER_HOME 4 | zipStorePath=wrapper/dists 5 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.8-bin.zip 6 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn () { 37 | echo "$*" 38 | } 39 | 40 | die () { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Escape application args 158 | save () { 159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 160 | echo " " 161 | } 162 | APP_ARGS=$(save "$@") 163 | 164 | # Collect all arguments for the java command, following the shell quoting and substitution rules 165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 166 | 167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 169 | cd "$(dirname "$0")" 170 | fi 171 | 172 | exec "$JAVACMD" "$@" 173 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /lib/asm.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tombousso/sJava/d926a3efee11415e18820707617da75725c0c215/lib/asm.jar -------------------------------------------------------------------------------- /lib/commons-cli-1.3.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tombousso/sJava/d926a3efee11415e18820707617da75725c0c215/lib/commons-cli-1.3.1.jar -------------------------------------------------------------------------------- /lib/commons-io-2.5.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tombousso/sJava/d926a3efee11415e18820707617da75725c0c215/lib/commons-io-2.5.jar -------------------------------------------------------------------------------- /lib/commons-lang-3.4.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tombousso/sJava/d926a3efee11415e18820707617da75725c0c215/lib/commons-lang-3.4.jar -------------------------------------------------------------------------------- /lib/kawa.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tombousso/sJava/d926a3efee11415e18820707617da75725c0c215/lib/kawa.jar -------------------------------------------------------------------------------- /plugin/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'java-gradle-plugin' 3 | } 4 | apply plugin: 'groovy' 5 | 6 | gradlePlugin { 7 | plugins { 8 | simplePlugin { 9 | id = 'sjava' 10 | implementationClass = 'sjava.gradle.SjavaPlugin' 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /plugin/src/main/groovy/sjava/gradle/SjavaCompile.groovy: -------------------------------------------------------------------------------- 1 | package sjava.gradle 2 | 3 | import org.gradle.api.* 4 | import org.gradle.api.tasks.* 5 | import org.gradle.api.file.* 6 | 7 | class SjavaCompile extends DefaultTask { 8 | @InputFiles 9 | File getSjavaJar() { 10 | return new File(project.ext.sjavaHome.toString() + "/sjava.jar") 11 | } 12 | 13 | @InputFiles 14 | FileCollection getCompileClasspath() { 15 | return project.sourceSets.main.compileClasspath 16 | } 17 | 18 | @InputFiles 19 | FileTree getSourceFiles() { 20 | return project.fileTree("src/main/sjava") 21 | } 22 | 23 | @OutputDirectory 24 | File getDestinationDir() { 25 | return project.file("build/classes/sjava/main") 26 | } 27 | 28 | @TaskAction 29 | public void compile() { 30 | project.javaexec { 31 | classpath = project.files(getSjavaJar()) + getCompileClasspath() 32 | main = "sjava.compiler.Main" 33 | args = ["build"] + getSourceFiles() + ["-d", getDestinationDir()] 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /plugin/src/main/groovy/sjava/gradle/SjavaPlugin.groovy: -------------------------------------------------------------------------------- 1 | package sjava.gradle 2 | 3 | import org.gradle.api.* 4 | import org.gradle.api.plugins.JavaPlugin 5 | 6 | class SjavaPlugin implements Plugin { 7 | public void apply(Project project) { 8 | project.plugins.apply(JavaPlugin) 9 | def task = project.task(type: SjavaCompile, "compileSjava") 10 | project.getTasksByName("classes", false)[0].dependsOn(task) 11 | def dependency = project.files(task.getDestinationDir()) 12 | project.dependencies { 13 | compile dependency 14 | runtimeClasspath dependency 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /sjava: -------------------------------------------------------------------------------- 1 | java -jar `dirname $0`/sjava.jar "$@" 2 | -------------------------------------------------------------------------------- /sjava.bat: -------------------------------------------------------------------------------- 1 | @java -jar %~dp0/sjava.jar %* 2 | -------------------------------------------------------------------------------- /sjava.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tombousso/sJava/d926a3efee11415e18820707617da75725c0c215/sjava.jar -------------------------------------------------------------------------------- /std/FunctionN.sjava: -------------------------------------------------------------------------------- 1 | (package sjava.std) 2 | 3 | (define-class Function0{R} () public interface abstract 4 | ((apply) R public abstract) 5 | ) 6 | 7 | (define-class Function1{A R} () public interface abstract 8 | ((apply a A) R public abstract) 9 | ) 10 | 11 | (define-class Function2{A B R} () public interface abstract 12 | ((apply a A b B) R public abstract) 13 | ) 14 | 15 | (define-class Function3{A B C R} () public interface abstract 16 | ((apply a A b B c C) R public abstract) 17 | ) 18 | 19 | (define-class Function4{A B C D R} () public interface abstract 20 | ((apply a A b B c C d D) R public abstract) 21 | ) 22 | 23 | (define-class Function5{A B C D E R} () public interface abstract 24 | ((apply a A b B c C d D e E) R public abstract) 25 | ) 26 | 27 | (define-class Function6{A B C D E F R} () public interface abstract 28 | ((apply a A b B c C d D e E f F) R public abstract) 29 | ) 30 | 31 | (define-class Function7{A B C D E F G R} () public interface abstract 32 | ((apply a A b B c C d D e E f F g G) R public abstract) 33 | ) 34 | 35 | (define-class Function8{A B C D E F G H R} () public interface abstract 36 | ((apply a A b B c C d D e E f F g G h H) R public abstract) 37 | ) 38 | 39 | (define-class Function9{A B C D E F G H I R} () public interface abstract 40 | ((apply a A b B c C d D e E f F g G h H i I) R public abstract) 41 | ) 42 | 43 | (define-class Function10{A B C D E F G H I J R} () public interface abstract 44 | ((apply a A b B c C d D e E f F g G h H i I j J) R public abstract) 45 | ) 46 | -------------------------------------------------------------------------------- /std/TupleN.sjava: -------------------------------------------------------------------------------- 1 | (package sjava.std) 2 | 3 | (define-class Tuple2{A B} () public 4 | (_1 A public) 5 | (_2 B public) 6 | (( _1 A _2 B) void public 7 | (super:) 8 | (set this:_1 _1) 9 | (set this:_2 _2) 10 | ) 11 | ) 12 | 13 | (define-class Tuple3{A B C} () public 14 | (_1 A public) 15 | (_2 B public) 16 | (_3 C public) 17 | (( _1 A _2 B _3 C) void public 18 | (super:) 19 | (set this:_1 _1) 20 | (set this:_2 _2) 21 | (set this:_3 _3) 22 | ) 23 | ) 24 | -------------------------------------------------------------------------------- /std/macros.sjava: -------------------------------------------------------------------------------- 1 | (import gnu.bytecode.*) 2 | (import java.util.*) 3 | (import sjava.compiler.tokens.*) 4 | 5 | (define-macro (when cond @rest) 6 | `(if ,cond 7 | (begin 8 | ,rest 9 | ) 10 | ) 11 | ) 12 | (define-macro (while cond @block) 13 | `(begin 14 | (label start) 15 | (when ,cond 16 | ,block 17 | (goto start) 18 | ) 19 | ) 20 | ) 21 | (define-macro (do-while cond @block) 22 | `(begin 23 | (label start) 24 | ,block 25 | (when ,cond 26 | (goto start) 27 | ) 28 | ) 29 | ) 30 | (define-macro (inc v n) 31 | `(set ,v (+ ,v ,n)) 32 | ) 33 | (define-macro (inc v) 34 | (macro inc v `1) 35 | ) 36 | (define-macro (dec v n) 37 | `(set ,v (- ,v ,n)) 38 | ) 39 | (define-macro (dec v) 40 | (macro dec v `1) 41 | ) 42 | (define-macro (forEach vars iterable @block) 43 | (define item VToken 44 | (if (instance? vars VToken) 45 | vars 46 | ((as BlockToken vars):toks:get 0) 47 | ) 48 | ) 49 | (define index VToken 50 | (if (instance? vars VToken) 51 | `notused 52 | ((as BlockToken vars):toks:get 1) 53 | ) 54 | ) 55 | (if (instance? (type iterable) ArrayType) 56 | `(begin 57 | (define array ,iterable) 58 | (define ,index 0) 59 | (while (!= ,index (alen array)) 60 | (define ,item (aget array ,index)) 61 | ,block 62 | (inc ,index) 63 | ) 64 | ) 65 | `(begin 66 | (define iterable ,iterable) 67 | (define it (iterable:iterator)) 68 | (define ,index 0) 69 | (while (it:hasNext) 70 | (define ,item (it:next)) 71 | ,block 72 | (inc ,index) 73 | ) 74 | ) 75 | ) 76 | ) 77 | (define-macro (print @objects) 78 | `(System:out:print (concat ,objects)) 79 | ) 80 | (define-macro (println @objects) 81 | `(System:out:println (concat ,objects)) 82 | ) 83 | (define-macro (mapA vars collection @block) 84 | (define t (type collection)) 85 | (define itemT 86 | (if (instance? t ArrayType) 87 | (t:getComponentType) 88 | (type 89 | `(begin 90 | (define collection ,collection) 91 | ((collection:iterator):next) 92 | ) 93 | ) 94 | ) 95 | ) 96 | (define len 97 | (if (instance? t ArrayType) 98 | `(alen collection) 99 | `(collection:size) 100 | ) 101 | ) 102 | (define item VToken 103 | (if (instance? vars VToken) 104 | vars 105 | ((as BlockToken vars):toks:get 0) 106 | ) 107 | ) 108 | (define i VToken 109 | (if (instance? vars VToken) 110 | `i 111 | ((as BlockToken vars):toks:get 1) 112 | ) 113 | ) 114 | (define arrElement `(begin (define ,item ,itemT) (define ,i int) ,block)) 115 | (define o (type arrElement)) 116 | `(begin 117 | (define collection ,collection) 118 | (define out ((unquote o)[] len:,len)) 119 | (forEach (,item ,i) collection 120 | (aset out ,i (begin ,block)) 121 | ) 122 | out 123 | ) 124 | ) 125 | (define-macro (concat @objects) 126 | (define appends 127 | (mapA o objects 128 | (if (instance? (type o) ArrayType) 129 | `(sb:append (java.util.Arrays:toString ,o)) 130 | `(sb:append ,o) 131 | ) 132 | ) 133 | ) 134 | `(begin 135 | (define sb (StringBuilder)) 136 | ,appends 137 | (sb:toString) 138 | ) 139 | ) 140 | (define-macro (let inits @block) 141 | (define defines 142 | (mapA init (as BlockToken inits):toks 143 | `(define ,(as BlockToken init):toks) 144 | ) 145 | ) 146 | `(begin 147 | ,defines 148 | ,block 149 | ) 150 | ) 151 | (define-macro (lambdaWrap name @types) 152 | (define n (alen types)) 153 | (define decl (Object[] len:(* n 2))) 154 | (define args (Object[] len:n)) 155 | (define i 0) 156 | (while (!= i n) 157 | (define v `,$(Character:toString (as char (+ 97 i)))) 158 | (define t (aget types i)) 159 | (aset decl (* i 2) v) 160 | (aset decl (+ (* i 2) 1) t) 161 | (aset args i v) 162 | (inc i) 163 | ) 164 | `(lambda (,decl) (,name ,args)) 165 | ) 166 | (define-macro (for inits test step @block) 167 | `(let ,inits 168 | (while ,test 169 | (begin 170 | ,block 171 | ) 172 | ,step 173 | ) 174 | ) 175 | ) 176 | (define-macro (repeat n @block) 177 | `(for ((i ,n)) (> i 0) (dec i) ,block) 178 | ) 179 | (define-macro (cond @cases) 180 | (define out BlockToken (aget cases (- (alen cases) 1))) 181 | (define n 182 | (if 183 | (&& 184 | (instance? (out:toks:get 0) ConstToken) 185 | ((as ConstToken (out:toks:get 0)):val:equals "true") 186 | ) 187 | (begin 188 | (set out `(begin ,(out:toks:skip 1))) 189 | 2 190 | ) 191 | (begin 192 | (set out `()) 193 | 1 194 | ) 195 | ) 196 | ) 197 | (for ((i (- (alen cases) n))) (>= i 0) (dec i) 198 | (define case BlockToken (aget cases i)) 199 | (set out 200 | `(if ,(case:toks:get 0) 201 | (begin 202 | ,(case:toks:skip 1) 203 | ) 204 | ,out 205 | ) 206 | ) 207 | ) 208 | out 209 | ) 210 | (define-macro (instanceCond var @cases) 211 | (define newCases 212 | (mapA case cases 213 | (define case BlockToken case) 214 | (if 215 | (&& 216 | (instance? (case:toks:get 0) ConstToken) 217 | ((as ConstToken (case:toks:get 0)):val:equals "true") 218 | ) 219 | case 220 | `((instance? ,var ,(case:toks:get 0)) 221 | (define ,var ,(case:toks:get 0) ,var) 222 | ,(case:toks:skip 1) 223 | ) 224 | ) 225 | ) 226 | ) 227 | `(cond 228 | ,newCases 229 | ) 230 | ) 231 | (define-macro (doubleDispatch call arg) 232 | (define j 1) 233 | (define special 0) 234 | (define call BlockToken call) 235 | (while (&& (!= j (call:toks:size)) (= special 0)) 236 | (define arg VToken (call:toks:get j)) 237 | (if (arg:val:equals "_") 238 | (set special j) 239 | ) 240 | (inc j) 241 | ) 242 | (set call:toks (call:toks:update special arg)) 243 | (define conds (ArrayList)) 244 | (define mname (as VToken (as ColonToken (call:toks:get 0)):right):val) 245 | (define nargs (alen (mi:method:getParameterTypes))) 246 | (forEach omi mi:ci:methods 247 | (when 248 | (&& 249 | ((omi:method:getName):equals mname) (!= mi omi) 250 | (= nargs (alen (omi:method:getParameterTypes))) 251 | ) 252 | (define t (aget (omi:method:getParameterTypes) (- special 1))) 253 | (conds:add 254 | `((instance? ,arg ,t) 255 | ,call 256 | ) 257 | ) 258 | ) 259 | ) 260 | (define out 261 | `(cond 262 | ,conds 263 | (true (throw (RuntimeException (concat "Double dispatch with " ,arg)))) 264 | ) 265 | ) 266 | out 267 | ) 268 | (define-macro (with obj @calls) 269 | `(begin 270 | (define obj ,obj) 271 | ,(mapA call calls 272 | (define call BlockToken call) 273 | `(obj:,(call:toks:get 0) ,(call:toks:skip 1)) 274 | ) 275 | obj 276 | ) 277 | ) 278 | (define-macro (chain obj @calls) 279 | (define out obj) 280 | (forEach call calls 281 | (define call BlockToken call) 282 | (set out `((unquote out):(unquote (call:toks:get 0)) ,(call:toks:skip 1))) 283 | ) 284 | out 285 | ) 286 | (define-class-macro (get @rest) 287 | (define s (as VToken (aget rest 0)):val) 288 | (define f (ci:c:getField s -1)) 289 | (define tok `(this:,$s)) 290 | (define scope (LinkedHashMap)) 291 | (define tup (sjava.compiler.Main:extractModifiers (Arrays:asList rest) 1)) 292 | (ci:addMethod (concat "get" (Character:toUpperCase (s:charAt 0)) (s:substring 1 (s:length))) (f:getType) tup:_1 tok:toks scope) 293 | ) 294 | (define-class-macro (set @rest) 295 | (define s (as VToken (aget rest 0)):val) 296 | (define f (ci:c:getField s -1)) 297 | (define tok `((set this:,$s ,$s))) 298 | (define scope (LinkedHashMap)) 299 | (scope:put s (sjava.compiler.Arg (f:getType) 1 0)) 300 | (define tup (sjava.compiler.Main:extractModifiers (Arrays:asList rest) 1)) 301 | (ci:addMethod (concat "set" (Character:toUpperCase (s:charAt 0)) (s:substring 1 (s:length))) Type:voidType tup:_1 tok:toks scope) 302 | ) 303 | ;first block after modifiers must be supercall 304 | (define-class-macro (ctor params @rest) 305 | (define scope (LinkedHashMap)) 306 | (define arg 1) 307 | (define sets (ArrayList{Token})) 308 | (define params BlockToken params) 309 | (for ((i 0)) (< i (params:toks:size)) (inc i) 310 | (define param (params:toks:get i)) 311 | (instanceCond param 312 | (VToken 313 | (scope:put param:val (sjava.compiler.Arg (ci:getType (params:toks:get (+ i 1))) arg 0)) 314 | (inc i) 315 | ) 316 | (SingleQuoteToken 317 | (define s (as VToken (param:toks:get 0)):val) 318 | (define f (ci:c:getField s -1)) 319 | (scope:put s (sjava.compiler.Arg (f:getType) arg 0)) 320 | (sets:add `(set this:,$s ,$s)) 321 | ) 322 | ) 323 | (inc arg) 324 | ) 325 | (define tup (sjava.compiler.Main:extractModifiers (Arrays:asList rest) 0)) 326 | (define body ((ImList (Arrays:asList rest)):skip tup:_2)) 327 | (define toks (ArrayList{LexedParsedToken})) 328 | (toks:add (body:get 0)) 329 | (toks:addAll sets) 330 | (toks:addAll (body:skip 1)) 331 | (ci:addMethod "" Type:voidType tup:_1 (ImList toks) scope) 332 | ) 333 | (define-macro (tokString tok) 334 | (if (instance? tok UnquoteToken) 335 | (tok:toks:get 0) 336 | `,(tok:toStringParsed) 337 | ) 338 | ) 339 | (define-macro (xml @rest) 340 | (define out (ArrayList{LexedParsedToken})) 341 | (forEach tag rest 342 | (cond 343 | ( 344 | (&& 345 | (instance? tag BlockToken) 346 | (instance? (tag:toks:get 0) VToken) 347 | ((as VToken (tag:toks:get 0)):val:equals "if") 348 | ) 349 | (out:add 350 | `(if ,(tag:toks:get 1) 351 | ,(mapA tok (tag:toks:skip 2) 352 | `(sb:append ,(macro xml tok)) 353 | ) 354 | ) 355 | ) 356 | ) 357 | ((instance? tag BlockToken) 358 | (define last (tag:toks:get (- (tag:toks:size) 1))) 359 | (define selfClose 360 | (&& 361 | (instance? last VToken) 362 | ((as VToken last):val:equals "!") 363 | ) 364 | ) 365 | (define size (tag:toks:size)) 366 | (if selfClose (dec size)) 367 | (define props (ArrayList{LexedParsedToken})) 368 | (define i 1) 369 | (for () (&& (< i size) (instance? (tag:toks:get i) ArrayToken)) (inc i) 370 | (define tok ArrayToken (tag:toks:get i)) 371 | (props:add 372 | (if (= (tok:toks:size) 1) 373 | `(begin 374 | (sb:append " ") 375 | (sb:append ,(macro tokString (tok:toks:get 0))) 376 | ) 377 | `(begin 378 | (sb:append " ") 379 | (sb:append ,(macro tokString (tok:toks:get 0))) 380 | (sb:append "=\"") 381 | (sb:append ,(macro tokString (tok:toks:get 1))) 382 | (sb:append "\"") 383 | ) 384 | ) 385 | ) 386 | ) 387 | (define children (ArrayList{LexedParsedToken})) 388 | (forEach tok (tag:toks:skip i) 389 | (if (instance? tok BlockToken) 390 | (children:add `(sb:append ,(macro xml tok))) 391 | (children:add `(sb:append ,(macro tokString tok))) 392 | ) 393 | ) 394 | (if (&& selfClose (!= (children:size) 0)) (throw (RuntimeException))) 395 | (out:add 396 | `(begin 397 | (sb:append "<") 398 | (sb:append ,(macro tokString (tag:toks:get 0))) 399 | ,props 400 | (sb:append ">") 401 | ,children 402 | ,(if selfClose 403 | `() 404 | `(begin 405 | (sb:append "") 408 | ) 409 | ) 410 | sb 411 | ) 412 | ) 413 | ) 414 | (true 415 | (out:add `(sb:append ,(macro tokString tag))) 416 | ) 417 | ) 418 | ) 419 | `(begin 420 | (define sb (StringBuffer)) 421 | ,out 422 | sb 423 | ) 424 | ) 425 | --------------------------------------------------------------------------------