├── .gitignore ├── Contributing.md ├── Extensions.md ├── LICENSE ├── README.md ├── UnitTest.devp ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── jpizza ├── bin │ └── main │ │ └── META-INF │ │ └── MANIFEST.MF ├── build.gradle └── src │ └── main │ └── java │ ├── META-INF │ └── MANIFEST.MF │ └── lemon │ └── jpizza │ ├── Constants.java │ ├── JPType.java │ ├── Logger.java │ ├── Operations.java │ ├── Pair.java │ ├── Position.java │ ├── RunMain.java │ ├── RunTest.java │ ├── Shell.java │ ├── Token.java │ ├── TokenType.java │ ├── Tokens.java │ ├── cases │ ├── Case.java │ └── ElseCase.java │ ├── compiler │ ├── Chunk.java │ ├── ChunkBuilder.java │ ├── ChunkCode.java │ ├── Compiler.java │ ├── Disassembler.java │ ├── FlatPosition.java │ ├── FunctionType.java │ ├── JStack.java │ ├── OpCode.java │ ├── TypeLookup.java │ ├── headers │ │ ├── Cache.java │ │ ├── HeadCode.java │ │ └── Memo.java │ ├── libraries │ │ ├── GUIs.java │ │ ├── Generators.java │ │ ├── HTTPx.java │ │ ├── IOFile.java │ │ ├── JPCollections.java │ │ ├── JPSon.java │ │ ├── JPrinter.java │ │ ├── JSystem.java │ │ ├── Time.java │ │ ├── awt │ │ │ ├── AbstractWindowToolkit.java │ │ │ ├── config │ │ │ │ ├── Canvas.java │ │ │ │ ├── ColorSpan.java │ │ │ │ ├── JFont.java │ │ │ │ ├── Queue.java │ │ │ │ └── Window.java │ │ │ └── displays │ │ │ │ ├── Drawable.java │ │ │ │ ├── Img.java │ │ │ │ ├── Line.java │ │ │ │ ├── Oval.java │ │ │ │ ├── Polygon.java │ │ │ │ ├── Rectangle.java │ │ │ │ └── Text.java │ │ ├── pretzel │ │ │ ├── Handle.java │ │ │ └── Pretzel.java │ │ └── puddle │ │ │ ├── ClientPDL.java │ │ │ ├── PDL.java │ │ │ └── ServerPDL.java │ ├── types │ │ ├── AnyType.java │ │ ├── GenericType.java │ │ ├── SpreadType.java │ │ ├── Type.java │ │ ├── TypeCodes.java │ │ ├── Types.java │ │ ├── VoidType.java │ │ ├── objects │ │ │ ├── ClassType.java │ │ │ ├── EnumChildType.java │ │ │ ├── EnumType.java │ │ │ ├── FuncType.java │ │ │ ├── InstanceType.java │ │ │ ├── MapType.java │ │ │ ├── MaybeType.java │ │ │ ├── MethodType.java │ │ │ ├── NamespaceType.java │ │ │ ├── PrimitiveGenericType.java │ │ │ ├── ReferenceType.java │ │ │ ├── TupleType.java │ │ │ └── VecType.java │ │ └── primitives │ │ │ ├── BooleanType.java │ │ │ ├── BytesType.java │ │ │ ├── DictType.java │ │ │ ├── FloatType.java │ │ │ ├── IntType.java │ │ │ ├── ListType.java │ │ │ ├── PrimitiveType.java │ │ │ ├── PrimitiveTypes.java │ │ │ ├── ResultType.java │ │ │ └── StringType.java │ ├── values │ │ ├── Pattern.java │ │ ├── Value.java │ │ ├── ValueArray.java │ │ ├── Var.java │ │ ├── classes │ │ │ ├── BoundMethod.java │ │ │ ├── ClassAttr.java │ │ │ ├── Instance.java │ │ │ ├── JClass.java │ │ │ └── Namespace.java │ │ ├── enums │ │ │ ├── JEnum.java │ │ │ └── JEnumChild.java │ │ └── functions │ │ │ ├── JClosure.java │ │ │ ├── JFunc.java │ │ │ ├── JNative.java │ │ │ ├── NativeResult.java │ │ │ ├── Result.java │ │ │ └── Spread.java │ └── vm │ │ ├── CallFrame.java │ │ ├── JPExtension.java │ │ ├── LibraryManager.java │ │ ├── VM.java │ │ └── VMResult.java │ ├── errors │ ├── Error.java │ └── Tip.java │ ├── generators │ ├── Lexer.java │ ├── Optimizer.java │ └── Parser.java │ ├── nodes │ ├── Node.java │ ├── TreePrinter.java │ ├── definitions │ │ ├── AttrAssignNode.java │ │ ├── AttrDeclareNode.java │ │ ├── ClassDefNode.java │ │ ├── DecoratorNode.java │ │ ├── DestructNode.java │ │ ├── DynAssignNode.java │ │ ├── FuncDefNode.java │ │ ├── LetNode.java │ │ ├── MethDefNode.java │ │ └── VarAssignNode.java │ ├── expressions │ │ ├── AssertNode.java │ │ ├── BodyNode.java │ │ ├── BreakNode.java │ │ ├── CallNode.java │ │ ├── CastNode.java │ │ ├── ClaccessNode.java │ │ ├── ContinueNode.java │ │ ├── DerefNode.java │ │ ├── DropNode.java │ │ ├── ExtendNode.java │ │ ├── ForNode.java │ │ ├── ImportNode.java │ │ ├── IterNode.java │ │ ├── PassNode.java │ │ ├── QueryNode.java │ │ ├── ReturnNode.java │ │ ├── ScopeNode.java │ │ ├── SpreadNode.java │ │ ├── SwitchNode.java │ │ ├── ThrowNode.java │ │ ├── UseNode.java │ │ └── WhileNode.java │ ├── operations │ │ ├── BinOpNode.java │ │ └── UnaryOpNode.java │ ├── values │ │ ├── BooleanNode.java │ │ ├── BytesNode.java │ │ ├── DictNode.java │ │ ├── EnumNode.java │ │ ├── ListNode.java │ │ ├── NullNode.java │ │ ├── NumberNode.java │ │ ├── PatternNode.java │ │ ├── RefNode.java │ │ ├── StringNode.java │ │ └── ValueNode.java │ └── variables │ │ ├── AttrAccessNode.java │ │ ├── AttrNode.java │ │ ├── VarAccessNode.java │ │ └── VarNode.java │ └── results │ └── ParseResult.java ├── jpn.png ├── pizzico512.png ├── settings.gradle └── shadow.bat /.gitignore: -------------------------------------------------------------------------------- 1 | .replit 2 | replit.nix 3 | *.class 4 | *.jar 5 | sometoken.txt 6 | .DS_STORE 7 | *.devp 8 | *.jbox 9 | *.json 10 | .classpath 11 | .project 12 | .idea 13 | .gradle 14 | **/build/ 15 | !src/**/build/ 16 | gradle-app.setting 17 | !gradle-wrapper.jar 18 | .gradletasknamecache 19 | etc 20 | package.bat 21 | !UnitTest.devp -------------------------------------------------------------------------------- /Contributing.md: -------------------------------------------------------------------------------- 1 | # Contributing Guide 2 | 3 | A short and sweet guide on how to get started contributing to JPizza. 4 | 5 | ## Getting the source code 6 | 7 | If you just want to build JPizza for yourself, you can just download the source from github or clone the main repo. 8 | 9 | If you want to contribute any code, Please fork the repo and clone from your fork. 10 | 11 | ## Compiling JPizza 12 | 13 | JPizza uses the gradle build system. So, compiling JPizza is pretty simple! Just navigate your terminal into the folder where you cloned JPizza, then `cd` into the JPizza folder. From there, run the `gradlew shadowJar` command if you are on macos or linux, or `gradlew.bat shadowJar` if you are on windows. 14 | 15 | This will compile JPizza, and the resulting jar will be located at `jpizza/build/libs/jpizza-all.jar` 16 | 17 | If you want to create a cross platform release, you can run `gradlew assembleShadowDist` \[or `gradlew.bat assembleShadowDist` if on windows\] 18 | 19 | This will create archives which include scripts to run JPizza on unix and windows, alongside with the compiled JPizza jar. These archives can be extracted and put anywhere, and once you add the bin folder to your path, you can run JPizza easily. 20 | 21 | ## Thats it! 22 | 23 | That's really all you need to know to compile JPizza! Have fun! 24 | -------------------------------------------------------------------------------- /Extensions.md: -------------------------------------------------------------------------------- 1 | # JPizza Extension Development 2 | 3 | So, you want to make an extension for JPizza? Well, You've come to the right place. 4 | 5 | ## Getting Started 6 | 7 | The first thing you need to do is [clone the base extension repo.](https://github.com/Lemon-Chad/JPizza-Extension-Template) 8 | This repo contains all of the code and gradle magic to make your own JPizza extension. 9 | 10 | After you have the code, Pick a name for your extension. Should be the easy part. 11 | 12 | ## Beginning Development 13 | 14 | In order to start writing code for your extension, look in the `app/src/main/java/jpext` folder. In there, there should be one file, named `LibraryName.java` (You should rename this to match the name of your library) 15 | 16 | Once you have the file opened, make sure to change every instance of LibraryName to the exact same thing you put as the name of the file. Now, you are almost ready to start making all of your custom functions! 17 | 18 | Next, you need the JPizza jar. Download the latest jar from github, (or compile it yourself), and put it into the `app/jars` folder. Make sure to name it jpizza-all.jar 19 | 20 | This is necessary for all the imports to work, but don't worry, it's not included in the final jar of your extension. 21 | 22 | ## Making Libraries 23 | 24 | So, you want to make a function, but where does that function go? 25 | 26 | Well, in a library of course! 27 | 28 | If you look in the LibraryName.java (Which is what it will be referred to, even though you should have changed the name), you will see a function called `initialize`. This is where all of your initialization code should go. To make the initialization code, simply make a call to the initialize function with the name of your import, the class of your library, (as in, `LibraryName.class`), and finally, a HashMap. In this HashMap, you should `put` all of your functions that will go into that library and a list of parameters for the function. 29 | Example: 30 | `initialize("demo", LibraryName.class, new HashMap<>(){{ 31 | put("printDemo", Collections.singletonList("value")); 32 | }});` 33 | This is the initialize call for a library called demo, with one function, 'printDemo', which takes in 1 'value' as its parameter. 34 | 35 | ## Making Functions 36 | 37 | So, you have your libraries, but how do you make functions? Well, once you add it to your library, just create a public Java function below with a return type of RTResult. Make sure to make the name of the function `execute_FunctionName`. This function should take in 1 value, a Context. From this, just do what you gotta do, add a return somewhere, and bam. Easy extension done! 38 | 39 | ## What Next? 40 | 41 | So you have all your code, but how do you use this? Well, just run the gradle task named `jar`. You can do this by running `./gradlew jar` on unix or `./gradlew.bat jar` on windows. 42 | 43 | If everything is good, this should create a jar in the app/build/libs folder called `app.jar`. Simply rename this to the name of your extension, (as used previously), and add it to your `.jpizza/extensions` folder located in your home directory (unless you configured otherwise). Then, simply load up JPizza, and use the command `extend LibraryName` to load the extension, then just import anything you want to use! 44 | 45 | ### Notes 46 | - This is a VERY new and untested system. If you find any bugs with the extension template/compilation process, Please create an issue on the template's github repository. If you find any bugs with the JPizza command, Please create an issue on JPizza's github repository. 47 | - This system will be better eventually once we know what bugs there are. You can use this to do anything you can do with Java within JPizza, so we want it to be as good as possible. 48 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Jackson Oliver Smith 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![](jpn.png) 2 | 3 | # JPizza2 4 | 5 | GitHub license GitHub stars GitHub all releases GitHub tag (latest by date) 6 | 7 | A fast to type and easy to ship language for developers on the go! 8 | 9 | ## Why Use It? 10 | 11 | - Function arrow syntax for fast inline functions. 12 | - Loop arrow syntax to generate complex lists. 13 | - Callback variables that update the value when called. 14 | - The ability to strictly limit numeric variable ranges. 15 | - Query expression that function as an alternative to ternary chains. 16 | - Match expression that functions as a switch statement that returns a value. 17 | - Built-in optimization features like memoization. 18 | - Main functions/classes. 19 | - Built-in benchmarking functions. 20 | - Automatic feedback on how to make your code cleaner. 21 | - Open source. 22 | - Response devs that constantly fix bugs. 23 | - Open source package manager. 24 | - More! 25 | 26 | ## Resources 27 | - [Documentation](https://jpizza.rtfd.io) -> The good ol' docs 28 | - [Contributing Guide](Contributing.md) -> Basic steps to get started contributing. 29 | - [Extension Guide](Extensions.md) -> Guide to developing jpizza extensions. 30 | - [VSCode](https://bit.ly/jp2vscode) -> Add JPizza2 to VSCode 31 | - [JPX](https://bit.ly/jpx) -> Framework adding fun import features and helps you ship your app to other machines without the need for JPizza2 32 | - [Video Tutorials](https://bit.ly/jp2tutorial) -> A full video tutorial series over JPizza2, Fridge, and even JPX! 33 | - [Discord](https://discord.gg/9RGBBk4w4B) -> The official JPizza discord. 34 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | GRADLE_OPTS=-Dfile.encoding=utf-8 2 | org.gradle.jvmargs='-Dfile.encoding=UTF-8' -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lemon-Chad/jpizza/1d0380d519decb5d8a7c0b19858dc4772a96862c/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /jpizza/bin/main/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Main-Class: lemon.jpizza.Shell 3 | 4 | -------------------------------------------------------------------------------- /jpizza/build.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * This file was generated by the Gradle 'init' task. 3 | * 4 | * This generated file contains a sample Java application project to get you started. 5 | * For more details take a look at the 'Building Java & JVM projects' chapter in the Gradle 6 | * User Manual available at https://docs.gradle.org/7.2/userguide/building_java_projects.html 7 | */ 8 | 9 | plugins { 10 | // Apply the application plugin to add support for building a CLI application in Java. 11 | id 'application' 12 | id 'com.github.johnrengelman.shadow' version '7.0.0' 13 | id 'java' 14 | } 15 | 16 | compileJava.options.encoding = 'UTF-8' 17 | 18 | repositories { 19 | // Use Maven Central for resolving dependencies. 20 | mavenCentral() 21 | } 22 | 23 | dependencies { 24 | // Use JUnit test framework. 25 | testImplementation 'junit:junit:4.13.2' 26 | 27 | implementation 'com.github.tomas-langer:chalk:1.0.2' 28 | 29 | implementation 'org.apache.commons:commons-lang3:3.12.0' 30 | implementation 'org.apache.commons:commons-text:1.9' 31 | implementation 'commons-io:commons-io:2.11.0' 32 | 33 | 34 | // Use Jackson for JSON serialization. 35 | implementation 'com.fasterxml.jackson.core:jackson-databind:2.0.1' 36 | 37 | implementation 'org.jetbrains:annotations:16.0.2' 38 | 39 | 40 | // This dependency is used by the application. 41 | implementation 'com.google.guava:guava:30.1.1-jre' 42 | } 43 | 44 | application { 45 | // Define the main class for the application. 46 | mainClass = 'lemon.jpizza.Shell' 47 | } 48 | 49 | 50 | jar { 51 | //noinspection GroovyAssignabilityCheck 52 | manifest { 53 | attributes 'Main-Class': 'lemon.jpizza.Shell' 54 | } 55 | 56 | } 57 | 58 | run{ 59 | standardInput = System.in 60 | } 61 | -------------------------------------------------------------------------------- /jpizza/src/main/java/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Main-Class: lemon.jpizza.Shell 3 | 4 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/JPType.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza; 2 | 3 | public enum JPType { 4 | AttrAssign, 5 | AttrAccess, 6 | Attr, 7 | Assert, 8 | Bytes, 9 | BaseFunction, 10 | Break, 11 | BinOp, 12 | Boolean, 13 | ClassInstance, 14 | ClassPlate, 15 | CMethod, 16 | ClassDef, 17 | Call, 18 | Claccess, 19 | Continue, 20 | Deref, 21 | DynAssign, 22 | Dict, 23 | Decorator, 24 | Extend, 25 | Enum, 26 | EnumChild, 27 | Function, 28 | FuncDef, 29 | For, 30 | Generic, 31 | Import, 32 | Iter, 33 | Library, 34 | List, 35 | MethDef, 36 | Null, 37 | Number, 38 | Pattern, 39 | Pass, 40 | Query, 41 | Ref, 42 | Return, 43 | Res, 44 | String, 45 | Switch, 46 | Spread, 47 | Use, 48 | UnaryOp, 49 | VarAssign, 50 | Value, 51 | VarAccess, 52 | Var, 53 | While, 54 | Body, 55 | Scope, 56 | Let, 57 | Throw, 58 | Drop, 59 | Destruct, 60 | Cast, 61 | } 62 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/Logger.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza; 2 | 3 | import com.github.tomaslanger.chalk.Chalk; 4 | import lemon.jpizza.compiler.values.Value; 5 | 6 | import java.util.Collections; 7 | import java.util.List; 8 | import java.util.Map; 9 | import java.util.Scanner; 10 | 11 | public class Logger { 12 | boolean log = true; 13 | boolean tips = false; 14 | public final boolean debug = false; 15 | final int omitt = 5; 16 | final int tape = 40; 17 | final Scanner scanner = new Scanner(System.in); 18 | 19 | public void reset() { 20 | log = true; 21 | tips = false; 22 | } 23 | 24 | public String ots(Object text) { 25 | return ots(text, false); 26 | } 27 | 28 | @SuppressWarnings("DuplicatedCode") 29 | public String ots(Object text, boolean stringInner) { 30 | if (text instanceof Value) { 31 | Value val = (Value) text; 32 | if (val.isList) { 33 | StringBuilder sb = new StringBuilder(); 34 | List l = val.asList(); 35 | 36 | for (int i = 0; i < l.size(); i++) 37 | if (i >= omitt && i < l.size() - omitt) { 38 | if (i == omitt + 1) sb.append("..., "); 39 | } 40 | else sb.append(ots(l.get(i), true)).append(", "); 41 | 42 | return "[ " + sb + "len=" + l.size() + " ]"; 43 | } 44 | else if (val.isMap) { 45 | StringBuilder sb = new StringBuilder(); 46 | Map d = val.asMap(); 47 | 48 | Value[] keys = d.keySet().toArray(new Value[0]); 49 | for (int i = 0; i < keys.length; i++) 50 | if (i >= omitt && i < keys.length - omitt) { 51 | if (i == omitt + 1) sb.append("..., "); 52 | } 53 | else sb.append(ots(keys[i], true)).append(": ") 54 | .append(ots(d.get(keys[i]), true)).append(", "); 55 | 56 | return "{ " + sb + "len=" + keys.length + " }"; 57 | } 58 | else if (val.isNull) { 59 | return "null"; 60 | } 61 | else if (val.isString && stringInner) { 62 | return "\"" + val.asString() + "\""; 63 | } 64 | return val.asString(); 65 | } 66 | return text.toString(); 67 | } 68 | 69 | public void out(Object text) { 70 | if (log) 71 | System.out.print(ots(text)); 72 | System.out.flush(); 73 | } 74 | 75 | public void warn(Object text) { 76 | if (log) 77 | System.out.println(Chalk.on( 78 | getTape("WARNING") + "\n" + ots(text) 79 | ).yellow()); 80 | } 81 | 82 | private String getTape(String message) { 83 | return String.join("", Collections.nCopies((tape - message.length()) / 2, " ")) + message + "\n" + 84 | String.join("", Collections.nCopies(tape, Shell.fileEncoding.equals("UTF-8") ? "─" : "_")); 85 | } 86 | 87 | public void fail(Object text) { 88 | if (log) { 89 | System.out.println(Chalk.on( 90 | getTape("FAILURE") + "\n" + ots(text) 91 | ).red()); 92 | System.exit(1); 93 | } 94 | } 95 | 96 | public void tip(Object text) { 97 | if (log && tips) 98 | System.out.println(Chalk.on( 99 | getTape("TIP") + "\n" + ots(text) 100 | ).cyan()); 101 | } 102 | 103 | public void outln(Object text) { 104 | if (log) System.out.println(ots(text)); 105 | } 106 | 107 | public void disableLogging() { log = false; } 108 | public void enableLogging() { log = true; } 109 | 110 | public void enableTips() { tips = true; } 111 | public void disableTips() { tips = false; } 112 | 113 | public void debug(String format) { 114 | if (debug) 115 | System.out.print(Chalk.on(format).magenta()); 116 | } 117 | 118 | public void debug(Value val) { 119 | if (debug) 120 | System.out.print(Chalk.on(ots(val)).magenta()); 121 | } 122 | 123 | public String in() { 124 | return scanner.nextLine(); 125 | } 126 | 127 | } 128 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/Operations.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza; 2 | 3 | public enum Operations { 4 | BITCOMPL, 5 | BITAND, 6 | BITOR, 7 | BITXOR, 8 | LEFTSHIFT, 9 | RIGHTSHIFT, 10 | SIGNRIGHTSHIFT, 11 | BRACKET, 12 | NUMBER, 13 | DICTIONARY, 14 | ALIST, 15 | ASTRING, 16 | BOOL, 17 | ANULL, 18 | FUNCTION, 19 | DELETE, 20 | GET, 21 | ADD, 22 | SUB, 23 | MUL, 24 | DIV, 25 | MOD, 26 | FASTPOW, 27 | LTE, 28 | LT, 29 | ALSO, 30 | INCLUDING, 31 | INVERT, 32 | APPEND, 33 | EXTEND, 34 | POP, 35 | REMOVE, 36 | EXECUTE, 37 | EQ, 38 | NE, 39 | TOSTRING, 40 | COPY, 41 | TYPE, 42 | ACCESS, 43 | } 44 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/Pair.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza; 2 | 3 | public class Pair { 4 | public T a; 5 | public X b; 6 | public Pair(T a, X b) { 7 | this.a = a; 8 | this.b = b; 9 | } 10 | 11 | public String toString() { 12 | return String.format("%s, %s", a, b); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/Position.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza; 2 | 3 | public class Position { 4 | public int idx; 5 | public int ln; 6 | public int col; 7 | public int tcol = -1; 8 | public int tidx; 9 | public final String fn; 10 | public final String ftext; 11 | 12 | public Position(int idx, int ln, int col, String fn, String ftext) { 13 | this.idx = idx; 14 | this.ln = ln; 15 | this.col = col; 16 | this.fn = fn; 17 | this.ftext = ftext; 18 | } 19 | 20 | public Position setT(int tcol, int tidx) { 21 | this.tcol = tcol; 22 | this.tidx = tidx; 23 | return this; 24 | } 25 | 26 | public void advance(char current_char) { 27 | idx++; 28 | col++; 29 | 30 | if (current_char != '\t') { 31 | tcol++; 32 | tidx++; 33 | } 34 | 35 | if (current_char == Constants.splitter) { 36 | ln++; 37 | col = 0; 38 | tcol = 0; 39 | } 40 | 41 | } 42 | 43 | public Position advance() { 44 | idx++; 45 | col++; 46 | return this; 47 | } 48 | 49 | public Position copy() { 50 | return new Position(idx, ln, col, fn, ftext).setT(tcol, tidx); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/RunMain.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza; 2 | 3 | public class RunMain { 4 | public static void main(String[] args) { 5 | Shell.main(new String[]{ "-c", "main.devp", "-r", "main.jbox" }); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/RunTest.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza; 2 | 3 | import java.io.IOException; 4 | 5 | public class RunTest { 6 | public static void main(String[] args) { 7 | double start = System.currentTimeMillis(); 8 | Shell.main("-c UnitTest.devp -r UnitTest.jbox".split(" ")); 9 | double end = System.currentTimeMillis(); 10 | Shell.logger.outln("Time: " + (end - start) + "ms"); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/Tokens.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | public class Tokens { 7 | public static final Map TOKEY = new HashMap(){{ 8 | put("[", TokenType.LeftBracket); 9 | put("\\", TokenType.Backslash); 10 | put("..", TokenType.DotDot); 11 | put("~~", TokenType.TildeTilde); 12 | put("~>", TokenType.RightTildeArrow); 13 | put("<~", TokenType.LeftTildeArrow); 14 | put("@", TokenType.At); 15 | put("~&", TokenType.TildeAmpersand); 16 | put("~|", TokenType.TildePipe); 17 | put("~^", TokenType.TildeCaret); 18 | put("~", TokenType.Tilde); 19 | put("<-", TokenType.LeftArrow); 20 | put("::", TokenType.ColonColon); 21 | put("%", TokenType.Percent); 22 | put("#", TokenType.Hash); 23 | put("]", TokenType.RightBracket); 24 | put(",", TokenType.Comma); 25 | put("+", TokenType.Plus); 26 | put("++", TokenType.PlusPlus); 27 | put("--", TokenType.MinusMinus); 28 | put(">>", TokenType.AngleAngle); 29 | put(":", TokenType.Colon); 30 | put("$", TokenType.DollarSign); 31 | put("$_", TokenType.DollarUnderscore); 32 | put("?", TokenType.QuestionMark); 33 | put("-", TokenType.Minus); 34 | put("*", TokenType.Star); 35 | put("/", TokenType.Slash); 36 | put("(", TokenType.LeftParen); 37 | put(")", TokenType.RightParen); 38 | put("^", TokenType.Caret); 39 | put("=>", TokenType.FatArrow); 40 | put("&", TokenType.Ampersand); 41 | put("|", TokenType.Pipe); 42 | put("->", TokenType.SkinnyArrow); 43 | put(";", TokenType.Newline); 44 | put("{", TokenType.LeftBrace); 45 | put("}", TokenType.RightBrace); 46 | put("^=", TokenType.CaretEquals); 47 | put("*=", TokenType.StarEquals); 48 | put("/=", TokenType.SlashEquals); 49 | put("+=", TokenType.PlusEquals); 50 | put("-=", TokenType.MinusEquals); 51 | put(".", TokenType.Dot); 52 | }}; 53 | } 54 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/cases/Case.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.cases; 2 | 3 | import lemon.jpizza.nodes.Node; 4 | 5 | public class Case { 6 | public final boolean returnValue; 7 | public final Node condition; 8 | public final Node statements; 9 | 10 | public Case(Node condition, Node statements, boolean returnValue) { 11 | this.condition = condition; 12 | this.statements = statements; 13 | this.returnValue = returnValue; 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/cases/ElseCase.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.cases; 2 | 3 | import lemon.jpizza.nodes.Node; 4 | 5 | public class ElseCase { 6 | public final boolean returnValue; 7 | public final Node statements; 8 | 9 | public ElseCase(Node statements, boolean returnValue) { 10 | this.statements = statements; 11 | this.returnValue = returnValue; 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/Chunk.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler; 2 | 3 | import lemon.jpizza.Constants; 4 | import lemon.jpizza.compiler.types.Type; 5 | import lemon.jpizza.compiler.values.Value; 6 | import lemon.jpizza.compiler.values.ValueArray; 7 | 8 | import java.util.*; 9 | 10 | public class Chunk { 11 | List code; 12 | public int[] codeArray; 13 | public String packageName; 14 | public String target; 15 | ValueArray constants; 16 | public List positions; 17 | final String source; 18 | public Map globals; 19 | 20 | public Chunk(String source) { 21 | this.code = new ArrayList<>(); 22 | this.constants = new ValueArray(); 23 | this.positions = new ArrayList<>(Collections.singletonList(new FlatPosition(0, 0, 0))); 24 | this.source = source; 25 | this.globals = new HashMap<>(); 26 | } 27 | 28 | public void addGlobal(String name, Type type) { 29 | globals.put(name, type); 30 | } 31 | 32 | public void write(int b, int index, int len) { 33 | code.add(b); 34 | 35 | FlatPosition last = positions.get(positions.size() - 1); 36 | if (last.index == index && last.len == len) { 37 | last.span++; 38 | } 39 | else { 40 | positions.add(new FlatPosition(index, len, 1)); 41 | } 42 | } 43 | 44 | public FlatPosition getPosition(int offset) { 45 | int i = 0; 46 | for (FlatPosition pos : positions) { 47 | if (i + pos.span >= offset) { 48 | return pos; 49 | } 50 | i += pos.span; 51 | } 52 | return positions.get(positions.size() - 1); 53 | } 54 | 55 | public void compile() { 56 | codeArray = new int[code.size()]; 57 | for (int i = 0; i < code.size(); i++) { 58 | codeArray[i] = code.get(i); 59 | } 60 | constants.compile(); 61 | } 62 | 63 | public int getLine(int offset) { 64 | return Constants.indexToLine(source, getPosition(offset).index); 65 | } 66 | 67 | public int addConstant(Value value) { 68 | return constants.write(value); 69 | } 70 | 71 | public String source() { 72 | return source; 73 | } 74 | 75 | public ValueArray constants() { 76 | return constants; 77 | } 78 | public void constants(ValueArray constants) { 79 | this.constants = constants; 80 | } 81 | 82 | public int[] dump() { 83 | List list = new ArrayList<>(Collections.singletonList(ChunkCode.Chunk)); 84 | Value.addAllString(list, source); 85 | if (packageName != null) { 86 | Value.addAllString(list, packageName); 87 | } 88 | else { 89 | list.add(0); 90 | } 91 | if (target != null) { 92 | Value.addAllString(list, target); 93 | } 94 | else { 95 | list.add(0); 96 | } 97 | list.add(positions.size()); 98 | for (FlatPosition pos : positions) { 99 | list.add(pos.index); 100 | list.add(pos.len); 101 | list.add(pos.span); 102 | } 103 | for (int i : constants().dump()) 104 | list.add(i); 105 | list.add(globals.size()); 106 | for (Map.Entry entry : globals.entrySet()) { 107 | Value.addAllString(list, entry.getKey()); 108 | list.addAll(entry.getValue().dumpList()); 109 | } 110 | list.add(codeArray.length); 111 | for (int i : codeArray) 112 | list.add(i); 113 | return list.stream().mapToInt(Integer::intValue).toArray(); 114 | } 115 | 116 | } 117 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/ChunkCode.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler; 2 | 3 | public class ChunkCode { 4 | public static final int Number = 0; 5 | public static final int Boolean = 1; 6 | public static final int String = 2; 7 | public static final int Enum = 3; 8 | public static final int EnumChild = 4; 9 | public static final int Func = 5; 10 | public static final int Type = 6; 11 | public static final int Chunk = 7; 12 | } 13 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/FlatPosition.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler; 2 | 3 | public class FlatPosition { 4 | // The starting index of the token in the source file 5 | public final int index; 6 | // The number of characters after the index 7 | public final int len; 8 | // How many bytes this instruction takes 9 | public int span; 10 | 11 | public FlatPosition(int index, int len, int span) { 12 | this.index = index; 13 | this.len = len; 14 | this.span = span; 15 | } 16 | 17 | public String toString() { 18 | return "(" + index + "," + len + ")"; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/FunctionType.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler; 2 | 3 | public enum FunctionType { 4 | Function, 5 | Script, 6 | Method, 7 | Constructor, 8 | Scope, 9 | } 10 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/JStack.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler; 2 | 3 | public class JStack { 4 | public int count; 5 | T[] stack; 6 | int top; 7 | int size; 8 | 9 | static int MAX = 5000; 10 | static double GROW_RATE = 1.5; 11 | 12 | public JStack(int size) { 13 | this.size = size; 14 | stack = (T[]) new Object[size]; 15 | top = 0; 16 | } 17 | 18 | public void push(T t) { 19 | stack[top++] = t; 20 | count++; 21 | if (size - top < 32) { 22 | int newSize = (int) (size * GROW_RATE); 23 | T[] newStack = (T[]) new Object[newSize]; 24 | System.arraycopy(stack, 0, newStack, 0, size); 25 | stack = newStack; 26 | size = newSize; 27 | } 28 | if (count > MAX) { 29 | throw new RuntimeException("Stack overflow"); 30 | } 31 | } 32 | 33 | public T pop() { 34 | count--; 35 | return stack[--top]; 36 | } 37 | 38 | public T peek() { 39 | return peek(0); 40 | } 41 | 42 | public T peek(int offset) { 43 | return stack[top - offset - 1]; 44 | } 45 | 46 | public T get(int index) { 47 | return stack[index]; 48 | } 49 | 50 | public void set(int index, T t) { 51 | stack[index] = t; 52 | } 53 | 54 | public void setTop(int top) { 55 | this.top = top; 56 | count = top; 57 | } 58 | 59 | public void clear() { 60 | top = 0; 61 | count = 0; 62 | for (int i = 0; i < size; i++) { 63 | stack[i] = null; 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/OpCode.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler; 2 | 3 | public class OpCode { 4 | public static final int Return = 0x00; 5 | public static final int Constant = 0x01; 6 | public static final int Negate = 0x02; 7 | public static final int Increment = 0x03; 8 | public static final int Decrement = 0x04; 9 | public static final int Add = 0x05; 10 | public static final int Subtract = 0x06; 11 | public static final int Multiply = 0x07; 12 | public static final int Divide = 0x08; 13 | public static final int Modulo = 0x09; 14 | public static final int Power = 0x0A; 15 | public static final int Equal = 0x0B; 16 | public static final int LessThan = 0x0C; 17 | public static final int GreaterThan = 0x0D; 18 | public static final int Not = 0x0E; 19 | public static final int Pop = 0x0F; 20 | public static final int SetGlobal = 0x10; 21 | public static final int DefineGlobal = 0x11; 22 | public static final int GetGlobal = 0x12; 23 | public static final int GetLocal = 0x13; 24 | public static final int SetLocal = 0x14; 25 | public static final int Jump = 0x16; 26 | public static final int JumpIfFalse = 0x17; 27 | public static final int JumpIfTrue = 0x18; 28 | public static final int Loop = 0x19; 29 | public static final int For = 0x1A; 30 | public static final int StartCache = 0x1B; 31 | public static final int CollectLoop = 0x1C; 32 | public static final int FlushLoop = 0x1D; 33 | public static final int DefineLocal = 0x1E; 34 | public static final int Pattern = 0x1F; 35 | public static final int Call = 0x20; 36 | public static final int Closure = 0x21; 37 | public static final int GetUpvalue = 0x22; 38 | public static final int SetUpvalue = 0x23; 39 | public static final int MakeArray = 0x24; 40 | public static final int MakeMap = 0x25; 41 | public static final int Class = 0x26; 42 | public static final int Access = 0x27; 43 | public static final int Method = 0x28; 44 | public static final int MakeVar = 0x29; 45 | public static final int SetAttr = 0x2A; 46 | public static final int GetAttr = 0x2B; 47 | public static final int Index = 0x2C; 48 | public static final int Get = 0x2D; 49 | public static final int Null = 0x2E; 50 | public static final int Assert = 0x2F; 51 | public static final int Throw = 0x30; 52 | public static final int Import = 0x31; 53 | public static final int Enum = 0x32; 54 | public static final int BitAnd = 0x33; 55 | public static final int BitOr = 0x34; 56 | public static final int BitXor = 0x35; 57 | public static final int BitCompl = 0x36; 58 | public static final int LeftShift = 0x37; 59 | public static final int RightShift = 0x38; 60 | public static final int SignRightShift = 0x39; 61 | public static final int Copy = 0x3A; 62 | public static final int Iter = 0x3B; 63 | public static final int Spread = 0x3C; 64 | public static final int Ref = 0x3D; 65 | public static final int Deref = 0x3E; 66 | public static final int SetRef = 0x3F; 67 | public static final int ToBytes = 0x40; 68 | public static final int FromBytes = 0x41; 69 | public static final int Chain = 0x43; 70 | public static final int DropLocal = 0x44; 71 | public static final int DropGlobal = 0x45; 72 | public static final int DropUpvalue = 0x46; 73 | public static final int Header = 0x47; 74 | public static final int Destruct = 0x48; 75 | public static final int PatternVars = 0x49; 76 | public static final int Extend = 0x4B; 77 | } 78 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/headers/Cache.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler.headers; 2 | 3 | import lemon.jpizza.compiler.values.Value; 4 | 5 | public class Cache { 6 | String name; 7 | Value[] args; 8 | Value result; 9 | public Cache(String name, Value[] args, Value result) { 10 | this.name = name; 11 | this.args = args; 12 | this.result = result; 13 | } 14 | public boolean equals(Object o) { 15 | if (o instanceof Cache) { 16 | Cache c = (Cache) o; 17 | if (!c.name.equals(name)) return false; 18 | if (c.args.length != args.length) return false; 19 | for (int i = 0; i < args.length; i++) { 20 | if (!c.args[i].equals(args[i])) return false; 21 | } 22 | return true; 23 | } 24 | return false; 25 | } 26 | 27 | public boolean equals(String name, Value[] args) { 28 | if (!this.name.equals(name)) return false; 29 | if (this.args.length != args.length) return false; 30 | for (int i = 0; i < args.length; i++) { 31 | if (!this.args[i].equals(args[i])) return false; 32 | } 33 | return true; 34 | } 35 | 36 | public Value getValue() { 37 | return result; 38 | } 39 | 40 | public void store(Value result) { 41 | this.result = result; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/headers/HeadCode.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler.headers; 2 | 3 | public class HeadCode { 4 | public static final int Memoize = 0x0; 5 | public static final int SetMainFunction = 0x1; 6 | public static final int SetMainClass = 0x2; 7 | public static final int Export = 0x3; 8 | public static final int Package = 0x4; 9 | public static final int ExportTo = 0x5; 10 | } 11 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/headers/Memo.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler.headers; 2 | 3 | import lemon.jpizza.compiler.values.Value; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | import java.util.Stack; 8 | 9 | public class Memo { 10 | List caches; 11 | Stack stack; 12 | 13 | public Memo() { 14 | this.caches = new ArrayList<>(); 15 | this.stack = new Stack<>(); 16 | } 17 | 18 | public void stackCache(String name, Value[] args) { 19 | Cache c = new Cache(name, args, null); 20 | caches.add(c); 21 | stack.add(c); 22 | } 23 | 24 | public void storeCache(Value result) { 25 | stack.pop().store(result); 26 | } 27 | 28 | public Value get(String key, Value[] args) { 29 | for (Cache cache : caches) { 30 | if (cache.equals(key, args)) { 31 | return cache.getValue(); 32 | } 33 | } 34 | return null; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/libraries/GUIs.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler.libraries; 2 | 3 | import lemon.jpizza.compiler.types.Types; 4 | import lemon.jpizza.compiler.vm.JPExtension; 5 | import lemon.jpizza.compiler.vm.VM; 6 | 7 | import javax.imageio.ImageIO; 8 | import javax.swing.*; 9 | import java.awt.*; 10 | import java.io.IOException; 11 | import java.net.URL; 12 | 13 | public class GUIs extends JPExtension { 14 | 15 | static JFrame frame; 16 | 17 | @Override 18 | public String name() { return "guis"; } 19 | 20 | public GUIs(VM vm) { 21 | super(vm); 22 | } 23 | 24 | @Override 25 | public void setup() { 26 | 27 | func("createGUI", (args) -> { 28 | 29 | frame = new JFrame(args[0].asString()); 30 | frame.setTitle(args[0].asString()); 31 | frame.setFocusTraversalKeysEnabled(false); 32 | frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 33 | 34 | try { 35 | URL url = new URL("https://raw.githubusercontent.com/Lemon-Chad/jpizza/main/pizzico512.png"); 36 | Image image = ImageIO.read(url); 37 | frame.setIconImage(image); 38 | } catch (IOException e) { 39 | e.printStackTrace(); 40 | } 41 | 42 | return Ok; 43 | }, Types.VOID, Types.STRING); 44 | 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/libraries/Generators.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler.libraries; 2 | 3 | import lemon.jpizza.compiler.types.Types; 4 | import lemon.jpizza.compiler.vm.JPExtension; 5 | import lemon.jpizza.compiler.vm.VM; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | public class Generators extends JPExtension { 11 | @Override 12 | public String name() { return "gens"; } 13 | 14 | public Generators(VM vm) { 15 | super(vm); 16 | } 17 | 18 | @Override 19 | public void setup() { 20 | func("range", (args) -> { 21 | double start = args[0].asNumber(); 22 | double end = args[1].asNumber(); 23 | double step = args[2].asNumber(); 24 | List list = new ArrayList<>(); 25 | for (double i = start; i < end; i += step) 26 | list.add(i); 27 | return Ok(list); 28 | }, Types.LIST, Types.FLOAT, Types.FLOAT, Types.FLOAT); 29 | func("linear", (args) -> { 30 | double start = args[0].asNumber(); 31 | double end = args[1].asNumber(); 32 | double step = args[2].asNumber(); 33 | 34 | double m = args[3].asNumber(); 35 | double b = args[4].asNumber(); 36 | 37 | List list = new ArrayList<>(); 38 | for (double i = start; i < end; i += step) 39 | list.add(m * i + b); 40 | return Ok(list); 41 | }, Types.LIST, Types.FLOAT, Types.FLOAT, Types.FLOAT, Types.FLOAT, Types.FLOAT); 42 | func("quadratic", (args) -> { 43 | double start = args[0].asNumber(); 44 | double end = args[1].asNumber(); 45 | double step = args[2].asNumber(); 46 | 47 | double a = args[3].asNumber(); 48 | double b = args[4].asNumber(); 49 | double c = args[5].asNumber(); 50 | 51 | List list = new ArrayList<>(); 52 | for (double i = start; i < end; i += step) 53 | list.add(a * i * i + b * i + c); 54 | return Ok(list); 55 | }, Types.LIST, Types.FLOAT, Types.FLOAT, Types.FLOAT, Types.FLOAT, Types.FLOAT, Types.FLOAT); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/libraries/Time.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler.libraries; 2 | 3 | import lemon.jpizza.compiler.types.GenericType; 4 | import lemon.jpizza.compiler.types.Type; 5 | import lemon.jpizza.compiler.types.Types; 6 | import lemon.jpizza.compiler.types.objects.FuncType; 7 | import lemon.jpizza.compiler.values.Value; 8 | import lemon.jpizza.compiler.values.functions.NativeResult; 9 | import lemon.jpizza.compiler.vm.JPExtension; 10 | import lemon.jpizza.compiler.vm.VM; 11 | 12 | public class Time extends JPExtension { 13 | @Override 14 | public String name() { return "time"; } 15 | 16 | public Time(VM vm) { 17 | super(vm); 18 | } 19 | 20 | @Override 21 | public void setup() { 22 | func("epoch", (args) -> Ok(System.currentTimeMillis()), Types.INT); 23 | func("halt", (args) -> { 24 | try { 25 | Thread.sleep(args[0].asNumber().intValue()); 26 | } catch (InterruptedException e) { 27 | return Err("Internal", "Interrupted"); 28 | } 29 | return Ok; 30 | }, Types.VOID, Types.INT); 31 | func("stopwatch", (args) -> { 32 | long start = System.currentTimeMillis(); 33 | NativeResult ret = VM.Run(args[0].asClosure(), new Value[0]); 34 | if (!ret.ok()) return ret; 35 | long end = System.currentTimeMillis(); 36 | return Ok(end - start); 37 | }, Types.INT, new FuncType(Types.VOID, new Type[0], new GenericType[0], false) ); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/libraries/awt/config/Canvas.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler.libraries.awt.config; 2 | 3 | import lemon.jpizza.compiler.libraries.awt.displays.Drawable; 4 | import lemon.jpizza.compiler.libraries.awt.displays.Rectangle; 5 | 6 | import javax.swing.*; 7 | import java.awt.*; 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | import java.util.Map; 11 | import java.util.Objects; 12 | import java.util.concurrent.ConcurrentHashMap; 13 | 14 | public class Canvas extends JPanel { 15 | Queue> drawings; 16 | Queue> colors; 17 | Queue> pixels; 18 | boolean painting; 19 | JFont font; 20 | 21 | public Canvas() { 22 | drawings = new Queue<>(new ArrayList<>()); 23 | colors = new Queue<>(new ArrayList<>()); 24 | pixels = new Queue<>(new ConcurrentHashMap<>()); 25 | painting = false; 26 | font = null; 27 | } 28 | 29 | public void flush() { 30 | drawings.get().clear(); 31 | drawings.next().clear(); 32 | colors.get().clear(); 33 | colors.next().clear(); 34 | pixels.get().clear(); 35 | pixels.next().clear(); 36 | } 37 | 38 | public void add(List drawables, List colors, Map pixels) { 39 | this.drawings.add(new ArrayList<>(drawables)); 40 | this.colors.add(new ArrayList<>(colors)); 41 | this.pixels.add(new ConcurrentHashMap<>(pixels)); 42 | } 43 | 44 | public static void colorPush(Drawable drawing, List drawables, List colors) { 45 | if (colors.size() > 0 && Objects.equals(drawing.color(), colors.get(colors.size() - 1).color)) { 46 | colors.get(colors.size() - 1).span++; 47 | } 48 | else { 49 | colors.add(new ColorSpan(1, drawing.color())); 50 | } 51 | drawables.add(drawing); 52 | } 53 | 54 | public void setPixel(Point point, Color color) { 55 | Rectangle rect = new Rectangle(point.x, point.y, 1, 1, color); 56 | 57 | if (pixels.get().containsKey(point)) { 58 | pixels.get().replace(point, rect); 59 | } 60 | else { 61 | pixels.get().put(point, rect); 62 | } 63 | } 64 | 65 | @Override 66 | public void paintComponent(Graphics g) { 67 | super.paintComponent(g); 68 | 69 | pixels.advance(); 70 | drawings.advance(); 71 | colors.advance(); 72 | 73 | List drawings = this.drawings.get(); 74 | List colors = this.colors.get(); 75 | Map pixels = this.pixels.get(); 76 | 77 | if (font != null) { 78 | g.setFont(font.getFont()); 79 | } 80 | 81 | for (Rectangle rect : pixels.values()) { 82 | g.setColor(rect.color()); 83 | rect.draw(g); 84 | } 85 | 86 | int i = 0; 87 | for (int j = 0; j < colors.size() && i < drawings.size(); j++) { 88 | ColorSpan span = colors.get(j); 89 | if (span.color != null) 90 | g.setColor(span.color); 91 | for (int k = 0; k < span.span && i + k < drawings.size(); k++) { 92 | Drawable drawing = drawings.get(i + k); 93 | drawing.draw(g, this); 94 | } 95 | i += span.span; 96 | } 97 | } 98 | 99 | public void draw(Drawable drawing) { 100 | colorPush(drawing, drawings.get(), colors.get()); 101 | } 102 | 103 | } 104 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/libraries/awt/config/ColorSpan.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler.libraries.awt.config; 2 | 3 | import java.awt.*; 4 | 5 | public class ColorSpan { 6 | public int span; 7 | public Color color; 8 | 9 | public ColorSpan(int span, Color color) { 10 | this.span = span; 11 | this.color = color; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/libraries/awt/config/JFont.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler.libraries.awt.config; 2 | 3 | import java.awt.*; 4 | 5 | public class JFont { 6 | private final String fontName; 7 | private final int style; 8 | private final int size; 9 | 10 | public JFont(String fontName, int style, int size) { 11 | this.fontName = fontName; 12 | this.style = style; 13 | this.size = size; 14 | } 15 | 16 | public Font getFont() { 17 | return new Font(fontName, style, size); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/libraries/awt/config/Queue.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler.libraries.awt.config; 2 | 3 | public class Queue { 4 | private T head; 5 | private T tail; 6 | 7 | public Queue(T head) { 8 | this.head = head; 9 | this.tail = head; 10 | } 11 | 12 | public void advance() { 13 | head = tail; 14 | } 15 | 16 | public T get() { 17 | return head; 18 | } 19 | 20 | public T next() { 21 | return tail; 22 | } 23 | 24 | public void add(T t) { 25 | tail = t; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/libraries/awt/displays/Drawable.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler.libraries.awt.displays; 2 | 3 | import lemon.jpizza.compiler.libraries.awt.config.Canvas; 4 | 5 | import java.awt.*; 6 | 7 | public abstract class Drawable { 8 | public void draw(Graphics g, Canvas canvas) { 9 | draw(g); 10 | } 11 | protected abstract void draw(Graphics g); 12 | 13 | public abstract Color color(); 14 | } 15 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/libraries/awt/displays/Img.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler.libraries.awt.displays; 2 | 3 | import lemon.jpizza.compiler.libraries.awt.config.Canvas; 4 | 5 | import javax.swing.*; 6 | import java.awt.*; 7 | import java.io.File; 8 | import java.io.IOException; 9 | import java.net.URL; 10 | 11 | public class Img extends Drawable { 12 | private final int x, y; 13 | private Image img; 14 | 15 | public Img(String path, int x, int y) throws IOException { 16 | // Load file with ImageIcon 17 | URL url; 18 | 19 | File file = new File(path); 20 | if (file.exists()) { 21 | url = file.toURI().toURL(); 22 | } 23 | else { 24 | url = new URL(path); 25 | } 26 | ImageIcon icon = new ImageIcon(url); 27 | img = icon.getImage(); 28 | 29 | // Set position 30 | this.x = x; 31 | this.y = y; 32 | } 33 | 34 | public Img(String path, int x, int y, int w, int h) throws IOException { 35 | this(path, x, y); 36 | img = img.getScaledInstance(w, h, Image.SCALE_FAST); 37 | } 38 | 39 | @Override 40 | public Color color() { 41 | return null; 42 | } 43 | 44 | @Override 45 | public void draw(Graphics g, Canvas canvas) { 46 | g.drawImage(img, x, y, canvas); 47 | } 48 | 49 | @Override 50 | protected void draw(Graphics g) { 51 | // Do nothing 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/libraries/awt/displays/Line.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler.libraries.awt.displays; 2 | 3 | import java.awt.*; 4 | 5 | public class Line extends Drawable { 6 | private final Point start, end; 7 | private final Color color; 8 | private final int width; 9 | 10 | public Line(Point start, Point end, Color color, int width) { 11 | this.start = start; 12 | this.end = end; 13 | this.color = color; 14 | this.width = width; 15 | } 16 | 17 | @Override 18 | public Color color() { 19 | return color; 20 | } 21 | 22 | @Override 23 | public void draw(Graphics g) { 24 | if (width != -1) { 25 | Graphics2D g2d = (Graphics2D) g; 26 | g2d.setStroke(new BasicStroke(width)); 27 | } 28 | g.drawLine(start.x, start.y, end.x, end.y); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/libraries/awt/displays/Oval.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler.libraries.awt.displays; 2 | 3 | import java.awt.*; 4 | 5 | public class Oval extends Drawable { 6 | private final int x, y; 7 | private final int w, h; 8 | private final Color color; 9 | 10 | public Oval(int x, int y, int w, int h, Color color) { 11 | this.x = x; 12 | this.y = y; 13 | this.w = w; 14 | this.h = h; 15 | this.color = color; 16 | } 17 | 18 | @Override 19 | public Color color() { 20 | return color; 21 | } 22 | 23 | @Override 24 | public void draw(Graphics g) { 25 | g.fillOval(x, y, w, h); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/libraries/awt/displays/Polygon.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler.libraries.awt.displays; 2 | 3 | import java.awt.*; 4 | 5 | public class Polygon extends Drawable { 6 | private final int[] x, y; 7 | private final Color color; 8 | private final boolean filled; 9 | private final int width; 10 | 11 | public Polygon(Point[] points, Color color, boolean filled, int width) { 12 | this.x = new int[points.length]; 13 | this.y = new int[points.length]; 14 | for (int i = 0; i < points.length; i++) { 15 | x[i] = points[i].x; 16 | y[i] = points[i].y; 17 | } 18 | this.color = color; 19 | this.filled = filled; 20 | this.width = width; 21 | } 22 | 23 | @Override 24 | public void draw(Graphics g) { 25 | if (width != -1) { 26 | Graphics2D g2d = (Graphics2D) g; 27 | g2d.setStroke(new BasicStroke(width)); 28 | } 29 | 30 | if (filled) { 31 | g.fillPolygon(x, y, x.length); 32 | } 33 | else { 34 | g.drawPolygon(x, y, x.length); 35 | } 36 | } 37 | 38 | @Override 39 | public Color color() { 40 | return color; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/libraries/awt/displays/Rectangle.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler.libraries.awt.displays; 2 | 3 | import java.awt.*; 4 | 5 | public class Rectangle extends Drawable { 6 | private final int x, y; 7 | private final int w, h; 8 | private final Color color; 9 | 10 | public Rectangle(int x, int y, int w, int h, Color color) { 11 | this.x = x; 12 | this.y = y; 13 | this.w = w; 14 | this.h = h; 15 | this.color = color; 16 | } 17 | 18 | @Override 19 | public void draw(Graphics g) { 20 | g.fillRect(x, y, w, h); 21 | } 22 | 23 | @Override 24 | public Color color() { 25 | return color; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/libraries/awt/displays/Text.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler.libraries.awt.displays; 2 | 3 | import lemon.jpizza.compiler.libraries.awt.config.JFont; 4 | 5 | import java.awt.*; 6 | 7 | public class Text extends Drawable { 8 | private final String text; 9 | private final int x, y; 10 | private final Color color; 11 | private final JFont font; 12 | 13 | public Text(String text, int x, int y, Color color, JFont font) { 14 | this.text = text; 15 | this.x = x; 16 | this.y = y; 17 | this.color = color; 18 | this.font = font; 19 | } 20 | 21 | @Override 22 | public void draw(Graphics g) { 23 | if (font != null) { 24 | g.setFont(font.getFont()); 25 | } 26 | g.drawString(text, x, y); 27 | } 28 | 29 | @Override 30 | public Color color() { 31 | return color; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/libraries/pretzel/Pretzel.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler.libraries.pretzel; 2 | 3 | import com.sun.net.httpserver.HttpServer; 4 | import lemon.jpizza.compiler.types.GenericType; 5 | import lemon.jpizza.compiler.types.Type; 6 | import lemon.jpizza.compiler.types.Types; 7 | import lemon.jpizza.compiler.types.objects.FuncType; 8 | import lemon.jpizza.compiler.values.functions.JClosure; 9 | import lemon.jpizza.compiler.vm.JPExtension; 10 | import lemon.jpizza.compiler.vm.VM; 11 | 12 | import java.io.IOException; 13 | import java.net.InetSocketAddress; 14 | import java.util.Arrays; 15 | 16 | public class Pretzel extends JPExtension { 17 | private HttpServer server; 18 | 19 | @Override 20 | public String name() { 21 | return "pretzel"; 22 | } 23 | 24 | public Pretzel(VM vm) { 25 | super(vm); 26 | } 27 | 28 | @Override 29 | public void setup() { 30 | func("init", args -> { 31 | String host = args[0].toString(); 32 | int port = args[1].asNumber().intValue(); 33 | 34 | try { 35 | server = HttpServer.create(new InetSocketAddress(host, port), 0); 36 | } catch (IOException e) { 37 | return Err("Host", e.getMessage()); 38 | } 39 | 40 | return Ok; 41 | }, Types.VOID, Types.STRING, Types.INT); 42 | func("route", args -> { 43 | if (server == null) { 44 | return Err("Init", "Server not initialized"); 45 | } 46 | 47 | String path = args[0].toString(); 48 | JClosure handler = args[1].asClosure(); 49 | 50 | server.createContext(path, new Handle(path, handler)); 51 | 52 | return Ok; 53 | }, Types.VOID, Types.STRING, new FuncType(Types.DICT, new Type[]{ Types.DICT }, new GenericType[0], false)); 54 | func("start", args -> { 55 | if (server == null) { 56 | return Err("Init", "Server not initialized"); 57 | } 58 | 59 | server.start(); 60 | 61 | return Ok; 62 | }, Types.VOID); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/libraries/puddle/ClientPDL.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler.libraries.puddle; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | import java.io.OutputStream; 6 | import java.net.Socket; 7 | 8 | public class ClientPDL { 9 | private final int id; 10 | private final OutputStream outputStream; 11 | private final InputStream inputStream; 12 | 13 | private ClientPDL(Socket socket) throws IOException { 14 | outputStream = socket.getOutputStream(); 15 | inputStream = socket.getInputStream(); 16 | 17 | id = hashCode(); 18 | PDL.clients.put(id, this); 19 | } 20 | 21 | public static int Create(Socket socket) throws IOException { 22 | return new ClientPDL(socket).id; 23 | } 24 | 25 | public void write(byte[] data, int off, int len) throws IOException { 26 | outputStream.write(data, off, len); 27 | } 28 | 29 | public byte[] read(int off, int len) throws IOException { 30 | byte[] data = new byte[len]; 31 | //noinspection ResultOfMethodCallIgnored 32 | inputStream.read(data, off, len); 33 | return data; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/libraries/puddle/PDL.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler.libraries.puddle; 2 | 3 | import lemon.jpizza.compiler.types.Type; 4 | import lemon.jpizza.compiler.types.Types; 5 | import lemon.jpizza.compiler.values.Value; 6 | import lemon.jpizza.compiler.values.functions.NativeResult; 7 | import lemon.jpizza.compiler.vm.JPExtension; 8 | import lemon.jpizza.compiler.vm.VM; 9 | 10 | import java.io.IOException; 11 | import java.net.Socket; 12 | import java.util.*; 13 | 14 | public class PDL extends JPExtension { 15 | public static Map servers = new HashMap<>(); 16 | public static Map clients = new HashMap<>(); 17 | 18 | @Override 19 | public String name() { 20 | return "pdl"; 21 | } 22 | 23 | public PDL(VM vm) { 24 | super(vm); 25 | } 26 | 27 | interface IOMethod { 28 | NativeResult call(Value[] args) throws IOException; 29 | } 30 | 31 | private void iofunc(String name, IOMethod method, Type returnType, Type... argTypes) { 32 | func(name, args -> { 33 | try { 34 | return method.call(args); 35 | } catch (IOException e) { 36 | return Err("Connection", e.getMessage()); 37 | } 38 | }, returnType, argTypes); 39 | } 40 | 41 | interface ClientMethod { 42 | NativeResult call(ClientPDL client) throws IOException; 43 | } 44 | 45 | NativeResult asClient(int id, ClientMethod method) throws IOException { 46 | ClientPDL client = clients.get(id); 47 | if (client == null) { 48 | return Err("Client", "No such client"); 49 | } 50 | return method.call(client); 51 | } 52 | 53 | interface ServerMethod { 54 | NativeResult call(ServerPDL server) throws IOException; 55 | } 56 | 57 | NativeResult asServer(int id, ServerMethod method) throws IOException { 58 | ServerPDL server = servers.get(id); 59 | if (server == null) { 60 | return Err("Server", "No such server"); 61 | } 62 | return method.call(server); 63 | } 64 | 65 | @Override 66 | public void setup() { 67 | // Client 68 | iofunc("connect", args -> { 69 | String host = args[0].toString(); 70 | int port = args[1].asNumber().intValue(); 71 | Socket sock = new Socket(host, port); 72 | int id = ClientPDL.Create(sock); 73 | return Ok(id); 74 | }, Types.INT, Types.STRING, Types.INT); 75 | iofunc("write", args -> { 76 | int id = args[0].asNumber().intValue(); 77 | byte[] data = args[1].asBytes(); 78 | int offset = args[2].asNumber().intValue(); 79 | int length = args[3].asNumber().intValue(); 80 | return asClient(id, client -> { 81 | client.write(data, offset, length); 82 | return Ok; 83 | }); 84 | }, Types.VOID, Types.INT, Types.BYTES, Types.INT, Types.INT); 85 | iofunc("read", args -> { 86 | int id = args[0].asNumber().intValue(); 87 | int offset = args[1].asNumber().intValue(); 88 | int length = args[2].asNumber().intValue(); 89 | return asClient(id, client -> Ok(client.read(offset, length))); 90 | }, Types.BYTES, Types.INT, Types.INT, Types.INT); 91 | 92 | // Server 93 | iofunc("host", args -> { 94 | int port = args[0].asNumber().intValue(); 95 | return Ok(ServerPDL.Create(port)); 96 | }, Types.INT, Types.INT); 97 | iofunc("accept", args -> { 98 | int id = args[0].asNumber().intValue(); 99 | return asServer(id, server -> Ok(server.accept())); 100 | }, Types.INT, Types.INT); 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/libraries/puddle/ServerPDL.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler.libraries.puddle; 2 | 3 | import java.io.IOException; 4 | import java.net.ServerSocket; 5 | 6 | public class ServerPDL { 7 | private final ServerSocket inner; 8 | private final int id; 9 | 10 | private ServerPDL(int port) throws IOException { 11 | inner = new ServerSocket(port); 12 | id = hashCode(); 13 | PDL.servers.put(id, this); 14 | } 15 | 16 | public static int Create(int port) throws IOException { 17 | return new ServerPDL(port).id; 18 | } 19 | 20 | public int accept() throws IOException { 21 | return ClientPDL.Create(inner.accept()); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/types/AnyType.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler.types; 2 | 3 | import lemon.jpizza.TokenType; 4 | import lemon.jpizza.compiler.types.primitives.PrimitiveType; 5 | 6 | public class AnyType extends PrimitiveType { 7 | static final AnyType INSTANCE = new AnyType(); 8 | 9 | private AnyType() { 10 | super("any"); 11 | } 12 | 13 | @Override 14 | protected Type operation(TokenType operation, Type other) { 15 | return INSTANCE; 16 | } 17 | 18 | @Override 19 | protected Type operation(TokenType operation) { 20 | return INSTANCE; 21 | } 22 | 23 | @Override 24 | public int[] dump() { 25 | return new int[]{TypeCodes.ANY}; 26 | } 27 | 28 | @Override 29 | public boolean equals(Object o) { 30 | return o instanceof Type; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/types/GenericType.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler.types; 2 | 3 | import lemon.jpizza.TokenType; 4 | import lemon.jpizza.compiler.values.Value; 5 | 6 | import java.util.Map; 7 | 8 | public class GenericType extends Type { 9 | public GenericType(String name) { 10 | super(name); 11 | } 12 | 13 | @Override 14 | protected Type operation(TokenType operation, Type other) { 15 | return null; 16 | } 17 | 18 | @Override 19 | protected Type operation(TokenType operation) { 20 | return null; 21 | } 22 | 23 | @Override 24 | public Type call(Type[] arguments, Type[] generics) { 25 | return null; 26 | } 27 | 28 | @Override 29 | public Type access(String name) { 30 | return null; 31 | } 32 | 33 | @Override 34 | public Type accessInternal(String name) { 35 | return null; 36 | } 37 | 38 | @Override 39 | public int[] dump() { 40 | int[] name = Value.dumpString(this.name); 41 | int[] result = new int[name.length + 1]; 42 | result[0] = TypeCodes.GENERIC; 43 | System.arraycopy(name, 0, result, 1, name.length); 44 | return result; 45 | } 46 | 47 | @Override 48 | public boolean equals(Object o) { 49 | return o instanceof GenericType && ((GenericType) o).name.equals(this.name); 50 | } 51 | 52 | @Override 53 | public int hashCode() { 54 | return this.name.hashCode(); 55 | } 56 | 57 | @Override 58 | public String toString() { 59 | return this.name; 60 | } 61 | 62 | @Override 63 | public Type applyGenerics(final Map generics) { 64 | return generics.getOrDefault(this, this); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/types/SpreadType.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler.types; 2 | 3 | import lemon.jpizza.TokenType; 4 | import lemon.jpizza.compiler.types.primitives.PrimitiveType; 5 | 6 | public class SpreadType extends PrimitiveType { 7 | static final SpreadType INSTANCE = new SpreadType(); 8 | 9 | private SpreadType() { 10 | super("spread"); 11 | } 12 | 13 | @Override 14 | protected Type operation(TokenType operation, Type other) { 15 | return null; 16 | } 17 | 18 | @Override 19 | protected Type operation(TokenType operation) { 20 | return null; 21 | } 22 | 23 | @Override 24 | public int[] dump() { 25 | return new int[]{TypeCodes.VOID}; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/types/Type.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler.types; 2 | 3 | import lemon.jpizza.TokenType; 4 | import lemon.jpizza.compiler.ChunkCode; 5 | 6 | import java.util.Arrays; 7 | import java.util.Collections; 8 | import java.util.List; 9 | import java.util.Map; 10 | import java.util.stream.Collectors; 11 | 12 | public abstract class Type { 13 | public String name; 14 | 15 | public Type(final String name) { 16 | this.name = name; 17 | } 18 | 19 | public boolean callable() { 20 | return false; 21 | } 22 | 23 | // Binary operations 24 | // If it returns null, operation is incompatible 25 | protected abstract Type operation(final TokenType operation, final Type other); 26 | public Type isCompatible(final TokenType operation, final Type other) { 27 | if (operation == TokenType.EqualEqual || operation == TokenType.BangEqual) { 28 | return Types.BOOL; 29 | } 30 | else if (other instanceof AnyType) { 31 | return Types.ANY; 32 | } 33 | else if (operation == TokenType.Colon) { 34 | return this instanceof VoidType ? other : this; 35 | } 36 | return operation(operation, other); 37 | } 38 | 39 | // Unary operations 40 | // If it returns null, operation is incompatible 41 | protected abstract Type operation(TokenType operation); 42 | public Type isCompatible(TokenType operation) { 43 | return operation(operation); 44 | } 45 | 46 | public abstract Type call(final Type[] arguments, final Type[] generics); 47 | 48 | public List accessors() { 49 | return null; 50 | } 51 | public abstract Type access(final String name); 52 | public abstract Type accessInternal(final String name); 53 | 54 | @Override 55 | public String toString() { 56 | return name; 57 | } 58 | 59 | @Override 60 | public boolean equals(Object o) { 61 | return this == o; 62 | } 63 | 64 | public int[] compile() { 65 | int[] dump = dump(); 66 | int[] result = new int[dump.length + 1]; 67 | result[0] = ChunkCode.Type; 68 | System.arraycopy(dump, 0, result, 1, dump.length); 69 | return result; 70 | } 71 | 72 | public abstract int[] dump(); 73 | 74 | public abstract Type applyGenerics(final Map generics); 75 | 76 | public List dumpList() { 77 | return Arrays.stream(compile()).boxed().collect(Collectors.toList()); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/types/TypeCodes.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler.types; 2 | 3 | public class TypeCodes { 4 | public static final int BOOL = 0; 5 | public static final int BYTES = 1; 6 | public static final int DICT = 2; 7 | public static final int FLOAT = 3; 8 | public static final int INT = 4; 9 | public static final int LIST = 5; 10 | public static final int RESULT = 6; 11 | public static final int STRING = 7; 12 | public static final int ANY = 8; 13 | public static final int GENERIC = 9; 14 | public static final int VOID = 10; 15 | public static final int CLASS = 11; 16 | public static final int ENUMCHILD = 12; 17 | public static final int ENUM = 13; 18 | public static final int FUNC = 14; 19 | public static final int INSTANCE = 15; 20 | public static final int NAMESPACE = 16; 21 | public static final int REFERENCE = 17; 22 | public static final int MAYBE = 18; 23 | public static final int MAP = 19; 24 | public static final int VEC = 20; 25 | public static final int TUPLE = 21; 26 | } 27 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/types/Types.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler.types; 2 | 3 | import lemon.jpizza.compiler.types.primitives.*; 4 | 5 | public class Types { 6 | public static final VoidType VOID = VoidType.INSTANCE; 7 | public static final AnyType ANY = AnyType.INSTANCE; 8 | public static final IntType INT = PrimitiveTypes.INT; 9 | public static final FloatType FLOAT = PrimitiveTypes.FLOAT; 10 | public static final BooleanType BOOL = PrimitiveTypes.BOOL; 11 | public static final ListType LIST = PrimitiveTypes.LIST; 12 | public static final DictType DICT = PrimitiveTypes.DICT; 13 | public static final StringType STRING = PrimitiveTypes.STRING; 14 | public static final BytesType BYTES = PrimitiveTypes.BYTES; 15 | public static final ResultType RESULT = PrimitiveTypes.RESULT; 16 | public static final SpreadType SPREAD = SpreadType.INSTANCE; 17 | } 18 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/types/VoidType.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler.types; 2 | 3 | import lemon.jpizza.TokenType; 4 | import lemon.jpizza.compiler.types.primitives.PrimitiveType; 5 | 6 | public class VoidType extends PrimitiveType { 7 | static final VoidType INSTANCE = new VoidType(); 8 | 9 | private VoidType() { 10 | super("void"); 11 | } 12 | 13 | @Override 14 | protected Type operation(TokenType operation, Type other) { 15 | return null; 16 | } 17 | 18 | @Override 19 | protected Type operation(TokenType operation) { 20 | return null; 21 | } 22 | 23 | @Override 24 | public int[] dump() { 25 | return new int[]{TypeCodes.VOID}; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/types/objects/EnumChildType.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler.types.objects; 2 | 3 | import lemon.jpizza.TokenType; 4 | import lemon.jpizza.compiler.types.GenericType; 5 | import lemon.jpizza.compiler.types.Type; 6 | import lemon.jpizza.compiler.types.TypeCodes; 7 | import lemon.jpizza.compiler.values.Value; 8 | 9 | import java.util.*; 10 | 11 | public class EnumChildType extends Type { 12 | public final Type[] propertyArguments; 13 | public final GenericType[] propertyGenerics; 14 | public final Map propertyGenericMap; 15 | public final String[] properties; 16 | public final ClassType asClass; 17 | 18 | public EnumChildType(String name, Type[] propertyArguments, GenericType[] propertyGenerics, String[] properties) { 19 | super(name); 20 | this.propertyArguments = propertyArguments; 21 | this.propertyGenerics = propertyGenerics; 22 | this.propertyGenericMap = new HashMap<>(); 23 | this.properties = properties; 24 | 25 | Map map = new HashMap<>(); 26 | for (int i = 0; i < properties.length; i++) { 27 | map.put(properties[i], propertyArguments[i]); 28 | } 29 | for (int i = 0; i < propertyGenerics.length; i++) { 30 | map.put(propertyGenerics[i].name, propertyGenerics[i]); 31 | } 32 | this.asClass = new ClassType(name, null, null, map, new HashSet<>(), new HashMap<>(), new HashMap<>(), propertyGenerics); 33 | } 34 | 35 | @Override 36 | public boolean callable() { 37 | return true; 38 | } 39 | 40 | @Override 41 | public Type applyGenerics(Map generics) { 42 | Type[] arguments = new Type[propertyArguments.length]; 43 | for (int i = 0; i < arguments.length; i++) { 44 | arguments[i] = propertyArguments[i].applyGenerics(generics); 45 | } 46 | return new EnumChildType(name, arguments, propertyGenerics, properties); 47 | } 48 | 49 | @Override 50 | protected Type operation(TokenType operation, Type other) { 51 | return null; 52 | } 53 | 54 | @Override 55 | protected Type operation(TokenType operation) { 56 | return null; 57 | } 58 | 59 | @Override 60 | public Type call(Type[] arguments, Type[] generics) { 61 | Map map = new HashMap<>(); 62 | for (int i = 0; i < generics.length; i++) { 63 | map.put(propertyGenerics[i], generics[i]); 64 | } 65 | 66 | if (arguments.length != propertyArguments.length) { 67 | return null; 68 | } 69 | for (int i = 0; i < arguments.length; i++) { 70 | if (!propertyArguments[i].applyGenerics(map).equals(arguments[i])) { 71 | return null; 72 | } 73 | } 74 | if (generics.length != propertyGenerics.length) { 75 | return null; 76 | } 77 | return new InstanceType(asClass, generics); 78 | } 79 | 80 | @Override 81 | public Type access(String name) { 82 | return null; 83 | } 84 | 85 | @Override 86 | public Type accessInternal(String name) { 87 | return null; 88 | } 89 | 90 | @Override 91 | public int[] dump() { 92 | List list = new ArrayList<>(); 93 | list.add(TypeCodes.ENUMCHILD); 94 | Value.addAllString(list, name); 95 | list.add(propertyArguments.length); 96 | for (Type type : propertyArguments) { 97 | list.addAll(type.dumpList()); 98 | } 99 | list.add(propertyGenerics.length); 100 | for (GenericType type : propertyGenerics) { 101 | list.addAll(type.dumpList()); 102 | } 103 | list.add(properties.length); 104 | for (String property : properties) { 105 | Value.addAllString(list, property); 106 | } 107 | return list.stream().mapToInt(Integer::intValue).toArray(); 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/types/objects/EnumType.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler.types.objects; 2 | 3 | import lemon.jpizza.TokenType; 4 | import lemon.jpizza.compiler.types.Type; 5 | import lemon.jpizza.compiler.types.TypeCodes; 6 | import lemon.jpizza.compiler.values.Value; 7 | 8 | import java.util.*; 9 | 10 | public class EnumType extends Type { 11 | public final Map children; 12 | public EnumType(String name, EnumChildType[] children) { 13 | super(name); 14 | this.children = new HashMap<>(children.length); 15 | for (EnumChildType child : children) { 16 | this.children.put(child.name, child); 17 | } 18 | } 19 | 20 | @Override 21 | protected Type operation(TokenType operation, Type other) { 22 | return null; 23 | } 24 | 25 | @Override 26 | protected Type operation(TokenType operation) { 27 | return null; 28 | } 29 | 30 | @Override 31 | public Type call(Type[] arguments, Type[] generics) { 32 | return null; 33 | } 34 | 35 | @Override 36 | public Type access(String name) { 37 | return children.get(name); 38 | } 39 | 40 | @Override 41 | public List accessors() { 42 | return new ArrayList<>(children.keySet()); 43 | } 44 | 45 | @Override 46 | public Type accessInternal(String name) { 47 | return null; 48 | } 49 | 50 | @Override 51 | public int[] dump() { 52 | List list = new ArrayList<>(); 53 | list.add(TypeCodes.ENUM); 54 | Value.addAllString(list, name); 55 | list.add(children.size()); 56 | for (EnumChildType child : children.values()) { 57 | list.addAll(child.dumpList()); 58 | } 59 | return list.stream().mapToInt(Integer::intValue).toArray(); 60 | } 61 | 62 | @Override 63 | public Type applyGenerics(Map generics) { 64 | EnumChildType[] newChildren = new EnumChildType[children.size()]; 65 | int i = 0; 66 | for (EnumChildType child : children.values()) { 67 | newChildren[i++] = (EnumChildType) child.applyGenerics(generics); 68 | } 69 | return new EnumType(name, newChildren); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/types/objects/MapType.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler.types.objects; 2 | 3 | import lemon.jpizza.TokenType; 4 | import lemon.jpizza.compiler.types.Type; 5 | import lemon.jpizza.compiler.types.TypeCodes; 6 | import lemon.jpizza.compiler.types.Types; 7 | import lemon.jpizza.compiler.types.primitives.PrimitiveType; 8 | 9 | public class MapType extends PrimitiveType { 10 | private final Type keyType; 11 | private final Type valueType; 12 | 13 | public MapType(Type keyType, Type valueType) { 14 | super("map<" + keyType.toString() + "," + valueType.toString() + ">"); 15 | this.keyType = keyType; 16 | this.valueType = valueType; 17 | } 18 | 19 | @Override 20 | protected Type operation(TokenType operation, Type other) { 21 | if (operation == TokenType.LeftBracket || operation == TokenType.Dot) { 22 | if (!other.equals(keyType)) 23 | return null; 24 | return valueType; 25 | } 26 | return null; 27 | } 28 | 29 | @Override 30 | protected Type operation(TokenType operation) { 31 | return null; 32 | } 33 | 34 | @Override 35 | public int[] dump() { 36 | int[] key = keyType.dump(); 37 | int[] value = valueType.dump(); 38 | int[] result = new int[key.length + value.length + 1]; 39 | result[0] = TypeCodes.MAP; 40 | System.arraycopy(key, 0, result, 1, key.length); 41 | System.arraycopy(value, 0, result, key.length + 1, value.length); 42 | return result; 43 | } 44 | 45 | @Override 46 | public boolean equals(Object obj) { 47 | if (obj instanceof MapType) { 48 | MapType other = (MapType) obj; 49 | return keyType.equals(other.keyType) && valueType.equals(other.valueType); 50 | } 51 | return false; 52 | } 53 | 54 | public Type getKeyType() { 55 | return keyType; 56 | } 57 | 58 | public Type getValueType() { 59 | return valueType; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/types/objects/MaybeType.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler.types.objects; 2 | 3 | import lemon.jpizza.TokenType; 4 | import lemon.jpizza.compiler.types.Type; 5 | import lemon.jpizza.compiler.types.TypeCodes; 6 | import lemon.jpizza.compiler.types.primitives.PrimitiveType; 7 | 8 | public class MaybeType extends PrimitiveType { 9 | private final Type optionalType; 10 | 11 | public MaybeType(Type optionalType) { 12 | super("?" + optionalType.toString()); 13 | this.optionalType = optionalType; 14 | } 15 | 16 | @Override 17 | protected Type operation(TokenType operation, Type other) { 18 | return null; 19 | } 20 | 21 | @Override 22 | protected Type operation(TokenType operation) { 23 | return null; 24 | } 25 | 26 | @Override 27 | public int[] dump() { 28 | int[] subtype = optionalType.dump(); 29 | int[] result = new int[subtype.length + 1]; 30 | result[0] = TypeCodes.MAYBE; 31 | System.arraycopy(subtype, 0, result, 1, subtype.length); 32 | return result; 33 | } 34 | 35 | @Override 36 | public boolean equals(Object other) { 37 | if (other instanceof MaybeType) { 38 | return optionalType.equals(((MaybeType)other).optionalType); 39 | } 40 | return false; 41 | } 42 | 43 | public Type getOptionalType() { 44 | return optionalType; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/types/objects/MethodType.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler.types.objects; 2 | 3 | import lemon.jpizza.TokenType; 4 | import lemon.jpizza.compiler.types.Type; 5 | 6 | import java.util.Map; 7 | 8 | public class MethodType extends Type { 9 | public final FuncType funcType; 10 | public final Map generics; 11 | 12 | public MethodType(FuncType inner, Map generics) { 13 | super("method"); 14 | this.funcType = inner; 15 | this.generics = generics; 16 | } 17 | 18 | @Override 19 | public boolean callable() { 20 | return true; 21 | } 22 | 23 | @Override 24 | public Type applyGenerics(Map generics) { 25 | return new MethodType((FuncType) funcType.applyGenerics(generics), generics); 26 | } 27 | 28 | @Override 29 | protected Type operation(TokenType operation, Type other) { 30 | return null; 31 | } 32 | 33 | @Override 34 | protected Type operation(TokenType operation) { 35 | return null; 36 | } 37 | 38 | @Override 39 | public Type call(Type[] arguments, Type[] generics) { 40 | return funcType.call(arguments, generics, this.generics); 41 | } 42 | 43 | @Override 44 | public Type access(String name) { 45 | return null; 46 | } 47 | 48 | @Override 49 | public Type accessInternal(String name) { 50 | return null; 51 | } 52 | 53 | @SuppressWarnings("EqualsWhichDoesntCheckParameterClass") 54 | @Override 55 | public boolean equals(Object o) { 56 | return funcType.equals(o); 57 | } 58 | 59 | @Override 60 | public int[] dump() { 61 | return funcType.dump(); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/types/objects/NamespaceType.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler.types.objects; 2 | 3 | import lemon.jpizza.TokenType; 4 | import lemon.jpizza.compiler.types.Type; 5 | import lemon.jpizza.compiler.types.TypeCodes; 6 | import lemon.jpizza.compiler.values.Value; 7 | 8 | import java.util.ArrayList; 9 | import java.util.HashMap; 10 | import java.util.List; 11 | import java.util.Map; 12 | 13 | public class NamespaceType extends Type { 14 | public final Map attributes; 15 | 16 | public NamespaceType(Map attributes) { 17 | super("namespace"); 18 | this.attributes = attributes; 19 | } 20 | 21 | @Override 22 | public Type applyGenerics(Map generics) { 23 | Map newAttributes = new HashMap<>(); 24 | for (Map.Entry entry : attributes.entrySet()) { 25 | newAttributes.put(entry.getKey(), entry.getValue().applyGenerics(generics)); 26 | } 27 | return new NamespaceType(newAttributes); 28 | } 29 | 30 | @Override 31 | protected Type operation(TokenType operation, Type other) { 32 | return null; 33 | } 34 | 35 | @Override 36 | protected Type operation(TokenType operation) { 37 | return null; 38 | } 39 | 40 | @Override 41 | public Type call(Type[] arguments, Type[] generics) { 42 | return null; 43 | } 44 | 45 | @Override 46 | public Type access(String name) { 47 | return attributes.get(name); 48 | } 49 | 50 | @Override 51 | public List accessors() { 52 | return new ArrayList<>(attributes.keySet()); 53 | } 54 | 55 | @Override 56 | public Type accessInternal(String name) { 57 | return null; 58 | } 59 | 60 | @Override 61 | public int[] dump() { 62 | List list = new ArrayList<>(); 63 | list.add(TypeCodes.NAMESPACE); 64 | compileAttributes(list, attributes); 65 | return list.stream().mapToInt(Integer::intValue).toArray(); 66 | } 67 | 68 | static void compileAttributes(List list, Map attributes) { 69 | list.add(attributes.size()); 70 | for (Map.Entry entry : attributes.entrySet()) { 71 | Value.addAllString(list, entry.getKey()); 72 | list.addAll(entry.getValue().dumpList()); 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/types/objects/PrimitiveGenericType.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler.types.objects; 2 | 3 | import lemon.jpizza.TokenType; 4 | import lemon.jpizza.compiler.types.Type; 5 | import lemon.jpizza.compiler.types.primitives.PrimitiveType; 6 | 7 | public abstract class PrimitiveGenericType extends PrimitiveType { 8 | public final int genericCount; 9 | 10 | public PrimitiveGenericType(String name, int genericCount) { 11 | super(name); 12 | this.genericCount = genericCount; 13 | } 14 | 15 | @Override 16 | protected Type operation(TokenType operation, Type other) { 17 | return null; 18 | } 19 | 20 | @Override 21 | protected Type operation(TokenType operation) { 22 | return null; 23 | } 24 | 25 | @Override 26 | public int[] dump() { 27 | return new int[0]; 28 | } 29 | 30 | public abstract Type applyGenerics(Type... generics); 31 | } 32 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/types/objects/ReferenceType.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler.types.objects; 2 | 3 | import lemon.jpizza.TokenType; 4 | import lemon.jpizza.compiler.types.Type; 5 | import lemon.jpizza.compiler.types.TypeCodes; 6 | import lemon.jpizza.compiler.types.Types; 7 | 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | import java.util.Map; 11 | 12 | public class ReferenceType extends Type { 13 | public Type ref; 14 | 15 | public ReferenceType(Type ref) { 16 | super(null); 17 | updateRef(ref); 18 | } 19 | 20 | private void updateRef(Type ref) { 21 | this.name = "[" + ref.name + "]"; 22 | this.ref = ref; 23 | } 24 | 25 | @Override 26 | protected Type operation(TokenType operation, Type other) { 27 | if (operation == TokenType.FatArrow) { 28 | updateRef(other); 29 | return Types.VOID; 30 | } 31 | return null; 32 | } 33 | 34 | @Override 35 | protected Type operation(TokenType operation) { 36 | return null; 37 | } 38 | 39 | @Override 40 | public Type call(Type[] arguments, Type[] generics) { 41 | return null; 42 | } 43 | 44 | @Override 45 | public Type access(String name) { 46 | return null; 47 | } 48 | 49 | @Override 50 | public Type accessInternal(String name) { 51 | return null; 52 | } 53 | 54 | @Override 55 | public int[] dump() { 56 | List list = new ArrayList<>(); 57 | list.add(TypeCodes.REFERENCE); 58 | list.addAll(ref.dumpList()); 59 | return list.stream().mapToInt(Integer::intValue).toArray(); 60 | } 61 | 62 | @Override 63 | public Type applyGenerics(Map generics) { 64 | return new ReferenceType(ref.applyGenerics(generics)); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/types/objects/TupleType.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler.types.objects; 2 | 3 | import lemon.jpizza.TokenType; 4 | import lemon.jpizza.compiler.types.Type; 5 | import lemon.jpizza.compiler.types.TypeCodes; 6 | import lemon.jpizza.compiler.types.Types; 7 | import lemon.jpizza.compiler.types.primitives.IntType; 8 | 9 | import java.util.Arrays; 10 | import java.util.Map; 11 | import java.util.stream.Collectors; 12 | 13 | public class TupleType extends Type { 14 | private final Type[] types; 15 | public TupleType(Type... types) { 16 | // (T1, T2, ..., Tn) 17 | super("(" + Arrays.stream(types).map(Type::toString).collect(Collectors.joining(", ")) + ")"); 18 | this.types = types; 19 | } 20 | 21 | @Override 22 | public Type applyGenerics(final Map generics) { 23 | Type[] newTypes = new Type[types.length]; 24 | for (int i = 0; i < types.length; i++) { 25 | newTypes[i] = types[i].applyGenerics(generics); 26 | } 27 | return new TupleType(newTypes); 28 | } 29 | 30 | @Override 31 | protected Type operation(TokenType operation, Type other) { 32 | if (operation == TokenType.LeftBracket && other instanceof IntType) { 33 | return Types.ANY; 34 | } 35 | return null; 36 | } 37 | 38 | @Override 39 | protected Type operation(TokenType operation) { 40 | return null; 41 | } 42 | 43 | @Override 44 | public boolean equals(Object o) { 45 | if (this == o) return true; 46 | if (!(o instanceof TupleType)) return false; 47 | TupleType tupleType = (TupleType) o; 48 | return Arrays.equals(types, tupleType.types); 49 | } 50 | 51 | @Override 52 | public Type call(Type[] arguments, Type[] generics) { 53 | return null; 54 | } 55 | 56 | @Override 57 | public Type access(String name) { 58 | return null; 59 | } 60 | 61 | @Override 62 | public Type accessInternal(String name) { 63 | return null; 64 | } 65 | 66 | @Override 67 | public int[] dump() { 68 | int listSize = 2; 69 | int[][] subTypes = new int[types.length][]; 70 | for (int i = 0; i < types.length; i++) { 71 | subTypes[i] = types[i].dump(); 72 | listSize += subTypes[i].length; 73 | } 74 | int[] result = new int[listSize]; 75 | result[0] = TypeCodes.TUPLE; 76 | result[1] = types.length; 77 | int offset = 2; 78 | for (int i = 0; i < types.length; i++) { 79 | System.arraycopy(subTypes[i], 0, result, offset, subTypes[i].length); 80 | offset += subTypes[i].length; 81 | } 82 | return result; 83 | } 84 | 85 | public final Type getType(int index) { 86 | if (index < 0 || index >= types.length) { 87 | return null; 88 | } 89 | return types[index]; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/types/objects/VecType.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler.types.objects; 2 | 3 | import lemon.jpizza.TokenType; 4 | import lemon.jpizza.compiler.types.Type; 5 | import lemon.jpizza.compiler.types.TypeCodes; 6 | import lemon.jpizza.compiler.types.Types; 7 | import lemon.jpizza.compiler.types.primitives.PrimitiveType; 8 | 9 | public class VecType extends PrimitiveType { 10 | private final Type itemType; 11 | 12 | public VecType(Type itemType) { 13 | super("vec<" + itemType.toString() + ">"); 14 | this.itemType = itemType; 15 | } 16 | 17 | @Override 18 | protected Type operation(TokenType operation, Type other) { 19 | if (operation == TokenType.Dot || operation == TokenType.LeftBracket) { 20 | return Types.INT.equals(other) ? itemType : null; 21 | } 22 | return null; 23 | } 24 | 25 | @Override 26 | protected Type operation(TokenType operation) { 27 | return null; 28 | } 29 | 30 | @Override 31 | public int[] dump() { 32 | int[] subType = itemType.dump(); 33 | int[] result = new int[subType.length + 1]; 34 | result[0] = TypeCodes.VEC; 35 | System.arraycopy(subType, 0, result, 1, subType.length); 36 | return result; 37 | } 38 | 39 | @Override 40 | public boolean equals(Object other) { 41 | return other instanceof VecType && itemType.equals(((VecType) other).itemType); 42 | } 43 | 44 | public Type getItemType() { 45 | return itemType; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/types/primitives/BooleanType.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler.types.primitives; 2 | 3 | import lemon.jpizza.TokenType; 4 | import lemon.jpizza.compiler.types.Type; 5 | import lemon.jpizza.compiler.types.TypeCodes; 6 | 7 | import java.util.Arrays; 8 | 9 | public class BooleanType extends PrimitiveType { 10 | static final BooleanType INSTANCE = new BooleanType(); 11 | 12 | static final TokenType[] VALID_OPS = { 13 | TokenType.Ampersand, 14 | TokenType.Pipe, 15 | TokenType.Bang 16 | }; 17 | 18 | private BooleanType() { 19 | super("bool"); 20 | } 21 | 22 | @Override 23 | protected Type operation(TokenType operation, Type other) { 24 | if (!(other instanceof BooleanType)) { 25 | return null; 26 | } 27 | if (Arrays.asList(VALID_OPS).contains(operation)) { 28 | return INSTANCE; 29 | } 30 | return null; 31 | } 32 | 33 | @Override 34 | protected Type operation(TokenType operation) { 35 | if (Arrays.asList(VALID_OPS).contains(operation)) { 36 | return INSTANCE; 37 | } 38 | return null; 39 | } 40 | 41 | @Override 42 | public int[] dump() { 43 | return new int[]{TypeCodes.BOOL}; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/types/primitives/BytesType.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler.types.primitives; 2 | 3 | import lemon.jpizza.TokenType; 4 | import lemon.jpizza.compiler.types.Type; 5 | import lemon.jpizza.compiler.types.TypeCodes; 6 | import lemon.jpizza.compiler.types.Types; 7 | 8 | public class BytesType extends PrimitiveType { 9 | static final BytesType INSTANCE = new BytesType(); 10 | 11 | private BytesType() { 12 | super("bytearray"); 13 | } 14 | 15 | @Override 16 | protected Type operation(TokenType operation, Type other) { 17 | if (operation == TokenType.LeftBracket) { 18 | return Types.INT; 19 | } 20 | return null; 21 | } 22 | 23 | @Override 24 | protected Type operation(TokenType operation) { 25 | return null; 26 | } 27 | 28 | @Override 29 | public int[] dump() { 30 | return new int[]{TypeCodes.BYTES}; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/types/primitives/DictType.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler.types.primitives; 2 | 3 | import lemon.jpizza.TokenType; 4 | import lemon.jpizza.compiler.types.Type; 5 | import lemon.jpizza.compiler.types.TypeCodes; 6 | import lemon.jpizza.compiler.types.Types; 7 | 8 | public class DictType extends PrimitiveType { 9 | static final DictType INSTANCE = new DictType(); 10 | 11 | private DictType() { 12 | super("dict"); 13 | } 14 | 15 | @Override 16 | protected Type operation(TokenType operation, Type other) { 17 | if (operation == TokenType.LeftBracket || operation == TokenType.Dot) { 18 | return Types.ANY; 19 | } 20 | else if (operation == TokenType.Plus) { 21 | return other == Types.DICT ? Types.DICT : null; 22 | } 23 | return null; 24 | } 25 | 26 | @Override 27 | protected Type operation(TokenType operation) { 28 | return null; 29 | } 30 | 31 | @Override 32 | public int[] dump() { 33 | return new int[]{TypeCodes.DICT}; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/types/primitives/FloatType.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler.types.primitives; 2 | 3 | import lemon.jpizza.TokenType; 4 | import lemon.jpizza.compiler.types.Type; 5 | import lemon.jpizza.compiler.types.TypeCodes; 6 | import lemon.jpizza.compiler.types.Types; 7 | 8 | import java.util.Arrays; 9 | 10 | import static lemon.jpizza.compiler.types.primitives.IntType.VALID_OPS; 11 | 12 | public class FloatType extends PrimitiveType { 13 | static final FloatType INSTANCE = new FloatType(); 14 | 15 | private FloatType() { 16 | super("float"); 17 | } 18 | 19 | @Override 20 | public Type operation(TokenType operation, Type other) { 21 | if (other != Types.INT && other != Types.FLOAT) { 22 | return null; 23 | } 24 | if (Arrays.asList(VALID_OPS).contains(operation)) { 25 | return Types.FLOAT; 26 | } 27 | return null; 28 | } 29 | 30 | @Override 31 | public Type operation(TokenType operation) { 32 | if (Arrays.asList(VALID_OPS).contains(operation)) { 33 | return this; 34 | } 35 | return null; 36 | } 37 | 38 | @Override 39 | public boolean equals(Object o) { 40 | // An int can be a float, but a float can't be an int. 41 | return o instanceof FloatType || o instanceof IntType; 42 | } 43 | 44 | @Override 45 | public int[] dump() { 46 | return new int[]{TypeCodes.FLOAT}; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/types/primitives/IntType.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler.types.primitives; 2 | 3 | import lemon.jpizza.TokenType; 4 | import lemon.jpizza.compiler.types.Type; 5 | import lemon.jpizza.compiler.types.TypeCodes; 6 | import lemon.jpizza.compiler.types.Types; 7 | 8 | import java.util.Arrays; 9 | 10 | public class IntType extends PrimitiveType { 11 | static final IntType INSTANCE = new IntType(); 12 | 13 | static final TokenType[] VALID_OPS = { 14 | TokenType.Plus, 15 | TokenType.Minus, 16 | TokenType.Star, 17 | TokenType.Slash, 18 | TokenType.Caret, 19 | TokenType.Percent, 20 | TokenType.RightAngle, 21 | TokenType.LeftAngle, 22 | TokenType.GreaterEquals, 23 | TokenType.LessEquals, 24 | TokenType.TildeAmpersand, 25 | TokenType.TildePipe, 26 | TokenType.TildeCaret, 27 | TokenType.LeftTildeArrow, 28 | TokenType.TildeTilde, 29 | TokenType.RightTildeArrow, 30 | TokenType.PlusPlus, 31 | TokenType.MinusMinus, 32 | }; 33 | 34 | private IntType() { 35 | super("int"); 36 | } 37 | 38 | @Override 39 | public Type operation(TokenType operation, Type other) { 40 | if (other != Types.INT && other != Types.FLOAT) { 41 | return null; 42 | } 43 | if (Arrays.asList(VALID_OPS).contains(operation)) { 44 | return other == Types.FLOAT ? Types.FLOAT : Types.INT; 45 | } 46 | return null; 47 | } 48 | 49 | @Override 50 | public Type operation(TokenType operation) { 51 | if (Arrays.asList(VALID_OPS).contains(operation)) { 52 | return Types.INT; 53 | } 54 | return null; 55 | } 56 | 57 | @Override 58 | public int[] dump() { 59 | return new int[]{TypeCodes.INT}; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/types/primitives/ListType.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler.types.primitives; 2 | 3 | import lemon.jpizza.TokenType; 4 | import lemon.jpizza.compiler.types.Type; 5 | import lemon.jpizza.compiler.types.TypeCodes; 6 | import lemon.jpizza.compiler.types.Types; 7 | 8 | import java.util.Arrays; 9 | 10 | public class ListType extends PrimitiveType { 11 | static final ListType INSTANCE = new ListType(); 12 | 13 | private ListType() { 14 | super("list"); 15 | } 16 | 17 | @Override 18 | protected Type operation(TokenType operation, Type other) { 19 | if (operation == TokenType.Dot || operation == TokenType.LeftBracket) { 20 | return Types.INT.equals(other) ? Types.ANY : null; 21 | } 22 | else if (operation == TokenType.Plus) { 23 | return other == Types.LIST ? Types.LIST : null; 24 | } 25 | else if (operation == TokenType.Slash || operation == TokenType.Percent) { 26 | return Types.LIST; 27 | } 28 | return null; 29 | } 30 | 31 | @Override 32 | protected Type operation(TokenType operation) { 33 | return null; 34 | } 35 | 36 | @Override 37 | public int[] dump() { 38 | return new int[]{TypeCodes.LIST}; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/types/primitives/PrimitiveType.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler.types.primitives; 2 | 3 | import lemon.jpizza.compiler.types.Type; 4 | import lemon.jpizza.compiler.types.TypeCodes; 5 | 6 | import java.util.Map; 7 | 8 | public abstract class PrimitiveType extends Type { 9 | public PrimitiveType(String name) { 10 | super(name); 11 | } 12 | 13 | @Override 14 | public Type call(final Type[] args, final Type[] generics) { 15 | return null; 16 | } 17 | 18 | @Override 19 | public Type access(final String name) { 20 | return null; 21 | } 22 | 23 | @Override 24 | public Type accessInternal(final String name) { 25 | return null; 26 | } 27 | 28 | @Override 29 | public Type applyGenerics(final Map generics) { 30 | return this; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/types/primitives/PrimitiveTypes.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler.types.primitives; 2 | 3 | public class PrimitiveTypes { 4 | public static final IntType INT = IntType.INSTANCE; 5 | public static final FloatType FLOAT = FloatType.INSTANCE; 6 | public static final BooleanType BOOL = BooleanType.INSTANCE; 7 | public static final ListType LIST = ListType.INSTANCE; 8 | public static final DictType DICT = DictType.INSTANCE; 9 | public static final StringType STRING = StringType.INSTANCE; 10 | public static final BytesType BYTES = BytesType.INSTANCE; 11 | public static final ResultType RESULT = ResultType.INSTANCE; 12 | } 13 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/types/primitives/ResultType.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler.types.primitives; 2 | 3 | import lemon.jpizza.TokenType; 4 | import lemon.jpizza.compiler.types.Type; 5 | import lemon.jpizza.compiler.types.TypeCodes; 6 | 7 | public class ResultType extends PrimitiveType { 8 | static final ResultType INSTANCE = new ResultType(); 9 | 10 | private ResultType() { 11 | super("catcher"); 12 | } 13 | 14 | @Override 15 | protected Type operation(TokenType operation, Type other) { 16 | return null; 17 | } 18 | 19 | @Override 20 | protected Type operation(TokenType operation) { 21 | return null; 22 | } 23 | 24 | @Override 25 | public int[] dump() { 26 | return new int[]{TypeCodes.RESULT}; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/types/primitives/StringType.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler.types.primitives; 2 | 3 | import lemon.jpizza.TokenType; 4 | import lemon.jpizza.compiler.types.Type; 5 | import lemon.jpizza.compiler.types.TypeCodes; 6 | import lemon.jpizza.compiler.types.Types; 7 | 8 | public class StringType extends PrimitiveType { 9 | static final StringType INSTANCE = new StringType(); 10 | 11 | private StringType() { 12 | super("String"); 13 | } 14 | 15 | @Override 16 | protected Type operation(TokenType operation, Type other) { 17 | if (operation == TokenType.Plus) { 18 | return Types.STRING; 19 | } 20 | else if (operation == TokenType.Star && other == Types.INT) { 21 | return Types.STRING; 22 | } 23 | else if (operation == TokenType.LeftBracket && other == Types.INT) { 24 | return Types.STRING; 25 | } 26 | return null; 27 | } 28 | 29 | @Override 30 | protected Type operation(TokenType operation) { 31 | return null; 32 | } 33 | 34 | @Override 35 | public int[] dump() { 36 | return new int[]{TypeCodes.STRING}; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/values/Pattern.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler.values; 2 | 3 | import java.util.Map; 4 | 5 | public class Pattern { 6 | public Value value; 7 | public Map matches; 8 | public String[] keys; 9 | public Map cases; 10 | 11 | public Pattern(Value value, Map cases, String[] keys, Map matches) { 12 | this.value = value; 13 | this.cases = cases; 14 | this.matches = matches; 15 | this.keys = keys; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/values/ValueArray.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler.values; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | import java.util.List; 6 | 7 | public class ValueArray { 8 | public int length; 9 | public final List values; 10 | public Value[] valuesArray; 11 | 12 | public ValueArray() { 13 | this.length = 0; 14 | this.values = new ArrayList<>(); 15 | } 16 | 17 | public ValueArray(Value[] constants) { 18 | this.length = constants.length; 19 | this.values = Arrays.asList(constants); 20 | this.valuesArray = constants; 21 | } 22 | 23 | public int write(Value value) { 24 | int index = values.indexOf(value); 25 | if (index == -1) { 26 | values.add(value); 27 | index = length++; 28 | } 29 | return index; 30 | } 31 | 32 | public void compile() { 33 | valuesArray = values.toArray(new Value[0]); 34 | } 35 | 36 | public ValueArray copy() { 37 | ValueArray copy = new ValueArray(); 38 | copy.length = length; 39 | for (Value value : values) { 40 | copy.values.add(value.copy()); 41 | } 42 | copy.compile(); 43 | return copy; 44 | } 45 | 46 | public int[] dump() { 47 | List list = new ArrayList<>(); 48 | list.add(length); 49 | for (Value value : values) { 50 | for (int i : value.dump()) { 51 | list.add(i); 52 | } 53 | } 54 | return list.stream().mapToInt(Integer::intValue).toArray(); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/values/Var.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler.values; 2 | 3 | public class Var { 4 | public Value val; 5 | public final boolean constant; 6 | public final int min; 7 | public final int max; 8 | 9 | public Var(Value val, boolean constant) { 10 | this.val = val; 11 | this.constant = constant; 12 | min = Integer.MIN_VALUE; 13 | max = Integer.MAX_VALUE; 14 | } 15 | 16 | public Var(Value val, boolean constant, int min, int max) { 17 | this.val = val; 18 | this.constant = constant; 19 | this.min = min; 20 | this.max = max; 21 | } 22 | 23 | public void val(Value v) { 24 | val = v; 25 | } 26 | 27 | public String toString() { 28 | return val.toString(); 29 | } 30 | 31 | public String toSafeString() { 32 | return val.toSafeString(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/values/classes/BoundMethod.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler.values.classes; 2 | 3 | import lemon.jpizza.compiler.values.Value; 4 | import lemon.jpizza.compiler.values.functions.JClosure; 5 | 6 | public class BoundMethod { 7 | public final JClosure closure; 8 | public final Value receiver; 9 | 10 | public BoundMethod(JClosure closure, Value receiver) { 11 | this.closure = closure; 12 | this.receiver = receiver; 13 | } 14 | 15 | public String toString() { 16 | return closure.toString(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/values/classes/ClassAttr.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler.values.classes; 2 | 3 | import lemon.jpizza.compiler.types.Type; 4 | import lemon.jpizza.compiler.values.Value; 5 | 6 | import java.util.ArrayList; 7 | import java.util.Collections; 8 | import java.util.List; 9 | 10 | public class ClassAttr { 11 | public Value val; 12 | public final boolean isStatic; 13 | public final boolean isPrivate; 14 | 15 | public ClassAttr(Value val, boolean isStatic, boolean isPrivate) { 16 | this.val = val; 17 | this.isStatic = isStatic; 18 | this.isPrivate = isPrivate; 19 | } 20 | 21 | public ClassAttr(Value val) { 22 | this(val, false, false); 23 | } 24 | 25 | public void set(Value val) { 26 | this.val = val; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/values/classes/JClass.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler.values.classes; 2 | 3 | import lemon.jpizza.compiler.types.Type; 4 | import lemon.jpizza.compiler.types.objects.ClassType; 5 | import lemon.jpizza.compiler.values.Value; 6 | import lemon.jpizza.compiler.values.functions.JClosure; 7 | import lemon.jpizza.compiler.values.functions.NativeResult; 8 | 9 | import java.util.HashMap; 10 | import java.util.List; 11 | import java.util.Map; 12 | 13 | import static lemon.jpizza.compiler.values.classes.Instance.copyAttributes; 14 | 15 | public class JClass { 16 | public final JClass superClass; 17 | 18 | public final String name; 19 | public final Map attributes; 20 | public Map methods; 21 | public Map binMethods; 22 | public List generics; 23 | 24 | public Value constructor; 25 | public Type type; 26 | 27 | public JClass(String name, Map attributes, 28 | List generics, JClass superClass) { 29 | this.name = name; 30 | this.attributes = new HashMap<>(); 31 | this.methods = new HashMap<>(); 32 | this.binMethods = new HashMap<>(); 33 | 34 | this.superClass = superClass; 35 | if (superClass != null) { 36 | copyAttributes(superClass.attributes, this.attributes); 37 | this.methods = superClass.methods; 38 | this.binMethods = superClass.binMethods; 39 | } 40 | 41 | this.attributes.putAll(attributes); 42 | this.generics = generics; 43 | } 44 | 45 | public String toString() { 46 | return name; 47 | } 48 | 49 | public void addMethod(String name, Value value) { 50 | if (name.equals("")) 51 | constructor = value; 52 | else if (value.asClosure().function.isBin) 53 | binMethods.put(name, value); 54 | else 55 | methods.put(name, value); 56 | } 57 | 58 | public Value getField(String name, boolean internal) { 59 | ClassAttr attr = attributes.get(name); 60 | if (attr != null && attr.isStatic && (!attr.isPrivate || internal)) 61 | return attr.val; 62 | 63 | Value val = methods.get(name); 64 | JClosure method = val != null ? val.asClosure() : null; 65 | if (method != null && method.function.isStatic && (!method.function.isPrivate || internal)) 66 | return val; 67 | 68 | return null; 69 | } 70 | 71 | public NativeResult setField(String name, Value value) { 72 | return Instance.setField(name, value, attributes); 73 | } 74 | 75 | public boolean hasField(String name) { 76 | return attributes.containsKey(name); 77 | } 78 | 79 | public boolean has(String name) { 80 | return attributes.containsKey(name) || methods.containsKey(name); 81 | } 82 | 83 | public JClass copy() { 84 | Map attrs = new HashMap<>(); 85 | copyAttributes(attributes, attrs); 86 | return new JClass(name, attrs, generics, superClass.copy()); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/values/classes/Namespace.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler.values.classes; 2 | 3 | import lemon.jpizza.compiler.values.Value; 4 | import lemon.jpizza.compiler.values.Var; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | import java.util.Map; 9 | 10 | public class Namespace { 11 | String name; 12 | Map values; 13 | List publics; 14 | 15 | public Namespace(String name, Map values, List publics) { 16 | this.name = name; 17 | this.values = values; 18 | this.publics = publics; 19 | } 20 | 21 | public Namespace(String name, Map values) { 22 | this(name, values, new ArrayList<>(values.keySet())); 23 | } 24 | 25 | public String getName() { 26 | return name; 27 | } 28 | 29 | public Map getValues() { 30 | return values; 31 | } 32 | 33 | public Var getValue(String name, boolean internal) { 34 | return publics.contains(name) || internal ? values.get(name) : null; 35 | } 36 | 37 | public Value getField(String name, boolean internal) { 38 | Var var = getValue(name, internal); 39 | return var != null ? var.val : null; 40 | } 41 | 42 | public void addField(String name, Value val) { 43 | values.put(name, new Var(val, false)); 44 | publics.add(name); 45 | } 46 | 47 | public String name() { 48 | return name; 49 | } 50 | 51 | public Map values() { 52 | return values; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/values/enums/JEnum.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler.values.enums; 2 | 3 | import lemon.jpizza.compiler.ChunkCode; 4 | import lemon.jpizza.compiler.values.Value; 5 | 6 | import java.util.ArrayList; 7 | import java.util.Collections; 8 | import java.util.List; 9 | import java.util.Map; 10 | 11 | public class JEnum { 12 | String name; 13 | Map children; 14 | 15 | public JEnum(String name, Map children) { 16 | this.name = name; 17 | this.children = children; 18 | 19 | for (JEnumChild child : children.values()) { 20 | child.setParent(this); 21 | } 22 | } 23 | 24 | public String name() { 25 | return name; 26 | } 27 | 28 | public Value get(String name) { 29 | return children.get(name).asValue(); 30 | } 31 | 32 | public int[] dump() { 33 | List list = new ArrayList<>(Collections.singletonList(ChunkCode.Enum)); 34 | for (int i : Value.dumpString(name)) { 35 | list.add(i); 36 | } 37 | list.add(children.size()); 38 | for (Map.Entry entry : children.entrySet()) { 39 | for (int i : Value.dumpString(entry.getKey())) { 40 | list.add(i); 41 | } 42 | for (int i : entry.getValue().dump()) { 43 | list.add(i); 44 | } 45 | } 46 | return list.stream().mapToInt(Integer::intValue).toArray(); 47 | } 48 | 49 | public Map children() { 50 | return children; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/values/enums/JEnumChild.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler.values.enums; 2 | 3 | import lemon.jpizza.compiler.ChunkCode; 4 | import lemon.jpizza.compiler.values.Value; 5 | import lemon.jpizza.compiler.values.classes.ClassAttr; 6 | import lemon.jpizza.compiler.values.classes.Instance; 7 | import lemon.jpizza.compiler.vm.VM; 8 | 9 | import java.util.*; 10 | 11 | public class JEnumChild { 12 | final int value; 13 | JEnum parent; 14 | 15 | private final Value asValue; 16 | 17 | // For Enum Props 18 | public final List props; 19 | 20 | public final int arity; 21 | 22 | public JEnumChild(int value, List props) { 23 | this.value = value; 24 | this.props = props; 25 | 26 | this.arity = props.size(); 27 | 28 | this.asValue = new Value(this); 29 | } 30 | 31 | public int getValue() { 32 | return value; 33 | } 34 | 35 | public boolean equals(JEnumChild other) { 36 | return value == other.value; 37 | } 38 | 39 | public void setParent(JEnum jEnum) { 40 | parent = jEnum; 41 | } 42 | 43 | public String type() { 44 | return parent.name(); 45 | } 46 | 47 | public JEnum getParent() { 48 | return parent; 49 | } 50 | 51 | public Value create(Value[] args, VM vm) { 52 | Map fields = new HashMap<>(); 53 | for (int i = 0; i < props.size(); i++) { 54 | fields.put( 55 | props.get(i), 56 | new ClassAttr(args[i]) 57 | ); 58 | } 59 | 60 | fields.put("$child", new ClassAttr(new Value(value))); 61 | fields.put("$parent", new ClassAttr(new Value(parent))); 62 | 63 | // Normal: EnumChild 64 | // Generic: EnumChild((Type1)(Type2)(etc)) 65 | return new Value(new Instance(parent.name(), fields, vm)); 66 | } 67 | 68 | public Value asValue() { 69 | return asValue; 70 | } 71 | 72 | public int[] dump() { 73 | List dump = new ArrayList<>(Arrays.asList(ChunkCode.EnumChild, value)); 74 | dump.add(props.size()); 75 | for (String prop : props) { 76 | Value.addAllString(dump, prop); 77 | } 78 | return dump.stream().mapToInt(Integer::intValue).toArray(); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/values/functions/JClosure.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler.values.functions; 2 | 3 | import lemon.jpizza.compiler.values.Var; 4 | 5 | public class JClosure { 6 | public final JFunc function; 7 | 8 | public final Var[] upvalues; 9 | public int upvalueCount; 10 | 11 | public JClosure(JFunc function) { 12 | this.function = function; 13 | this.upvalueCount = function.upvalueCount; 14 | this.upvalues = new Var[upvalueCount]; 15 | } 16 | 17 | public void asMethod(boolean isStatic, boolean isPrivate, boolean isBin, String owner) { 18 | function.isStatic = isStatic; 19 | function.isPrivate = isPrivate; 20 | function.isBin = isBin; 21 | function.owner = owner; 22 | } 23 | 24 | public String toString() { 25 | return function.toString(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/values/functions/JFunc.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler.values.functions; 2 | 3 | import lemon.jpizza.compiler.Chunk; 4 | import lemon.jpizza.compiler.ChunkCode; 5 | import lemon.jpizza.compiler.values.Value; 6 | 7 | import java.util.ArrayList; 8 | import java.util.Arrays; 9 | import java.util.List; 10 | 11 | public class JFunc { 12 | public int arity; 13 | public int totarity; 14 | public Chunk chunk; 15 | public String name; 16 | 17 | public boolean catcher; 18 | 19 | // Only if the function is a method 20 | public boolean isPrivate; 21 | public boolean isStatic; 22 | public boolean isBin; 23 | public String owner; 24 | 25 | public int upvalueCount; 26 | public boolean async; 27 | public List defaults; 28 | public int defaultCount; 29 | public boolean varargs; 30 | public boolean kwargs; 31 | 32 | public JFunc(String source) { 33 | arity = 0; 34 | totarity = 0; 35 | defaultCount = 0; 36 | name = ""; 37 | chunk = new Chunk(source); 38 | 39 | upvalueCount = 0; 40 | } 41 | 42 | public String toString() { 43 | if (owner != null) 44 | return "<" + owner + "-method-" + name + ">"; 45 | return ""; 46 | } 47 | 48 | public JFunc copy() { 49 | JFunc copy = new JFunc(chunk.source()); 50 | 51 | copy.chunk.constants(chunk.constants().copy()); 52 | copy.chunk.codeArray = chunk.codeArray; 53 | copy.chunk.positions = chunk.positions; 54 | 55 | copy.arity = arity; 56 | copy.defaults = defaults; 57 | copy.totarity = totarity; 58 | copy.name = name; 59 | copy.isPrivate = isPrivate; 60 | copy.isStatic = isStatic; 61 | copy.isBin = isBin; 62 | copy.owner = owner; 63 | copy.upvalueCount = upvalueCount; 64 | copy.async = async; 65 | copy.catcher = catcher; 66 | copy.kwargs = kwargs; 67 | copy.varargs = varargs; 68 | return copy; 69 | } 70 | 71 | public int[] dump() { 72 | List list = new ArrayList<>(Arrays.asList(ChunkCode.Func, arity, totarity)); 73 | if (name != null) 74 | Value.addAllString(list, name); 75 | else 76 | list.add(0); 77 | 78 | list.add(upvalueCount); 79 | 80 | list.add(async ? 1 : 0); 81 | list.add(catcher ? 1 : 0); 82 | list.add(varargs ? 1 : 0); 83 | list.add(kwargs ? 1 : 0); 84 | 85 | int[] chunk = this.chunk.dump(); 86 | for (int i : chunk) 87 | list.add(i); 88 | 89 | return list.stream().mapToInt(Integer::intValue).toArray(); 90 | } 91 | 92 | public byte[] dumpBytes() { 93 | int[] dump = dump(); 94 | byte[] bytes = new byte[dump.length * 4]; 95 | for (int i = 0; i < dump.length; i++) { 96 | int v = dump[i]; 97 | bytes[i * 4 ] = (byte) (v >>> 24); 98 | bytes[i * 4 + 1] = (byte) (v >>> 16); 99 | bytes[i * 4 + 2] = (byte) (v >>> 8); 100 | bytes[i * 4 + 3] = (byte) (v ); 101 | } 102 | return bytes; 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/values/functions/JNative.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler.values.functions; 2 | 3 | import lemon.jpizza.compiler.types.Type; 4 | import lemon.jpizza.compiler.types.Types; 5 | import lemon.jpizza.compiler.values.Value; 6 | 7 | public class JNative { 8 | 9 | public interface Method { 10 | NativeResult call(Value[] stack); 11 | } 12 | 13 | final String name; 14 | final Method method; 15 | final int argc; 16 | final Type[] types; 17 | 18 | public JNative(String name, Method method, int argc, Type[] types) { 19 | this.name = name; 20 | this.method = method; 21 | this.argc = argc; 22 | this.types = types; 23 | } 24 | 25 | public JNative(String name, Method method, int argc) { 26 | this(name, method, argc, new Type[argc == -1 ? 0 : argc]); 27 | for (int i = 0; i < argc; i++) 28 | types[i] = Types.ANY; 29 | } 30 | 31 | public NativeResult call(Value[] args) { 32 | if (args.length != argc && argc != -1) 33 | return NativeResult.Err("Argument Count", "Expected " + argc + " arguments, got " + args.length); 34 | return method.call(args); 35 | } 36 | 37 | public String toString() { 38 | return ""; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/values/functions/NativeResult.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler.values.functions; 2 | 3 | import lemon.jpizza.compiler.values.Value; 4 | 5 | public class NativeResult { 6 | final Value value; 7 | final boolean isException; 8 | final String exceptionName; 9 | final String exceptionMessage; 10 | 11 | private NativeResult(Value value) { 12 | this.value = value; 13 | 14 | this.isException = false; 15 | this.exceptionMessage = null; 16 | this.exceptionName = null; 17 | } 18 | 19 | private NativeResult(String name, String reason) { 20 | this.value = null; 21 | 22 | this.isException = true; 23 | this.exceptionName = name; 24 | this.exceptionMessage = reason; 25 | } 26 | 27 | public static NativeResult Err(String name, String reason) { 28 | return new NativeResult(name, reason); 29 | } 30 | 31 | public static NativeResult Ok(Value value) { 32 | return new NativeResult(value); 33 | } 34 | 35 | public static NativeResult Ok() { 36 | return new NativeResult(new Value()); 37 | } 38 | 39 | public boolean ok() { 40 | return !isException; 41 | } 42 | 43 | public Value value() { 44 | return value; 45 | } 46 | 47 | public String name() { 48 | return exceptionName; 49 | } 50 | 51 | public String reason() { 52 | return exceptionMessage; 53 | } 54 | } 55 | 56 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/values/functions/Result.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler.values.functions; 2 | 3 | import lemon.jpizza.Pair; 4 | import lemon.jpizza.compiler.values.Value; 5 | 6 | public class Result { 7 | Pair error = null; 8 | Value val; 9 | 10 | public Result(String message, String reason) { 11 | error = new Pair<>(message, reason); 12 | val = new Value(); 13 | } 14 | 15 | public Result(Value val) { 16 | this.val = val; 17 | } 18 | 19 | public boolean isError() { 20 | return error != null; 21 | } 22 | 23 | public String getErrorMessage() { 24 | return error.a; 25 | } 26 | 27 | public String getErrorReason() { 28 | return error.b; 29 | } 30 | 31 | public Value getValue() { 32 | return val; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/values/functions/Spread.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler.values.functions; 2 | 3 | import lemon.jpizza.compiler.values.Value; 4 | 5 | import java.util.List; 6 | 7 | public class Spread { 8 | public final List values; 9 | public Spread(List values) { 10 | this.values = values; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/vm/CallFrame.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler.vm; 2 | 3 | import lemon.jpizza.compiler.values.Value; 4 | import lemon.jpizza.compiler.values.functions.JClosure; 5 | 6 | public class CallFrame { 7 | public final JClosure closure; 8 | public int ip; 9 | public int slots; 10 | public String returnType; 11 | public Value bound; 12 | public int memoize = 0; 13 | public boolean catchError = false; 14 | public boolean addPeek = false; 15 | 16 | public CallFrame(JClosure closure, int ip, int slots, String returnType) { 17 | this(closure, ip, slots, returnType, null); 18 | } 19 | 20 | public CallFrame(JClosure closure, int ip, int slots, String returnType, Value binding) { 21 | this.closure = closure; 22 | this.ip = ip; 23 | this.slots = slots; 24 | this.returnType = returnType; 25 | this.bound = binding; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/vm/JPExtension.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler.vm; 2 | 3 | import lemon.jpizza.Shell; 4 | import lemon.jpizza.compiler.types.GenericType; 5 | import lemon.jpizza.compiler.types.Type; 6 | import lemon.jpizza.compiler.types.Types; 7 | import lemon.jpizza.compiler.types.objects.FuncType; 8 | import lemon.jpizza.compiler.types.objects.NamespaceType; 9 | import lemon.jpizza.compiler.values.Value; 10 | import lemon.jpizza.compiler.values.functions.JNative; 11 | import lemon.jpizza.compiler.values.functions.NativeResult; 12 | 13 | import java.util.HashMap; 14 | import java.util.Map; 15 | 16 | public abstract class JPExtension { 17 | protected final VM vm; 18 | protected final String lib; 19 | abstract public String name(); 20 | 21 | Map fields = new HashMap<>(); 22 | 23 | public JPExtension(VM vm) { 24 | this.vm = vm; 25 | this.lib = name(); 26 | } 27 | 28 | private JPExtension(VM vm, String lib) { 29 | this.vm = vm; 30 | this.lib = lib; 31 | } 32 | 33 | protected void print(Object str) { 34 | Shell.logger.out(str); 35 | } 36 | 37 | protected void println(Object str) { 38 | Shell.logger.outln(str); 39 | } 40 | 41 | protected static final NativeResult Ok = NativeResult.Ok(); 42 | 43 | protected static NativeResult Ok(Value val) { 44 | return NativeResult.Ok(val); 45 | } 46 | 47 | protected static NativeResult Ok(Object obj) { 48 | return Ok(Value.fromObject(obj)); 49 | } 50 | 51 | protected static NativeResult Err(String title, String msg) { 52 | return NativeResult.Err(title, msg); 53 | } 54 | 55 | protected void func(String name, JNative.Method method, Type returnType, int argc) { 56 | if (vm == null) { 57 | Type[] types = new Type[argc]; 58 | for (int i = 0; i < argc; i++) 59 | types[i] = Types.ANY; 60 | fields.put(name, new FuncType(returnType, types, new GenericType[0], false)); 61 | } else 62 | vm.defineNative(lib, name, method, argc); 63 | } 64 | 65 | protected void define(String name, JNative.Method method, FuncType type) { 66 | if (vm == null) 67 | fields.put(name, type); 68 | else 69 | vm.defineNative(lib, name, method, type.varargs ? -1 : type.parameterTypes.length); 70 | } 71 | 72 | protected void func(String name, JNative.Method method, Type returnType, Type... types) { 73 | if (vm == null) 74 | fields.put(name, new FuncType(returnType, types, new GenericType[0], false)); 75 | else 76 | vm.defineNative(lib, name, method, types); 77 | } 78 | 79 | protected void var(String name, Value val, Type type) { 80 | if (vm == null) 81 | fields.put(name, type); 82 | else 83 | vm.defineVar(lib, name, val); 84 | } 85 | 86 | protected void var(String name, Object val, Type type) { 87 | var(name, Value.fromObject(val), type); 88 | } 89 | 90 | public void Start() { 91 | setup(); 92 | Shell.libraries.put(name(), new NamespaceType(fields)); 93 | } 94 | 95 | abstract public void setup(); 96 | 97 | } 98 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/compiler/vm/VMResult.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.compiler.vm; 2 | 3 | public enum VMResult { 4 | OK, 5 | ERROR, 6 | EXIT 7 | } 8 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/errors/Error.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.errors; 2 | 3 | import lemon.jpizza.Constants; 4 | import lemon.jpizza.Position; 5 | import org.jetbrains.annotations.NotNull; 6 | 7 | public class Error { 8 | public final Position pos_start; 9 | public final Position pos_end; 10 | public final String error_name; 11 | public final String details; 12 | 13 | public Error(Position pos_start, Position pos_end, String error_name, String details) { 14 | this.pos_start = pos_start != null ? pos_start.copy() : null; 15 | this.pos_end = pos_end != null ? pos_end.copy() : null; 16 | this.error_name = error_name; 17 | this.details = details; 18 | } 19 | 20 | public String asString() { 21 | if (pos_start == null || pos_end == null) { 22 | return error_name + ": " + details; 23 | } 24 | return String.format( 25 | "%s: %s\nFile %s, line %s\n%s", 26 | error_name, details, 27 | pos_start.fn, pos_start.ln + 1, 28 | Constants.stringWithArrows(pos_start.ftext, pos_start, pos_end) 29 | ); 30 | } 31 | 32 | public static Error IllegalCharError(@NotNull Position start_pos, @NotNull Position end_pos, String details) { 33 | return new Error(start_pos, end_pos, "Illegal Character", details); 34 | } 35 | 36 | public static Error ExpectedCharError(@NotNull Position start_pos, @NotNull Position end_pos, String details) { 37 | return new Error(start_pos, end_pos, "Expected Character", details); 38 | } 39 | 40 | public static Error InvalidSyntax(@NotNull Position start_pos, @NotNull Position end_pos, String details) { 41 | return new Error(start_pos, end_pos, "Invalid Syntax", details); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/errors/Tip.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.errors; 2 | 3 | import lemon.jpizza.Constants; 4 | import lemon.jpizza.Position; 5 | import org.jetbrains.annotations.NotNull; 6 | 7 | public class Tip extends Error { 8 | final String refactor; 9 | 10 | public Tip(@NotNull Position pos_start, @NotNull Position pos_end, String details, String refactor) { 11 | super(pos_start, pos_end, "Tip", details); 12 | this.refactor = refactor; 13 | } 14 | 15 | public String asString() { 16 | if (pos_start == null || pos_end == null) return String.format("%s: %s", error_name, details); 17 | return String.format( 18 | "%s: %s\nFile %s, line %s\n%s\nExample: \n%s\n", 19 | error_name, details, 20 | pos_start.fn, pos_start.ln + 1, 21 | Constants.stringWithArrows(pos_start.ftext, pos_start, pos_end), 22 | refactor 23 | ); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/generators/Optimizer.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.generators; 2 | 3 | import lemon.jpizza.nodes.Node; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | public class Optimizer { 9 | public static List optimize(List nodes) { 10 | List optimized = new ArrayList<>(); 11 | for (Node node : nodes) { 12 | optimized.add(optimize(node)); 13 | } 14 | return optimized; 15 | } 16 | 17 | public static Node optimize(Node node) { 18 | return node.optimize(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/nodes/Node.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.nodes; 2 | 3 | import lemon.jpizza.JPType; 4 | import lemon.jpizza.Position; 5 | 6 | import java.util.Collections; 7 | import java.util.List; 8 | import java.util.Map; 9 | import java.util.concurrent.ConcurrentHashMap; 10 | 11 | public abstract class Node { 12 | public Position pos_start; 13 | public Position pos_end; 14 | public JPType jptype; 15 | public boolean constant = false; 16 | 17 | public abstract Node optimize(); 18 | 19 | public double asNumber() { 20 | return 0; 21 | } 22 | 23 | public boolean asBoolean() { 24 | return false; 25 | } 26 | 27 | public String asString() { 28 | return ""; 29 | } 30 | 31 | public Map asMap() { 32 | return new ConcurrentHashMap<>(); 33 | } 34 | 35 | public List asList() { 36 | return Collections.singletonList(this); 37 | } 38 | 39 | @Override 40 | public boolean equals(Object other) { 41 | return other instanceof Node && equals((Node) other); 42 | } 43 | 44 | public boolean equals(Node other) { 45 | return false; 46 | } 47 | 48 | public abstract List getChildren(); 49 | 50 | public abstract String visualize(); 51 | 52 | protected Node setStatic(boolean b) { 53 | constant = b; 54 | return this; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/nodes/TreePrinter.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.nodes; 2 | 3 | import static lemon.jpizza.Constants.repeat; 4 | 5 | public class TreePrinter { 6 | // ----[+]---- 7 | // | | 8 | // [ 1 ] [ 23456 ] 9 | 10 | public static String print(Node node) { 11 | String s = ""; 12 | for (Node child : node.getChildren()) { 13 | if (child == null) continue; 14 | String p = print(child); 15 | s = merge(s, p); 16 | } 17 | 18 | String parent = "[ " + node.visualize() + " ]"; 19 | 20 | int childWidth = width(s); 21 | int parentWidth = width(parent); 22 | int width = Math.max(childWidth, parentWidth); 23 | 24 | int parentOffset = (width - parentWidth) / 2; 25 | int childOffset = (width - childWidth) / 2; 26 | 27 | int centerPipeLoc = (width + 1) / 2 - 1; 28 | int left = s.split("\n")[0].indexOf("|"); 29 | int right = s.split("\n")[0].lastIndexOf("|"); 30 | String coverPipes = left == -1 ? "" : repeat(" ", left) + repeat("_", right - left + 1) + repeat(" ", width - right - 1); 31 | if (!coverPipes.isEmpty()) 32 | coverPipes = coverPipes.substring(0, centerPipeLoc) + "|" + coverPipes.substring(centerPipeLoc + 1); 33 | 34 | StringBuilder sb = new StringBuilder(); 35 | sb.append(repeat(" ", parentOffset)).append(parent).append(repeat(" ", width - parentOffset - parentWidth)).append("\n"); 36 | sb.append(coverPipes).append("\n"); 37 | for (String line : s.split("\n")) { 38 | sb.append(repeat(" ", childOffset)).append(line).append(repeat(" ", width - childOffset - childWidth)).append("\n"); 39 | } 40 | 41 | String centerPipe = repeat(" ", (width + 1) / 2 - 1) + "|\n"; 42 | return centerPipe + sb; 43 | } 44 | 45 | private static String merge(String a, String b) { 46 | if (a.isEmpty()) 47 | return b; 48 | 49 | StringBuilder sb = new StringBuilder(); 50 | String[] aLines = a.split("\n"); 51 | String[] bLines = b.split("\n"); 52 | int max = Math.max(aLines.length, bLines.length); 53 | for (int i = 0; i < max; i++) { 54 | if (i < aLines.length) { 55 | sb.append(aLines[i]).append(repeat(" ", width(a) - aLines[i].length())); 56 | } 57 | else { 58 | sb.append(repeat(" ", width(a))); 59 | } 60 | if (i < bLines.length) { 61 | sb.append(" ").append(bLines[i]); 62 | } 63 | sb.append("\n"); 64 | } 65 | return sb.toString(); 66 | } 67 | 68 | private static int width(String s) { 69 | int max = 0; 70 | for (String line : s.split("\n")) { 71 | max = Math.max(max, line.length()); 72 | } 73 | return max; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/nodes/definitions/AttrAssignNode.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.nodes.definitions; 2 | 3 | import lemon.jpizza.JPType; 4 | import lemon.jpizza.nodes.Node; 5 | import lemon.jpizza.Token; 6 | 7 | import java.util.ArrayList; 8 | import java.util.Collections; 9 | import java.util.List; 10 | 11 | public class AttrAssignNode extends Node { 12 | public final Token var_name_tok; 13 | public final Node value_node; 14 | 15 | public AttrAssignNode(Token var_name_tok, Node value_node) { 16 | this.var_name_tok = var_name_tok; 17 | this.value_node = value_node; 18 | 19 | pos_start = var_name_tok.pos_start; pos_end = var_name_tok.pos_end; 20 | jptype = JPType.AttrAssign; 21 | } 22 | 23 | @Override 24 | public Node optimize() { 25 | return new AttrAssignNode(var_name_tok, value_node.optimize()); 26 | } 27 | 28 | @Override 29 | public List getChildren() { 30 | return new ArrayList<>(Collections.singletonList(value_node)); 31 | } 32 | 33 | @Override 34 | public String visualize() { 35 | return "attr " + var_name_tok.value; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/nodes/definitions/AttrDeclareNode.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.nodes.definitions; 2 | 3 | import lemon.jpizza.nodes.Node; 4 | import lemon.jpizza.Token; 5 | 6 | import java.util.ArrayList; 7 | import java.util.Collections; 8 | import java.util.List; 9 | 10 | public class AttrDeclareNode extends Node { 11 | public final Token attrToken; 12 | public final List type; 13 | public final boolean isstatic; 14 | public final boolean isprivate; 15 | public final Node nValue; 16 | public final String name; 17 | 18 | public AttrDeclareNode(Token attrToken) { 19 | this.attrToken = attrToken; 20 | 21 | type = Collections.singletonList("any"); 22 | isstatic = false; 23 | isprivate = false; 24 | nValue = null; 25 | 26 | name = attrToken.value.toString(); 27 | 28 | pos_start = attrToken.pos_start; pos_end = attrToken.pos_end; 29 | } 30 | 31 | public AttrDeclareNode(Token attrToken, List type, boolean isstatic, boolean isprivate, Node value) { 32 | this.attrToken = attrToken; 33 | this.type = type; 34 | this.isstatic = isstatic; 35 | this.isprivate = isprivate; 36 | this.nValue = value; 37 | 38 | name = attrToken.value.toString(); 39 | 40 | pos_start = attrToken.pos_start; pos_end = attrToken.pos_end; 41 | } 42 | 43 | @Override 44 | public Node optimize() { 45 | return new AttrDeclareNode( 46 | attrToken, 47 | type, 48 | isstatic, 49 | isprivate, 50 | nValue == null ? null : nValue.optimize() 51 | ); 52 | } 53 | 54 | @Override 55 | public List getChildren() { 56 | return new ArrayList<>(Collections.singletonList(nValue)); 57 | } 58 | 59 | @Override 60 | public String visualize() { 61 | return "!attr " + name; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/nodes/definitions/ClassDefNode.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.nodes.definitions; 2 | 3 | import lemon.jpizza.JPType; 4 | import lemon.jpizza.nodes.Node; 5 | import lemon.jpizza.Position; 6 | import lemon.jpizza.Token; 7 | 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | 11 | public class ClassDefNode extends Node { 12 | public final Token class_name_tok; 13 | public final List attributes; 14 | public final List arg_name_toks; 15 | public final Node make_node; 16 | public final List methods; 17 | public final List arg_type_toks; 18 | public final List generic_toks; 19 | public final List defaults; 20 | public final int defaultCount; 21 | public final Token parentToken; 22 | public final String argname; 23 | public final String kwargname; 24 | 25 | public ClassDefNode(Token class_name_tok, List attributes, List arg_name_toks, 26 | List arg_type_toks, Node make_node, List methods, Position pos_end, 27 | List defaults, int defaultCount, Token pTK, List generics, String argname, 28 | String kwargname) { 29 | this.class_name_tok = class_name_tok; 30 | this.defaultCount = defaultCount; 31 | this.generic_toks = generics; 32 | this.defaults = defaults; 33 | this.attributes = attributes; 34 | this.make_node = make_node; 35 | this.arg_name_toks = arg_name_toks; 36 | this.arg_type_toks = arg_type_toks; 37 | this.methods = methods; 38 | this.pos_end = pos_end; 39 | this.pos_start = class_name_tok.pos_start; 40 | this.argname = argname; 41 | this.kwargname = kwargname; 42 | 43 | parentToken = pTK; 44 | jptype = JPType.ClassDef; 45 | } 46 | 47 | @Override 48 | public Node optimize() { 49 | List optimizedAttributes = new ArrayList<>(); 50 | for (AttrDeclareNode attr : attributes) { 51 | optimizedAttributes.add((AttrDeclareNode) attr.optimize()); 52 | } 53 | Node optimizedMake = make_node.optimize(); 54 | List optimizedMethods = new ArrayList<>(); 55 | for (MethDefNode method : methods) { 56 | optimizedMethods.add((MethDefNode) method.optimize()); 57 | } 58 | List optimizedDefaults = new ArrayList<>(); 59 | for (Node default_ : defaults) { 60 | optimizedDefaults.add(default_.optimize()); 61 | } 62 | return new ClassDefNode(class_name_tok, optimizedAttributes, arg_name_toks, arg_type_toks, 63 | optimizedMake, optimizedMethods, pos_end, optimizedDefaults, defaults.size(), 64 | parentToken, generic_toks, argname, kwargname); 65 | } 66 | 67 | @Override 68 | public List getChildren() { 69 | List children = new ArrayList<>(attributes); 70 | children.add(make_node); 71 | children.addAll(methods); 72 | return children; 73 | } 74 | 75 | @Override 76 | public String visualize() { 77 | return "class " + class_name_tok.value; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/nodes/definitions/DecoratorNode.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.nodes.definitions; 2 | 3 | import lemon.jpizza.JPType; 4 | import lemon.jpizza.Token; 5 | import lemon.jpizza.nodes.Node; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | public class DecoratorNode extends Node { 11 | public Node decorator; 12 | public Node decorated; 13 | public Token name; 14 | 15 | public DecoratorNode(Node decorator, Node fn, Token name) { 16 | this.decorator = decorator; 17 | this.decorated = fn; 18 | this.name = name; 19 | 20 | pos_start = decorator.pos_start; 21 | pos_end = decorated.pos_end; 22 | jptype = JPType.Decorator; 23 | } 24 | 25 | @Override 26 | public Node optimize() { 27 | return new DecoratorNode(decorator.optimize(), decorated.optimize(), name); 28 | } 29 | 30 | @Override 31 | public List getChildren() { 32 | List children = new ArrayList<>(); 33 | children.add(decorator); 34 | children.add(decorated); 35 | return children; 36 | } 37 | 38 | @Override 39 | public String visualize() { 40 | return "/decorator de " + name.value + "/"; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/nodes/definitions/DestructNode.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.nodes.definitions; 2 | 3 | import lemon.jpizza.JPType; 4 | import lemon.jpizza.Token; 5 | import lemon.jpizza.nodes.Node; 6 | 7 | import java.util.*; 8 | 9 | public class DestructNode extends Node { 10 | public final Node target; 11 | public List subs = new ArrayList<>(); 12 | public boolean glob = false; 13 | 14 | public DestructNode(Node tar) { 15 | target = tar; 16 | glob = true; 17 | 18 | pos_start = tar.pos_start; 19 | pos_end = tar.pos_end; 20 | jptype = JPType.Destruct; 21 | } 22 | 23 | public DestructNode(Node tar, List tars) { 24 | target = tar; 25 | subs = tars; 26 | 27 | pos_start = tars.get(0).pos_start; 28 | pos_end = tar.pos_end; 29 | jptype = JPType.Destruct; 30 | } 31 | 32 | @Override 33 | public Node optimize() { 34 | Node target = this.target.optimize(); 35 | if (glob) return new DestructNode(target); 36 | return new DestructNode(target, subs); 37 | } 38 | 39 | @Override 40 | public List getChildren() { 41 | return new ArrayList<>(Collections.singletonList(target)); 42 | } 43 | 44 | @Override 45 | public String visualize() { 46 | if (glob) { 47 | return "destruct *"; 48 | } 49 | else { 50 | StringBuilder sb = new StringBuilder(); 51 | sb.append("destruct "); 52 | for (Token struct : subs) 53 | sb.append(struct.value.toString()).append(" "); 54 | return sb.substring(0, sb.length() - 1); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/nodes/definitions/DynAssignNode.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.nodes.definitions; 2 | 3 | import lemon.jpizza.JPType; 4 | import lemon.jpizza.nodes.Node; 5 | import lemon.jpizza.Token; 6 | 7 | import java.util.ArrayList; 8 | import java.util.Collections; 9 | import java.util.List; 10 | 11 | public class DynAssignNode extends Node { 12 | public final Token var_name_tok; 13 | public final Node value_node; 14 | 15 | public DynAssignNode(Token var_name_tok, Node value_node) { 16 | this.var_name_tok = var_name_tok; 17 | this.value_node = value_node; 18 | 19 | pos_start = var_name_tok.pos_start; pos_end = var_name_tok.pos_end; 20 | jptype = JPType.DynAssign; 21 | } 22 | 23 | @Override 24 | public Node optimize() { 25 | return new DynAssignNode(var_name_tok, value_node.optimize()); 26 | } 27 | 28 | @Override 29 | public List getChildren() { 30 | return new ArrayList<>(Collections.singletonList(value_node)); 31 | } 32 | 33 | @Override 34 | public String visualize() { 35 | return "macro"; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/nodes/definitions/FuncDefNode.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.nodes.definitions; 2 | 3 | import lemon.jpizza.JPType; 4 | import lemon.jpizza.nodes.Node; 5 | import lemon.jpizza.Token; 6 | 7 | import java.util.ArrayList; 8 | import java.util.Collections; 9 | import java.util.List; 10 | import java.util.stream.Collectors; 11 | 12 | public class FuncDefNode extends Node { 13 | public final Token var_name_tok; 14 | public final List arg_name_toks; 15 | public final Node body_node; 16 | public final boolean autoreturn; 17 | public final boolean async; 18 | public final List arg_type_toks; 19 | public final List generic_toks; 20 | public final List returnType; 21 | public final List defaults; 22 | public final int defaultCount; 23 | public boolean catcher = false; 24 | public final String argname; 25 | public final String kwargname; 26 | 27 | public FuncDefNode(Token var_name_tok, List arg_name_toks, List arg_type_toks, Node body_node, 28 | boolean autoreturn, boolean async, List returnType, List defaults, int defaultCount, 29 | List generic_toks, String argname, String kwargname) { 30 | this.var_name_tok = var_name_tok; 31 | this.argname = argname; 32 | this.kwargname = kwargname; 33 | this.generic_toks = generic_toks; 34 | this.async = async; 35 | this.arg_name_toks = arg_name_toks; 36 | this.arg_type_toks = arg_type_toks; 37 | this.body_node = body_node; 38 | this.autoreturn = autoreturn; 39 | this.returnType = returnType; 40 | this.defaults = defaults; 41 | this.defaultCount = defaultCount; 42 | 43 | pos_start = var_name_tok != null ? var_name_tok.pos_start : ( 44 | arg_name_toks != null && arg_name_toks.size() > 0 ? arg_name_toks.get(0).pos_start : body_node.pos_start 45 | ); 46 | pos_end = body_node.pos_end; 47 | jptype = JPType.FuncDef; 48 | } 49 | 50 | public FuncDefNode setCatcher(boolean c) { 51 | this.catcher = c; 52 | return this; 53 | } 54 | 55 | @Override 56 | public Node optimize() { 57 | Node body = body_node.optimize(); 58 | List optimizedDefaults = new ArrayList<>(); 59 | for (Node n : defaults) { 60 | optimizedDefaults.add(n.optimize()); 61 | } 62 | return new FuncDefNode(var_name_tok, arg_name_toks, arg_type_toks, body, autoreturn, async, returnType, 63 | optimizedDefaults, defaultCount, generic_toks, argname, kwargname).setCatcher(catcher); 64 | } 65 | 66 | @Override 67 | public List getChildren() { 68 | return new ArrayList<>(Collections.singletonList(body_node)); 69 | } 70 | 71 | @Override 72 | public String visualize() { 73 | return "fn" + ( 74 | var_name_tok != null ? 75 | " " + var_name_tok.value : "" 76 | ) + "(" + arg_name_toks.stream().map(x -> x.value.toString()).collect(Collectors.joining(", ")) + ")"; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/nodes/definitions/LetNode.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.nodes.definitions; 2 | 3 | import lemon.jpizza.JPType; 4 | import lemon.jpizza.nodes.Node; 5 | import lemon.jpizza.Token; 6 | 7 | import java.util.ArrayList; 8 | import java.util.Collections; 9 | import java.util.List; 10 | 11 | public class LetNode extends Node { 12 | public final Token var_name_tok; 13 | public final Node value_node; 14 | 15 | public LetNode(Token var_name_tok, Node value_node) { 16 | this.var_name_tok = var_name_tok; 17 | this.value_node = value_node; 18 | 19 | pos_start = var_name_tok.pos_start; pos_end = var_name_tok.pos_end; 20 | jptype = JPType.Let; 21 | } 22 | 23 | @Override 24 | public Node optimize() { 25 | Node val = value_node.optimize(); 26 | return new LetNode(var_name_tok, val); 27 | } 28 | 29 | @Override 30 | public List getChildren() { 31 | return new ArrayList<>(Collections.singletonList(value_node)); 32 | } 33 | 34 | @Override 35 | public String visualize() { 36 | return "let " + var_name_tok.value; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/nodes/definitions/MethDefNode.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.nodes.definitions; 2 | 3 | import lemon.jpizza.JPType; 4 | import lemon.jpizza.nodes.Node; 5 | import lemon.jpizza.Token; 6 | 7 | import java.util.ArrayList; 8 | import java.util.Collections; 9 | import java.util.List; 10 | 11 | public class MethDefNode extends Node { 12 | public final Token var_name_tok; 13 | public final List arg_name_toks; 14 | public final Node body_node; 15 | public final boolean autoreturn; 16 | public final boolean async; 17 | public final boolean bin; 18 | public final List arg_type_toks; 19 | public final List generic_toks; 20 | public final List returnType; 21 | public final List defaults; 22 | public final int defaultCount; 23 | public boolean catcher = false; 24 | public final boolean stat; 25 | public final boolean priv; 26 | public final String argname; 27 | public final String kwargname; 28 | 29 | public MethDefNode(Token var_name_tok, List arg_name_toks, List arg_type_toks, Node body_node, 30 | boolean autoreturn, boolean bin, boolean async, List returnType, List defaults, 31 | int defaultCount, List generics, boolean stat, boolean priv, String argname, 32 | String kwargname) { 33 | this.var_name_tok = var_name_tok; 34 | this.stat = stat; 35 | this.priv = priv; 36 | this.generic_toks = generics; 37 | this.async = async; 38 | this.arg_name_toks = arg_name_toks; 39 | this.arg_type_toks = arg_type_toks; 40 | this.body_node = body_node; 41 | this.autoreturn = autoreturn; 42 | this.bin = bin; 43 | this.returnType = returnType; 44 | this.defaults = defaults; 45 | this.defaultCount = defaultCount; 46 | this.argname = argname; 47 | this.kwargname = kwargname; 48 | 49 | pos_start = var_name_tok.pos_start; 50 | pos_end = body_node.pos_end; 51 | jptype = JPType.MethDef; 52 | } 53 | 54 | public MethDefNode setCatcher(boolean c) { 55 | this.catcher = c; 56 | return this; 57 | } 58 | 59 | public FuncDefNode asFuncDef() { 60 | return new FuncDefNode(var_name_tok, arg_name_toks, arg_type_toks, body_node, autoreturn, async, 61 | returnType, defaults, defaultCount, generic_toks, argname, kwargname).setCatcher(catcher); 62 | } 63 | 64 | @Override 65 | public Node optimize() { 66 | Node body = body_node.optimize(); 67 | List optDefaults = new ArrayList<>(); 68 | for (Node n : defaults) { 69 | optDefaults.add(n.optimize()); 70 | } 71 | return new MethDefNode(var_name_tok, arg_name_toks, arg_type_toks, body, autoreturn, bin, async, 72 | returnType, optDefaults, defaultCount, generic_toks, stat, priv, argname, kwargname) 73 | .setCatcher(catcher); 74 | } 75 | 76 | @Override 77 | public List getChildren() { 78 | return new ArrayList<>(Collections.singletonList(body_node)); 79 | } 80 | 81 | @Override 82 | public String visualize() { 83 | String stc = stat ? "static " : ""; 84 | String prv = priv ? "private " : "public "; 85 | return prv + stc + "mthd " + var_name_tok.value + "(" + arg_name_toks.stream().map(x -> x.value.toString()).reduce("", (a, b) -> a + b + ",") + ")"; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/nodes/definitions/VarAssignNode.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.nodes.definitions; 2 | 3 | import lemon.jpizza.JPType; 4 | import lemon.jpizza.nodes.Node; 5 | import lemon.jpizza.Token; 6 | 7 | import java.util.ArrayList; 8 | import java.util.Collections; 9 | import java.util.List; 10 | 11 | public class VarAssignNode extends Node { 12 | public final Token var_name_tok; 13 | public final Node value_node; 14 | public final boolean locked; 15 | public boolean defining; 16 | public Integer min = null; 17 | public Integer max = null; 18 | public List type; 19 | 20 | public VarAssignNode setType(List type) { 21 | this.type = type; 22 | return this; 23 | } 24 | 25 | public VarAssignNode setDefining(boolean defining) { 26 | this.defining = defining; 27 | return this; 28 | } 29 | 30 | public VarAssignNode setRange(Integer min, Integer max) { 31 | this.max = max; 32 | this.min = min; 33 | return this; 34 | } 35 | 36 | public VarAssignNode(Token var_name_tok, Node value_node) { 37 | this.var_name_tok = var_name_tok; 38 | this.value_node = value_node; 39 | 40 | locked = false; 41 | defining = true; 42 | pos_start = var_name_tok.pos_start; pos_end = var_name_tok.pos_end; 43 | jptype = JPType.VarAssign; 44 | } 45 | 46 | public VarAssignNode(Token var_name_tok, Node value_node, boolean locked) { 47 | this.var_name_tok = var_name_tok; 48 | this.value_node = value_node; 49 | this.locked = locked; 50 | 51 | defining = true; 52 | pos_start = var_name_tok.pos_start; pos_end = var_name_tok.pos_end; 53 | jptype = JPType.VarAssign; 54 | } 55 | 56 | @SuppressWarnings("unused") 57 | public VarAssignNode(Token var_name_tok, Node value_node, boolean defining, int _x) { 58 | this.var_name_tok = var_name_tok; 59 | this.value_node = value_node; 60 | locked = false; 61 | 62 | this.defining = defining; 63 | pos_start = var_name_tok.pos_start; pos_end = var_name_tok.pos_end; 64 | jptype = JPType.VarAssign; 65 | } 66 | 67 | @Override 68 | public Node optimize() { 69 | Node val = value_node.optimize(); 70 | return new VarAssignNode(var_name_tok, val, locked) 71 | .setDefining(defining) 72 | .setRange(min, max) 73 | .setType(type); 74 | } 75 | 76 | @Override 77 | public List getChildren() { 78 | return new ArrayList<>(Collections.singletonList(value_node)); 79 | } 80 | 81 | @Override 82 | public String visualize() { 83 | return "var " + var_name_tok.value; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/nodes/expressions/AssertNode.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.nodes.expressions; 2 | 3 | import lemon.jpizza.JPType; 4 | import lemon.jpizza.nodes.Node; 5 | 6 | import java.util.ArrayList; 7 | import java.util.Collections; 8 | import java.util.List; 9 | 10 | public class AssertNode extends Node { 11 | public final Node condition; 12 | public AssertNode(Node condition) { 13 | this.condition = condition; 14 | pos_start = condition.pos_start; 15 | pos_end = condition.pos_end; 16 | jptype = JPType.Assert; 17 | } 18 | 19 | @Override 20 | public Node optimize() { 21 | return new AssertNode(condition.optimize()); 22 | } 23 | 24 | @Override 25 | public List getChildren() { 26 | return new ArrayList<>(Collections.singletonList(condition)); 27 | } 28 | 29 | @Override 30 | public String visualize() { 31 | return "assert"; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/nodes/expressions/BodyNode.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.nodes.expressions; 2 | 3 | import lemon.jpizza.JPType; 4 | import lemon.jpizza.Position; 5 | import lemon.jpizza.nodes.Node; 6 | import org.jetbrains.annotations.NotNull; 7 | 8 | import java.util.List; 9 | 10 | public class BodyNode extends Node { 11 | final public List statements; 12 | 13 | public BodyNode(List statements) { 14 | this.statements = statements; 15 | this.pos_start = statements.get(0).pos_start; 16 | this.pos_end = statements.get(statements.size() - 1).pos_end; 17 | this.jptype = JPType.Body; 18 | } 19 | 20 | public BodyNode(List statements, @NotNull Position start, @NotNull Position end) { 21 | this.statements = statements; 22 | this.pos_start = start; 23 | this.pos_end = end; 24 | this.jptype = JPType.Body; 25 | } 26 | 27 | @Override 28 | public Node optimize() { 29 | for (int i = 0; i < statements.size(); i++) { 30 | statements.set(i, statements.get(i).optimize()); 31 | } 32 | return this; 33 | } 34 | 35 | @Override 36 | public List getChildren() { 37 | return statements; 38 | } 39 | 40 | @Override 41 | public String visualize() { 42 | return "< body >"; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/nodes/expressions/BreakNode.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.nodes.expressions; 2 | 3 | import lemon.jpizza.JPType; 4 | import lemon.jpizza.nodes.Node; 5 | import lemon.jpizza.Position; 6 | import org.jetbrains.annotations.NotNull; 7 | 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | 11 | public class BreakNode extends Node { 12 | public BreakNode(@NotNull Position start_pos, @NotNull Position end_pos) { 13 | this.pos_start = start_pos.copy(); this.pos_end = end_pos.copy(); 14 | jptype = JPType.Break; 15 | } 16 | 17 | @Override 18 | public Node optimize() { 19 | return this; 20 | } 21 | 22 | @Override 23 | public List getChildren() { 24 | return new ArrayList<>(); 25 | } 26 | 27 | @Override 28 | public String visualize() { 29 | return "break"; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/nodes/expressions/CallNode.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.nodes.expressions; 2 | 3 | import lemon.jpizza.*; 4 | import lemon.jpizza.nodes.Node; 5 | 6 | import java.util.*; 7 | 8 | public class CallNode extends Node { 9 | public final Node nodeToCall; 10 | public final List argNodes; 11 | public final Map kwargs; 12 | public final List generics; 13 | 14 | public CallNode(Node nodeToCall, List argNodes, List generics, Map kwargs) { 15 | this.nodeToCall = nodeToCall; 16 | this.argNodes = argNodes; 17 | this.generics = generics; 18 | this.kwargs = kwargs; 19 | 20 | pos_start = nodeToCall.pos_start.copy(); 21 | pos_end = (argNodes != null && argNodes.size() > 0 ? argNodes.get(argNodes.size() - 1) : nodeToCall).pos_end.copy(); 22 | jptype = JPType.Call; 23 | } 24 | 25 | @Override 26 | public Node optimize() { 27 | List optimizedArgNodes = new ArrayList<>(); 28 | for (Node argNode : argNodes) { 29 | Node optimized = argNode.optimize(); 30 | if (optimized.jptype == JPType.Spread && optimized.constant) { 31 | SpreadNode spread = (SpreadNode) optimized; 32 | if (spread.internal.jptype == JPType.List) { 33 | for (Node node : spread.internal.asList()) 34 | optimizedArgNodes.add(node.optimize()); 35 | } 36 | } 37 | else { 38 | optimizedArgNodes.add(optimized); 39 | } 40 | } 41 | 42 | Map optimizedKwargs = new HashMap<>(); 43 | for (Map.Entry entry : kwargs.entrySet()) { 44 | Node optimized = entry.getValue().optimize(); 45 | optimizedKwargs.put(entry.getKey(), optimized); 46 | } 47 | 48 | return new CallNode(nodeToCall, optimizedArgNodes, generics, optimizedKwargs); 49 | } 50 | 51 | @Override 52 | public List getChildren() { 53 | List children = new ArrayList<>(); 54 | children.add(nodeToCall); 55 | children.addAll(argNodes); 56 | children.addAll(kwargs.values()); 57 | return children; 58 | } 59 | 60 | @Override 61 | public String visualize() { 62 | return "call"; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/nodes/expressions/CastNode.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.nodes.expressions; 2 | 3 | import lemon.jpizza.JPType; 4 | import lemon.jpizza.Token; 5 | import lemon.jpizza.nodes.Node; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | public class CastNode extends Node { 11 | public final Node expr; 12 | public final Token type; 13 | 14 | public CastNode(Node expr, Token type) { 15 | this.expr = expr; 16 | this.type = type; 17 | pos_start = type.pos_start; 18 | pos_end = expr.pos_end; 19 | jptype = JPType.Cast; 20 | } 21 | 22 | @Override 23 | public Node optimize() { 24 | return this; 25 | } 26 | 27 | @Override 28 | public List getChildren() { 29 | List children = new ArrayList<>(); 30 | children.add(expr); 31 | return children; 32 | } 33 | 34 | @Override 35 | public String visualize() { 36 | return "| " + String.join("", (List) type.value) + " |"; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/nodes/expressions/ClaccessNode.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.nodes.expressions; 2 | 3 | import lemon.jpizza.JPType; 4 | import lemon.jpizza.nodes.Node; 5 | import lemon.jpizza.Token; 6 | 7 | import java.util.ArrayList; 8 | import java.util.Collections; 9 | import java.util.List; 10 | 11 | public class ClaccessNode extends Node { 12 | public final Node class_tok; 13 | public final Token attr_name_tok; 14 | 15 | public ClaccessNode(Node cls, Token atr) { 16 | class_tok = cls; 17 | attr_name_tok = atr; 18 | pos_start = cls.pos_start.copy(); pos_end = atr.pos_end.copy(); 19 | jptype = JPType.Claccess; 20 | } 21 | 22 | @Override 23 | public Node optimize() { 24 | return new ClaccessNode(class_tok.optimize(), attr_name_tok); 25 | } 26 | 27 | @Override 28 | public List getChildren() { 29 | return new ArrayList<>(Collections.singletonList(class_tok)); 30 | } 31 | 32 | @Override 33 | public String visualize() { 34 | return "access::" + attr_name_tok.value; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/nodes/expressions/ContinueNode.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.nodes.expressions; 2 | 3 | import lemon.jpizza.JPType; 4 | import lemon.jpizza.nodes.Node; 5 | import lemon.jpizza.Position; 6 | import org.jetbrains.annotations.NotNull; 7 | 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | 11 | public class ContinueNode extends Node { 12 | public ContinueNode(@NotNull Position start_pos, @NotNull Position end_pos) { 13 | this.pos_start = start_pos.copy(); this.pos_end = end_pos.copy(); 14 | jptype = JPType.Continue; 15 | } 16 | 17 | @Override 18 | public Node optimize() { 19 | return this; 20 | } 21 | 22 | @Override 23 | public List getChildren() { 24 | return new ArrayList<>(); 25 | } 26 | 27 | @Override 28 | public String visualize() { 29 | return "continue"; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/nodes/expressions/DerefNode.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.nodes.expressions; 2 | 3 | import lemon.jpizza.JPType; 4 | import lemon.jpizza.nodes.Node; 5 | 6 | import java.util.ArrayList; 7 | import java.util.Collections; 8 | import java.util.List; 9 | 10 | public class DerefNode extends Node { 11 | public final Node ref; 12 | public DerefNode(Node ref) { 13 | this.ref = ref; 14 | 15 | pos_start = ref.pos_start; pos_end = ref.pos_end; 16 | jptype = JPType.Deref; 17 | } 18 | 19 | @Override 20 | public Node optimize() { 21 | return new DerefNode(ref.optimize()); 22 | } 23 | 24 | @Override 25 | public List getChildren() { 26 | return new ArrayList<>(Collections.singletonList(ref)); 27 | } 28 | 29 | @Override 30 | public String visualize() { 31 | return "*Ref"; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/nodes/expressions/DropNode.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.nodes.expressions; 2 | 3 | import lemon.jpizza.JPType; 4 | import lemon.jpizza.nodes.Node; 5 | import lemon.jpizza.Token; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | public class DropNode extends Node { 11 | public final Token varTok; 12 | 13 | public DropNode(Token varTok) { 14 | pos_start = varTok.pos_start; pos_end = varTok.pos_end; 15 | this.varTok = varTok; 16 | jptype = JPType.Drop; 17 | } 18 | 19 | @Override 20 | public Node optimize() { 21 | return this; 22 | } 23 | 24 | @Override 25 | public List getChildren() { 26 | return new ArrayList<>(); 27 | } 28 | 29 | @Override 30 | public String visualize() { 31 | return "free " + varTok.value; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/nodes/expressions/ExtendNode.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.nodes.expressions; 2 | 3 | import lemon.jpizza.JPType; 4 | import lemon.jpizza.Token; 5 | import lemon.jpizza.nodes.Node; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | public class ExtendNode extends Node { 11 | public final Token file_name_tok; 12 | 13 | public ExtendNode(Token file_name_tok) { 14 | this.file_name_tok = file_name_tok; 15 | 16 | pos_start = file_name_tok.pos_start.copy(); pos_end = file_name_tok.pos_end.copy(); 17 | jptype = JPType.Import; 18 | } 19 | 20 | @Override 21 | public Node optimize() { 22 | return this; 23 | } 24 | 25 | @Override 26 | public List getChildren() { 27 | return new ArrayList<>(); 28 | } 29 | 30 | @Override 31 | public String visualize() { 32 | return "extend " + file_name_tok.value; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/nodes/expressions/ForNode.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.nodes.expressions; 2 | 3 | import lemon.jpizza.JPType; 4 | import lemon.jpizza.nodes.Node; 5 | import lemon.jpizza.Token; 6 | 7 | import java.util.Arrays; 8 | import java.util.List; 9 | 10 | public class ForNode extends Node { 11 | public final Token var_name_tok; 12 | public final Node start_value_node; 13 | public final Node end_value_node; 14 | public final Node step_value_node; 15 | public final Node body_node; 16 | public final boolean retnull; 17 | 18 | public ForNode(Token var_name_tok, Node start_value_node, Node end_value_node, Node step_value_node, Node body_node, 19 | boolean retnull) { 20 | this.var_name_tok = var_name_tok; 21 | this.start_value_node = start_value_node; 22 | this.end_value_node = end_value_node; 23 | this.step_value_node = step_value_node; 24 | this.body_node = body_node; 25 | this.retnull = retnull; 26 | 27 | pos_start = var_name_tok.pos_start.copy(); pos_end = body_node.pos_end.copy(); 28 | jptype = JPType.For; 29 | } 30 | 31 | @Override 32 | public Node optimize() { 33 | Node start = start_value_node.optimize(); 34 | Node end = end_value_node.optimize(); 35 | Node step = null; 36 | if (step_value_node != null) 37 | step = step_value_node.optimize(); 38 | Node body = body_node.optimize(); 39 | return new ForNode(var_name_tok, start, end, step, body, retnull); 40 | } 41 | 42 | @Override 43 | public List getChildren() { 44 | return Arrays.asList(start_value_node, end_value_node, step_value_node, body_node); 45 | } 46 | 47 | @Override 48 | public String visualize() { 49 | return "for(" + var_name_tok.value + ")"; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/nodes/expressions/ImportNode.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.nodes.expressions; 2 | 3 | import lemon.jpizza.*; 4 | import lemon.jpizza.nodes.Node; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | public class ImportNode extends Node { 10 | public final Token file_name_tok; 11 | public final Token as_tok; 12 | 13 | public ImportNode(Token file_name_tok) { 14 | this.file_name_tok = file_name_tok; 15 | this.as_tok = null; 16 | 17 | pos_start = file_name_tok.pos_start.copy(); pos_end = file_name_tok.pos_end.copy(); 18 | jptype = JPType.Import; 19 | } 20 | 21 | public ImportNode(Token file_name_tok, Token as_tok) { 22 | this.file_name_tok = file_name_tok; 23 | this.as_tok = as_tok; 24 | 25 | pos_start = file_name_tok.pos_start.copy(); pos_end = as_tok.pos_end.copy(); 26 | jptype = JPType.Import; 27 | } 28 | 29 | @Override 30 | public Node optimize() { 31 | return this; 32 | } 33 | 34 | @Override 35 | public List getChildren() { 36 | return new ArrayList<>(); 37 | } 38 | 39 | @Override 40 | public String visualize() { 41 | return "import " + file_name_tok.value; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/nodes/expressions/IterNode.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.nodes.expressions; 2 | 3 | import lemon.jpizza.JPType; 4 | import lemon.jpizza.nodes.Node; 5 | import lemon.jpizza.Token; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | public class IterNode extends Node { 11 | public final Token var_name_tok; 12 | public final Node iterable_node; 13 | public final Node body_node; 14 | public final boolean retnull; 15 | 16 | public IterNode(Token var_name_tok, Node iterable_node, Node body_node, 17 | boolean retnull) { 18 | this.var_name_tok = var_name_tok; 19 | this.iterable_node = iterable_node; 20 | this.body_node = body_node; 21 | this.retnull = retnull; 22 | 23 | pos_start = var_name_tok.pos_start.copy(); pos_end = body_node.pos_end.copy(); 24 | jptype = JPType.Iter; 25 | } 26 | 27 | @Override 28 | public Node optimize() { 29 | Node iterable = iterable_node.optimize(); 30 | Node body = body_node.optimize(); 31 | return new IterNode(var_name_tok, iterable, body, retnull); 32 | } 33 | 34 | @Override 35 | public List getChildren() { 36 | List children = new ArrayList<>(); 37 | children.add(iterable_node); 38 | children.add(body_node); 39 | return children; 40 | } 41 | 42 | @Override 43 | public String visualize() { 44 | return "iter(" + var_name_tok.value + ")"; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/nodes/expressions/PassNode.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.nodes.expressions; 2 | 3 | import lemon.jpizza.JPType; 4 | import lemon.jpizza.nodes.Node; 5 | import lemon.jpizza.Position; 6 | import org.jetbrains.annotations.NotNull; 7 | 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | 11 | public class PassNode extends Node { 12 | public PassNode(@NotNull Position start_pos, @NotNull Position end_pos) { 13 | this.pos_start = start_pos.copy(); this.pos_end = end_pos.copy(); 14 | jptype = JPType.Pass; 15 | } 16 | 17 | @Override 18 | public Node optimize() { 19 | return this; 20 | } 21 | 22 | @Override 23 | public List getChildren() { 24 | return new ArrayList<>(); 25 | } 26 | 27 | @Override 28 | public String visualize() { 29 | return "pass"; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/nodes/expressions/QueryNode.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.nodes.expressions; 2 | 3 | import lemon.jpizza.JPType; 4 | import lemon.jpizza.cases.Case; 5 | import lemon.jpizza.cases.ElseCase; 6 | import lemon.jpizza.nodes.Node; 7 | 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | 11 | public class QueryNode extends Node { 12 | public final List cases; 13 | public final ElseCase else_case; 14 | 15 | public QueryNode(List cases, ElseCase else_case) { 16 | this.else_case = else_case; 17 | this.cases = cases; 18 | pos_start = cases.get(0).condition.pos_start.copy(); pos_end = ( 19 | else_case != null ? else_case.statements : cases.get(cases.size() - 1).condition 20 | ).pos_end.copy(); 21 | jptype = JPType.Query; 22 | } 23 | 24 | @Override 25 | public Node optimize() { 26 | List optimizedCases = new ArrayList<>(); 27 | for (Case c : cases) { 28 | optimizedCases.add(new Case(c.condition.optimize(), c.statements.optimize(), c.returnValue)); 29 | } 30 | return new QueryNode(optimizedCases, else_case != null ? new ElseCase(else_case.statements.optimize(), else_case.returnValue) : null); 31 | } 32 | 33 | @Override 34 | public List getChildren() { 35 | List children = new ArrayList<>(); 36 | for (Case c : cases) { 37 | children.add(c.condition); 38 | children.add(c.statements); 39 | } 40 | if (else_case != null) { 41 | children.add(else_case.statements); 42 | } 43 | return children; 44 | } 45 | 46 | @Override 47 | public String visualize() { 48 | return "query"; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/nodes/expressions/ReturnNode.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.nodes.expressions; 2 | 3 | import lemon.jpizza.JPType; 4 | import lemon.jpizza.nodes.Node; 5 | import lemon.jpizza.Position; 6 | import org.jetbrains.annotations.NotNull; 7 | 8 | import java.util.ArrayList; 9 | import java.util.Collections; 10 | import java.util.List; 11 | 12 | public class ReturnNode extends Node { 13 | public final Node nodeToReturn; 14 | 15 | public ReturnNode(Node nodeToReturn, @NotNull Position pos_start, @NotNull Position pos_end) { 16 | this.nodeToReturn = nodeToReturn; 17 | this.pos_start = pos_start.copy(); this.pos_end = pos_end.copy(); 18 | jptype = JPType.Return; 19 | } 20 | 21 | @Override 22 | public Node optimize() { 23 | return new ReturnNode(nodeToReturn != null ? nodeToReturn.optimize() : null, pos_start, pos_end); 24 | } 25 | 26 | @Override 27 | public List getChildren() { 28 | return new ArrayList<>(Collections.singletonList(nodeToReturn)); 29 | } 30 | 31 | @Override 32 | public String visualize() { 33 | return "return"; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/nodes/expressions/ScopeNode.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.nodes.expressions; 2 | 3 | import lemon.jpizza.JPType; 4 | import lemon.jpizza.nodes.Node; 5 | 6 | import java.util.ArrayList; 7 | import java.util.Collections; 8 | import java.util.List; 9 | 10 | public class ScopeNode extends Node { 11 | public final Node statements; 12 | public final String scopeName; 13 | 14 | public ScopeNode(String name, Node states) { 15 | statements = states; 16 | scopeName = name; 17 | 18 | pos_start = states.pos_start; 19 | pos_end = states.pos_end; 20 | jptype = JPType.Scope; 21 | } 22 | 23 | @Override 24 | public Node optimize() { 25 | return new ScopeNode(scopeName, statements.optimize()); 26 | } 27 | 28 | @Override 29 | public List getChildren() { 30 | return new ArrayList<>(Collections.singletonList(statements)); 31 | } 32 | 33 | @Override 34 | public String visualize() { 35 | return "scope" + (scopeName == null ? "" : "[" + scopeName + "]"); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/nodes/expressions/SpreadNode.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.nodes.expressions; 2 | 3 | import lemon.jpizza.JPType; 4 | import lemon.jpizza.nodes.Node; 5 | 6 | import java.util.ArrayList; 7 | import java.util.Collections; 8 | import java.util.List; 9 | 10 | public class SpreadNode extends Node { 11 | public final Node internal; 12 | public SpreadNode(Node internal) { 13 | this.internal = internal; 14 | pos_start = internal.pos_start; pos_end = internal.pos_end; 15 | this.jptype = JPType.Spread; 16 | constant = internal.constant; 17 | } 18 | 19 | @Override 20 | public Node optimize() { 21 | return new SpreadNode(internal.optimize()); 22 | } 23 | 24 | @Override 25 | public List getChildren() { 26 | return new ArrayList<>(Collections.singletonList(internal)); 27 | } 28 | 29 | @Override 30 | public String visualize() { 31 | return "..."; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/nodes/expressions/SwitchNode.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.nodes.expressions; 2 | 3 | import lemon.jpizza.JPType; 4 | import lemon.jpizza.cases.Case; 5 | import lemon.jpizza.cases.ElseCase; 6 | import lemon.jpizza.nodes.Node; 7 | 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | 11 | public class SwitchNode extends Node { 12 | public final boolean match; 13 | public final List cases; 14 | public final ElseCase elseCase; 15 | public final Node reference; 16 | 17 | public SwitchNode(Node ref, List css, ElseCase else_case, boolean isMatch) { 18 | elseCase = else_case; 19 | match = isMatch; 20 | cases = css; 21 | reference = ref; 22 | pos_start = (cases.size() > 0 ? cases.get(0).condition : ref).pos_start.copy(); 23 | pos_end = (else_case != null ? else_case.statements : 24 | (cases.size() > 0 ? cases.get(cases.size() - 1).condition : ref) 25 | ).pos_end.copy(); 26 | jptype = JPType.Switch; 27 | } 28 | 29 | @Override 30 | public Node optimize() { 31 | Node ref = reference.optimize(); 32 | List newCases = new ArrayList<>(); 33 | for (Case cs : cases) { 34 | newCases.add(new Case(cs.condition.optimize(), cs.statements.optimize(), cs.returnValue)); 35 | } 36 | ElseCase newElseCase = elseCase != null ? new ElseCase(elseCase.statements.optimize(), elseCase.returnValue) : null; 37 | return new SwitchNode(ref, newCases, newElseCase, match); 38 | } 39 | 40 | @Override 41 | public List getChildren() { 42 | List children = new ArrayList<>(); 43 | children.add(reference); 44 | for (Case cs : cases) { 45 | children.add(cs.condition); 46 | children.add(cs.statements); 47 | } 48 | if (elseCase != null) { 49 | children.add(elseCase.statements); 50 | } 51 | return children; 52 | } 53 | 54 | @Override 55 | public String visualize() { 56 | return match ? "match" : "switch"; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/nodes/expressions/ThrowNode.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.nodes.expressions; 2 | 3 | import lemon.jpizza.JPType; 4 | import lemon.jpizza.nodes.Node; 5 | 6 | import java.util.ArrayList; 7 | import java.util.Arrays; 8 | import java.util.List; 9 | 10 | public class ThrowNode extends Node { 11 | public final Node thrown; 12 | public final Node throwType; 13 | 14 | public ThrowNode(Node throwType, Node thrown) { 15 | this.thrown = thrown; 16 | this.throwType = throwType; 17 | pos_start = throwType.pos_start; pos_end = thrown.pos_end; 18 | jptype = JPType.Throw; 19 | } 20 | 21 | @Override 22 | public Node optimize() { 23 | return new ThrowNode(throwType.optimize(), thrown.optimize()); 24 | } 25 | 26 | @Override 27 | public List getChildren() { 28 | return new ArrayList<>(Arrays.asList(throwType, thrown)); 29 | } 30 | 31 | @Override 32 | public String visualize() { 33 | return "throw"; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/nodes/expressions/UseNode.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.nodes.expressions; 2 | 3 | import lemon.jpizza.JPType; 4 | import lemon.jpizza.nodes.Node; 5 | import lemon.jpizza.Token; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | public class UseNode extends Node { 11 | public final Token useToken; 12 | public final List args; 13 | 14 | public UseNode(Token useToken, List args) { 15 | this.useToken = useToken; 16 | this.args = args; 17 | pos_start = useToken.pos_start.copy(); pos_end = useToken.pos_end.copy(); 18 | jptype = JPType.Use; 19 | } 20 | 21 | @Override 22 | public Node optimize() { 23 | return this; 24 | } 25 | 26 | @Override 27 | public List getChildren() { 28 | return new ArrayList<>(); 29 | } 30 | 31 | @Override 32 | public String visualize() { 33 | String[] args = new String[this.args.size() + 1]; 34 | for (int i = 0; i < args.length - 1; i++) { 35 | args[i + 1] = this.args.get(i).value.toString(); 36 | } 37 | args[0] = useToken.value.toString(); 38 | return "#" + String.join(" ", args); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/nodes/expressions/WhileNode.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.nodes.expressions; 2 | 3 | import lemon.jpizza.JPType; 4 | import lemon.jpizza.nodes.Node; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | public class WhileNode extends Node { 10 | public final Node condition_node; 11 | public final Node body_node; 12 | public final boolean retnull; 13 | public final boolean conLast; 14 | 15 | public WhileNode(Node condition_node, Node body_node, boolean retnull, boolean conLast) { 16 | this.condition_node = condition_node; 17 | this.body_node = body_node; 18 | this.retnull = retnull; 19 | this.conLast = conLast; 20 | pos_start = condition_node.pos_start.copy(); pos_end = body_node.pos_end.copy(); 21 | jptype = JPType.While; 22 | } 23 | 24 | @Override 25 | public Node optimize() { 26 | Node condition = condition_node.optimize(); 27 | Node body = body_node.optimize(); 28 | return new WhileNode(condition, body, retnull, conLast); 29 | } 30 | 31 | @Override 32 | public List getChildren() { 33 | List children = new ArrayList<>(); 34 | children.add(condition_node); 35 | children.add(body_node); 36 | return children; 37 | } 38 | 39 | @Override 40 | public String visualize() { 41 | return "while"; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/nodes/operations/UnaryOpNode.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.nodes.operations; 2 | 3 | import lemon.jpizza.*; 4 | import lemon.jpizza.compiler.vm.VM; 5 | import lemon.jpizza.nodes.Node; 6 | import lemon.jpizza.nodes.values.BooleanNode; 7 | import lemon.jpizza.nodes.values.NumberNode; 8 | 9 | import java.util.ArrayList; 10 | import java.util.Collections; 11 | import java.util.List; 12 | 13 | public class UnaryOpNode extends Node { 14 | public final TokenType op_tok; 15 | public final Node node; 16 | 17 | public UnaryOpNode(TokenType op_tok, Node node) { 18 | this.node = node; 19 | this.op_tok = op_tok; 20 | 21 | constant = node.constant; 22 | 23 | pos_start = node.pos_start.copy(); pos_end = node.pos_end.copy(); 24 | jptype = JPType.UnaryOp; 25 | } 26 | 27 | public String toString() { return String.format("(%s, %s)", op_tok, node); } 28 | 29 | /* 30 | * All unary operations: 31 | * - $ => From Bytes 32 | * - ~ => Bitwise Complement 33 | * - - => Negative 34 | * - ! => Logical Not 35 | * - -- => Decrement 36 | * - ++ => Increment 37 | * - + => Stay the same 38 | */ 39 | 40 | @Override 41 | public Node optimize() { 42 | if (node.constant && op_tok != TokenType.Tilde) { 43 | Node node = this.node.optimize(); 44 | switch (op_tok) { 45 | case Minus: return new NumberNode(-node.asNumber(), node.pos_start, node.pos_end); 46 | case Tilde: return new NumberNode(VM.bitOp( 47 | node.asNumber(), 48 | 0, 49 | (a, b) -> ~a 50 | ), node.pos_start, node.pos_end); 51 | case Bang: return new BooleanNode(!node.asBoolean(), node.pos_start, node.pos_end); 52 | case MinusMinus: 53 | case PlusPlus: return new NumberNode(node.asNumber() + (op_tok == TokenType.PlusPlus ? 1.0 : -1.0), node.pos_start, node.pos_end); 54 | default: return node; 55 | } 56 | } 57 | return this; 58 | } 59 | 60 | @Override 61 | public List getChildren() { 62 | return new ArrayList<>(Collections.singletonList(node)); 63 | } 64 | 65 | @Override 66 | public String visualize() { 67 | switch (op_tok) { 68 | case Minus: return "-"; 69 | case Plus: return "+"; 70 | case DollarSign: return "$"; 71 | case Tilde: return "~"; 72 | case Bang: return "!"; 73 | case MinusMinus: return "--"; 74 | case PlusPlus: return "++"; 75 | default: return ""; 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/nodes/values/BooleanNode.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.nodes.values; 2 | 3 | import lemon.jpizza.*; 4 | import lemon.jpizza.nodes.Node; 5 | 6 | public class BooleanNode extends ValueNode { 7 | public final boolean val; 8 | 9 | public BooleanNode(Token tok) { 10 | super(tok); 11 | val = (boolean) tok.value; 12 | jptype = JPType.Boolean; 13 | } 14 | 15 | public BooleanNode(boolean val, Position start, Position end) { 16 | super(new Token(TokenType.Boolean, start, end)); 17 | this.val = val; 18 | jptype = JPType.Boolean; 19 | } 20 | 21 | @Override 22 | public double asNumber() { 23 | return val ? 1 : 0; 24 | } 25 | 26 | @Override 27 | public boolean asBoolean() { 28 | return val; 29 | } 30 | 31 | @Override 32 | public String asString() { 33 | return String.valueOf(val); 34 | } 35 | 36 | @Override 37 | public boolean equals(Node other) { 38 | if (other instanceof BooleanNode) { 39 | return val == ((BooleanNode) other).val; 40 | } 41 | return false; 42 | } 43 | 44 | @Override 45 | public String visualize() { 46 | return String.valueOf(val); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/nodes/values/BytesNode.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.nodes.values; 2 | 3 | import lemon.jpizza.JPType; 4 | import lemon.jpizza.nodes.Node; 5 | 6 | import java.util.ArrayList; 7 | import java.util.Collections; 8 | import java.util.List; 9 | 10 | 11 | public class BytesNode extends Node { 12 | public final Node toBytes; 13 | 14 | public BytesNode(Node toBytes) { 15 | this.toBytes = toBytes; 16 | this.pos_start = toBytes.pos_start.copy(); this.pos_end = toBytes.pos_end.copy(); 17 | jptype = JPType.Bytes; 18 | } 19 | 20 | @Override 21 | public Node optimize() { 22 | return new BytesNode(toBytes.optimize()); 23 | } 24 | 25 | @Override 26 | public List getChildren() { 27 | return new ArrayList<>(Collections.singletonList(toBytes)); 28 | } 29 | 30 | @Override 31 | public String visualize() { 32 | return "@"; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/nodes/values/DictNode.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.nodes.values; 2 | 3 | import lemon.jpizza.JPType; 4 | import lemon.jpizza.nodes.Node; 5 | import lemon.jpizza.Position; 6 | import org.jetbrains.annotations.NotNull; 7 | 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | import java.util.Map; 11 | import java.util.concurrent.ConcurrentHashMap; 12 | 13 | public class DictNode extends Node { 14 | public final Map dict; 15 | 16 | public DictNode(Map dict, @NotNull Position pos_start, @NotNull Position pos_end) { 17 | this.dict = dict; 18 | 19 | constant = true; 20 | for (Map.Entry entry : dict.entrySet()) { 21 | if (!entry.getKey().constant || !entry.getValue().constant) { 22 | constant = false; 23 | break; 24 | } 25 | } 26 | 27 | this.pos_start = pos_start.copy(); 28 | this.pos_end = pos_end.copy(); 29 | jptype = JPType.Dict; 30 | } 31 | 32 | @Override 33 | public Node optimize() { 34 | Map newDict = new ConcurrentHashMap<>(); 35 | for (Map.Entry entry : dict.entrySet()) { 36 | Node val = entry.getValue().optimize(); 37 | Node key = entry.getKey().optimize(); 38 | newDict.put(key, val); 39 | } 40 | return new DictNode(newDict, pos_start, pos_end); 41 | } 42 | 43 | @Override 44 | public boolean asBoolean() { 45 | return !dict.isEmpty(); 46 | } 47 | 48 | @Override 49 | public String asString() { 50 | StringBuilder result = new StringBuilder("{"); 51 | dict.forEach((k, v) -> { 52 | if (k.jptype == JPType.String) { 53 | result.append('"').append(k.asString()).append('"'); 54 | } 55 | else { 56 | result.append(k.asString()); 57 | } 58 | result.append(": "); 59 | if (v.jptype == JPType.String) { 60 | result.append('"').append(v.asString()).append('"'); 61 | } 62 | else { 63 | result.append(v.asString()); 64 | } 65 | result.append(", "); 66 | }); 67 | if (result.length() > 1) { 68 | result.setLength(result.length() - 2); 69 | } result.append("}"); 70 | return result.toString(); 71 | } 72 | 73 | @Override 74 | public Map asMap() { 75 | return dict; 76 | } 77 | 78 | @Override 79 | public double asNumber() { 80 | return dict.size(); 81 | } 82 | 83 | @Override 84 | public boolean equals(Node other) { 85 | if (other.jptype != JPType.Dict) return false; 86 | DictNode otherDict = (DictNode) other; 87 | if (dict.size() != otherDict.dict.size()) return false; 88 | for (Map.Entry entry : dict.entrySet()) { 89 | Node key = entry.getKey(); 90 | Node value = entry.getValue(); 91 | if (!otherDict.dict.containsKey(key)) return false; 92 | if (!otherDict.dict.get(key).equals(value)) return false; 93 | } return true; 94 | } 95 | 96 | @Override 97 | public List getChildren() { 98 | List children = new ArrayList<>(); 99 | for (Map.Entry entry : dict.entrySet()) { 100 | children.add(entry.getKey()); 101 | children.add(entry.getValue()); 102 | } return children; 103 | } 104 | 105 | @Override 106 | public String visualize() { 107 | return "{ Map }"; 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/nodes/values/EnumNode.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.nodes.values; 2 | 3 | import lemon.jpizza.JPType; 4 | import lemon.jpizza.generators.Parser.EnumChild; 5 | import lemon.jpizza.Token; 6 | 7 | import java.util.List; 8 | 9 | public class EnumNode extends ValueNode { 10 | public final List children; 11 | public final boolean pub; 12 | 13 | public EnumNode(Token tok, List children, boolean pub) { 14 | super(tok); 15 | this.children = children; 16 | this.pub = pub; 17 | jptype = JPType.Enum; 18 | } 19 | 20 | @Override 21 | public String visualize() { 22 | return "Enum"; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/nodes/values/ListNode.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.nodes.values; 2 | 3 | import lemon.jpizza.JPType; 4 | import lemon.jpizza.nodes.Node; 5 | import lemon.jpizza.Position; 6 | import org.jetbrains.annotations.NotNull; 7 | 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | 11 | public class ListNode extends Node { 12 | public final List elements; 13 | 14 | public ListNode(List element_nodes, @NotNull Position pos_start, @NotNull Position pos_end) { 15 | elements = element_nodes; 16 | 17 | constant = true; 18 | for (Node element : elements) { 19 | if (!element.constant) { 20 | constant = false; 21 | break; 22 | } 23 | } 24 | 25 | this.pos_start = pos_start.copy(); this.pos_end = pos_end.copy(); 26 | jptype = JPType.List; 27 | } 28 | 29 | @Override 30 | public Node optimize() { 31 | List optimizedElements = new ArrayList<>(); 32 | for (Node element : elements) { 33 | optimizedElements.add(element.optimize()); 34 | } 35 | return new ListNode(optimizedElements, pos_start, pos_end); 36 | } 37 | 38 | @Override 39 | public double asNumber() { 40 | return elements.size(); 41 | } 42 | 43 | @Override 44 | public List asList() { 45 | return elements; 46 | } 47 | 48 | @Override 49 | public String asString() { 50 | StringBuilder result = new StringBuilder("["); 51 | elements.forEach(k -> { 52 | if (k.jptype == JPType.String) { 53 | result.append('"').append(k.asString()).append('"'); 54 | } 55 | else { 56 | result.append(k.asString()); 57 | } 58 | result.append(", "); 59 | }); 60 | if (result.length() > 1) { 61 | result.setLength(result.length() - 2); 62 | } result.append("]"); 63 | return result.toString(); 64 | } 65 | 66 | @Override 67 | public boolean asBoolean() { 68 | return !elements.isEmpty(); 69 | } 70 | 71 | @Override 72 | public boolean equals(Node other) { 73 | if (other.jptype != JPType.List) 74 | return false; 75 | ListNode otherList = (ListNode) other; 76 | if (otherList.elements.size() != elements.size()) 77 | return false; 78 | for (int i = 0; i < elements.size(); i++) { 79 | if (!elements.get(i).equals(otherList.elements.get(i))) 80 | return false; 81 | } 82 | return true; 83 | } 84 | 85 | @Override 86 | public List getChildren() { 87 | return elements; 88 | } 89 | 90 | @Override 91 | public String visualize() { 92 | return "[ List ]"; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/nodes/values/NullNode.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.nodes.values; 2 | 3 | import lemon.jpizza.JPType; 4 | import lemon.jpizza.nodes.Node; 5 | import lemon.jpizza.Token; 6 | 7 | public class NullNode extends ValueNode { 8 | public NullNode(Token tok) { 9 | super(tok); 10 | jptype = JPType.Null; 11 | } 12 | 13 | @Override 14 | public boolean equals(Node other) { 15 | return other instanceof NullNode; 16 | } 17 | 18 | @Override 19 | public String visualize() { 20 | return "null"; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/nodes/values/NumberNode.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.nodes.values; 2 | 3 | import lemon.jpizza.*; 4 | import lemon.jpizza.nodes.Node; 5 | import org.jetbrains.annotations.NotNull; 6 | 7 | public class NumberNode extends ValueNode { 8 | public final double val; 9 | public final boolean hex; 10 | public final boolean floating; 11 | 12 | public NumberNode(Token tok) { 13 | super(tok); 14 | val = (double) tok.value; 15 | floating = tok.type == TokenType.Float; 16 | hex = false; 17 | jptype = JPType.Number; 18 | } 19 | 20 | public NumberNode(Token tok, boolean hex) { 21 | super(tok); 22 | val = (double) tok.value; 23 | floating = tok.type == TokenType.Float; 24 | this.hex = hex; 25 | jptype = JPType.Number; 26 | } 27 | 28 | public NumberNode(int v, @NotNull Position pos_start, @NotNull Position pos_end) { 29 | super(new Token(TokenType.Identifier, "null", pos_start, pos_end)); 30 | val = v; 31 | hex = true; 32 | floating = false; 33 | jptype = JPType.Number; 34 | } 35 | 36 | public NumberNode(double v, @NotNull Position pos_start, @NotNull Position pos_end) { 37 | super(new Token(TokenType.Identifier, "null", pos_start, pos_end)); 38 | val = v; 39 | hex = true; 40 | floating = true; 41 | jptype = JPType.Number; 42 | } 43 | 44 | @Override 45 | public double asNumber() { 46 | return val; 47 | } 48 | 49 | @Override 50 | public boolean asBoolean() { 51 | return val != 0; 52 | } 53 | 54 | @Override 55 | public String asString() { 56 | return String.valueOf(val); 57 | } 58 | 59 | @Override 60 | public boolean equals(Node other) { 61 | if (other instanceof NumberNode) { 62 | return val == ((NumberNode) other).val; 63 | } 64 | return false; 65 | } 66 | 67 | @Override 68 | public String visualize() { 69 | return String.valueOf(val); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/nodes/values/PatternNode.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.nodes.values; 2 | 3 | import lemon.jpizza.JPType; 4 | import lemon.jpizza.Token; 5 | import lemon.jpizza.nodes.Node; 6 | 7 | import java.util.*; 8 | 9 | public class PatternNode extends Node { 10 | public final Node accessNode; 11 | public final HashMap patterns; 12 | 13 | public PatternNode(Node accessNode, HashMap patterns) { 14 | this.accessNode = accessNode; 15 | this.patterns = patterns; 16 | 17 | pos_start = accessNode.pos_start; pos_end = accessNode.pos_end; 18 | jptype = JPType.Pattern; 19 | } 20 | 21 | @Override 22 | public Node optimize() { 23 | accessNode.optimize(); 24 | for (Node node : patterns.values()) 25 | node.optimize(); 26 | return this; 27 | } 28 | 29 | @Override 30 | public List getChildren() { 31 | return new ArrayList<>(Collections.singletonList(accessNode)); 32 | } 33 | 34 | @Override 35 | public String visualize() { 36 | return "Pattern"; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/nodes/values/RefNode.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.nodes.values; 2 | 3 | import lemon.jpizza.JPType; 4 | import lemon.jpizza.nodes.Node; 5 | 6 | import java.util.ArrayList; 7 | import java.util.Collections; 8 | import java.util.List; 9 | 10 | public class RefNode extends Node { 11 | public final Node inner; 12 | public RefNode(Node inner) { 13 | this.inner = inner; 14 | pos_start = inner.pos_start; pos_end = inner.pos_end; 15 | jptype = JPType.Ref; 16 | } 17 | 18 | @Override 19 | public Node optimize() { 20 | return new RefNode(inner.optimize()); 21 | } 22 | 23 | @Override 24 | public List getChildren() { 25 | return new ArrayList<>(Collections.singletonList(inner)); 26 | } 27 | 28 | @Override 29 | public String visualize() { 30 | return "&Ref"; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/nodes/values/StringNode.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.nodes.values; 2 | 3 | import lemon.jpizza.*; 4 | import lemon.jpizza.nodes.Node; 5 | import org.apache.commons.text.StringEscapeUtils; 6 | 7 | public class StringNode extends ValueNode { 8 | public final String val; 9 | public StringNode(Token tok) { 10 | super(tok); 11 | val = ((Pair) tok.value).a; 12 | jptype = JPType.String; 13 | } 14 | 15 | public StringNode(String val, Position start, Position end) { 16 | super(new Token(TokenType.String, new Pair<>(val, false), start, end)); 17 | this.val = val; 18 | jptype = JPType.String; 19 | } 20 | 21 | @Override 22 | public boolean asBoolean() { 23 | return !val.isEmpty(); 24 | } 25 | 26 | @Override 27 | public String asString() { 28 | return val; 29 | } 30 | 31 | @Override 32 | public double asNumber() { 33 | return val.length(); 34 | } 35 | 36 | @Override 37 | public boolean equals(Node other) { 38 | if (other instanceof StringNode) { 39 | return val.equals(((StringNode) other).val); 40 | } 41 | return false; 42 | } 43 | 44 | @Override 45 | public String visualize() { 46 | return "\"" + StringEscapeUtils.escapeJava(val) + "\""; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/nodes/values/ValueNode.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.nodes.values; 2 | 3 | import lemon.jpizza.JPType; 4 | import lemon.jpizza.nodes.Node; 5 | import lemon.jpizza.Token; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | public class ValueNode extends Node { 11 | public final Token tok; 12 | 13 | public ValueNode(Token tok) { 14 | this.tok = tok; 15 | pos_start = tok.pos_start; pos_end = tok.pos_end; 16 | jptype = JPType.Value; 17 | constant = true; 18 | } 19 | 20 | public String toString() { 21 | return tok.toString(); 22 | } 23 | 24 | @Override 25 | public Node optimize() { 26 | return this; 27 | } 28 | 29 | @Override 30 | public List getChildren() { 31 | return new ArrayList<>(); 32 | } 33 | 34 | @Override 35 | public String visualize() { 36 | return toString(); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/nodes/variables/AttrAccessNode.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.nodes.variables; 2 | 3 | import lemon.jpizza.JPType; 4 | import lemon.jpizza.nodes.Node; 5 | import lemon.jpizza.Token; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | public class AttrAccessNode extends Node { 11 | public final Token var_name_tok; 12 | 13 | public AttrAccessNode(Token var_name_tok) { 14 | this.var_name_tok = var_name_tok; 15 | pos_start = var_name_tok.pos_start.copy(); pos_end = var_name_tok.pos_end.copy(); 16 | jptype = JPType.AttrAccess; 17 | } 18 | 19 | @Override 20 | public Node optimize() { 21 | return this; 22 | } 23 | 24 | @Override 25 | public List getChildren() { 26 | return new ArrayList<>(); 27 | } 28 | 29 | @Override 30 | public String visualize() { 31 | return var_name_tok.value.toString(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/nodes/variables/AttrNode.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.nodes.variables; 2 | 3 | import lemon.jpizza.JPType; 4 | import lemon.jpizza.nodes.Node; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | public class AttrNode extends Node { 10 | public final Object value_node; 11 | 12 | public AttrNode(Object value_node) { 13 | this.value_node = value_node; 14 | jptype = JPType.Attr; 15 | } 16 | 17 | @Override 18 | public Node optimize() { 19 | return this; 20 | } 21 | 22 | @Override 23 | public List getChildren() { 24 | return new ArrayList<>(); 25 | } 26 | 27 | @Override 28 | public String visualize() { 29 | return "AttrNode"; 30 | } 31 | } 32 | 33 | // Jaws Approved! 34 | // Die 35 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/nodes/variables/VarAccessNode.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.nodes.variables; 2 | 3 | import lemon.jpizza.JPType; 4 | import lemon.jpizza.nodes.Node; 5 | import lemon.jpizza.Token; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | public class VarAccessNode extends Node { 11 | public final Token var_name_tok; 12 | 13 | public VarAccessNode(Token var_name_tok) { 14 | this.var_name_tok = var_name_tok; 15 | pos_start = var_name_tok.pos_start.copy(); pos_end = var_name_tok.pos_end.copy(); 16 | jptype = JPType.VarAccess; 17 | } 18 | 19 | @Override 20 | public Node optimize() { 21 | return this; 22 | } 23 | 24 | @Override 25 | public List getChildren() { 26 | return new ArrayList<>(); 27 | } 28 | 29 | @Override 30 | public String visualize() { 31 | return var_name_tok.value.toString(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/nodes/variables/VarNode.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.nodes.variables; 2 | 3 | import lemon.jpizza.JPType; 4 | import lemon.jpizza.nodes.Node; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | public class VarNode extends Node { 10 | public final Object value_node; 11 | public final boolean locked; 12 | public Integer min = null; 13 | public Integer max = null; 14 | 15 | public VarNode(Object value_node, boolean locked) { 16 | this.value_node = value_node; 17 | this.locked = locked; 18 | jptype = JPType.Var; 19 | } 20 | 21 | public VarNode setRange(Integer min, Integer max) { 22 | this.min = min; 23 | this.max = max; 24 | return this; 25 | } 26 | 27 | @Override 28 | public Node optimize() { 29 | return this; 30 | } 31 | 32 | @Override 33 | public List getChildren() { 34 | return new ArrayList<>(); 35 | } 36 | 37 | @Override 38 | public String visualize() { 39 | return "VarNode"; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /jpizza/src/main/java/lemon/jpizza/results/ParseResult.java: -------------------------------------------------------------------------------- 1 | package lemon.jpizza.results; 2 | 3 | import lemon.jpizza.errors.Error; 4 | 5 | public class ParseResult { 6 | public T node = null; 7 | public Error error = null; 8 | public int advanceCount = 0; 9 | public int toReverseCount = 0; 10 | 11 | public void registerAdvancement() { advanceCount++; } 12 | 13 | public U register(ParseResult res) { 14 | advanceCount += res.advanceCount; 15 | if (res.error != null) { 16 | error = res.error; 17 | } return res.node; 18 | } 19 | 20 | public U try_register(ParseResult res) { 21 | if (res.error != null) { 22 | error = res.error; 23 | toReverseCount += res.advanceCount; 24 | return null; 25 | } return register(res); 26 | } 27 | 28 | public ParseResult success(T node) { 29 | this.node = node; 30 | return this; 31 | } 32 | 33 | public ParseResult failure(Error error) { 34 | if (this.error == null || advanceCount == 0) { 35 | this.error = error; 36 | } return this; 37 | } 38 | 39 | 40 | } 41 | -------------------------------------------------------------------------------- /jpn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lemon-Chad/jpizza/1d0380d519decb5d8a7c0b19858dc4772a96862c/jpn.png -------------------------------------------------------------------------------- /pizzico512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lemon-Chad/jpizza/1d0380d519decb5d8a7c0b19858dc4772a96862c/pizzico512.png -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * This file was generated by the Gradle 'init' task. 3 | * 4 | * The settings file is used to specify which projects to include in your build. 5 | * 6 | * Detailed information about configuring a multi-project build in Gradle can be found 7 | * in the user manual at https://docs.gradle.org/7.2/userguide/multi_project_builds.html 8 | */ 9 | 10 | rootProject.name = 'jpizza' 11 | include('jpizza') 12 | -------------------------------------------------------------------------------- /shadow.bat: -------------------------------------------------------------------------------- 1 | gradlew assembleShadowDist --------------------------------------------------------------------------------