├── .gitignore ├── LICENSE ├── README.md ├── build.gradle └── src ├── main ├── java │ └── org │ │ └── iota │ │ └── qupla │ │ ├── CrackerJack.java │ │ ├── Helix.java │ │ ├── Qupla.java │ │ ├── TestConverter.java │ │ ├── TestFpgaClient.java │ │ ├── Tester.java │ │ ├── Trytes.java │ │ ├── abra │ │ ├── AbraModule.java │ │ ├── FpgaClient.java │ │ ├── block │ │ │ ├── AbraBlockBranch.java │ │ │ ├── AbraBlockImport.java │ │ │ ├── AbraBlockLut.java │ │ │ ├── AbraBlockSpecial.java │ │ │ ├── base │ │ │ │ └── AbraBaseBlock.java │ │ │ └── site │ │ │ │ ├── AbraSiteKnot.java │ │ │ │ ├── AbraSiteLatch.java │ │ │ │ ├── AbraSiteParam.java │ │ │ │ └── base │ │ │ │ └── AbraBaseSite.java │ │ ├── context │ │ │ ├── AbraAnalyzeContext.java │ │ │ ├── AbraConfigContext.java │ │ │ ├── AbraEvalContext.java │ │ │ ├── AbraOrderBlockContext.java │ │ │ ├── AbraPrintContext.java │ │ │ ├── AbraReadDebugInfoContext.java │ │ │ ├── AbraReadTritCodeContext.java │ │ │ ├── AbraToVerilogContext.java │ │ │ ├── AbraViewTreeContext.java │ │ │ ├── AbraWriteDebugInfoContext.java │ │ │ ├── AbraWriteTritCodeContext.java │ │ │ └── base │ │ │ │ ├── AbraBaseContext.java │ │ │ │ └── AbraTritCodeBaseContext.java │ │ └── optimizers │ │ │ ├── ConcatenationOptimizer.java │ │ │ ├── ConstantTritOptimizer.java │ │ │ ├── DuplicateSiteOptimizer.java │ │ │ ├── EmptyFunctionOptimizer.java │ │ │ ├── FpgaConfigurationOptimizer.java │ │ │ ├── LutFunctionWrapperOptimizer.java │ │ │ ├── MultiLutOptimizer.java │ │ │ ├── NullifyOptimizer.java │ │ │ ├── SingleInputMergeOptimizer.java │ │ │ ├── SlicedInputOptimizer.java │ │ │ ├── UnreferencedSiteRemover.java │ │ │ └── base │ │ │ └── BaseOptimizer.java │ │ ├── dispatcher │ │ ├── Dispatcher.java │ │ ├── Effect.java │ │ ├── Entity.java │ │ ├── Environment.java │ │ ├── Event.java │ │ └── entity │ │ │ ├── FuncEntity.java │ │ │ ├── GameOfLifeEntity.java │ │ │ ├── TangleEntity.java │ │ │ ├── ViewEntity.java │ │ │ ├── helper │ │ │ └── ViewModel.java │ │ │ └── tangle │ │ │ ├── TangleAddressListener.java │ │ │ ├── TangleInterface.java │ │ │ └── ZMQListener.java │ │ ├── exception │ │ ├── CodeException.java │ │ └── ExitException.java │ │ ├── helper │ │ ├── BaseContext.java │ │ ├── DummyStmt.java │ │ ├── Indentable.java │ │ ├── StateValue.java │ │ ├── TritConverter.java │ │ ├── TritVector.java │ │ ├── TritVectorBuffer.java │ │ └── Verilog.java │ │ └── qupla │ │ ├── context │ │ ├── QuplaAnyNullContext.java │ │ ├── QuplaEvalContext.java │ │ ├── QuplaPrintContext.java │ │ ├── QuplaRecursionContext.java │ │ ├── QuplaToAbraContext.java │ │ ├── QuplaToVerilogContext.java │ │ ├── QuplaToYAMLContext.java │ │ ├── QuplaTreeViewerContext.java │ │ └── base │ │ │ └── QuplaBaseContext.java │ │ ├── expression │ │ ├── AffectExpr.java │ │ ├── AssignExpr.java │ │ ├── ConcatExpr.java │ │ ├── CondExpr.java │ │ ├── FieldExpr.java │ │ ├── FuncExpr.java │ │ ├── JoinExpr.java │ │ ├── LutExpr.java │ │ ├── MergeExpr.java │ │ ├── NameExpr.java │ │ ├── PostfixExpr.java │ │ ├── SizeofExpr.java │ │ ├── SliceExpr.java │ │ ├── StateExpr.java │ │ ├── SubExpr.java │ │ ├── TypeExpr.java │ │ ├── ValueExpr.java │ │ ├── VectorExpr.java │ │ ├── base │ │ │ ├── BaseBinaryExpr.java │ │ │ ├── BaseExpr.java │ │ │ └── BaseSubExpr.java │ │ └── constant │ │ │ ├── ConstExpr.java │ │ │ ├── ConstFactor.java │ │ │ ├── ConstFuncExpr.java │ │ │ ├── ConstNumber.java │ │ │ ├── ConstSubExpr.java │ │ │ ├── ConstTerm.java │ │ │ └── ConstTypeName.java │ │ ├── parser │ │ ├── QuplaModule.java │ │ ├── QuplaSource.java │ │ ├── Token.java │ │ └── Tokenizer.java │ │ └── statement │ │ ├── ExecStmt.java │ │ ├── FuncStmt.java │ │ ├── ImportStmt.java │ │ ├── LutStmt.java │ │ ├── TemplateStmt.java │ │ ├── TypeStmt.java │ │ ├── UseStmt.java │ │ └── helper │ │ ├── LutEntry.java │ │ ├── TritStructDef.java │ │ └── TritVectorDef.java └── resources │ ├── Curl │ └── Curl.qpl │ ├── Examples │ ├── DispatcherTest.qpl │ ├── Factorial.qpl │ ├── Sorting.qpl │ ├── ThreeXplusOne.qpl │ ├── bin2trin.qpl │ ├── helix.qpl │ ├── primes.qpl │ └── sqrtfloor.qpl │ ├── Fibonacci │ └── Fibonacci.qpl │ ├── FpgaServer │ ├── FpgaServer.c │ ├── Layout.c │ ├── Layout.h │ ├── Qlut.c │ ├── Qlut.h │ └── soc_system.rbf │ ├── GameOfLife │ ├── Environment.qpl │ ├── GameOfLife.qpl │ └── GolHash.qpl │ ├── Qupla │ ├── Container │ │ ├── arcRadixMap.qpl │ │ ├── array.qpl │ │ ├── listMap.qpl │ │ └── radixMap.qpl │ ├── Math │ │ ├── abs.qpl │ │ ├── add.qpl │ │ ├── cmp.qpl │ │ ├── decr.qpl │ │ ├── div.qpl │ │ ├── divmod.qpl │ │ ├── even.qpl │ │ ├── float.qpl │ │ ├── fulladd.qpl │ │ ├── fullmul.qpl │ │ ├── halfadd.qpl │ │ ├── incr.qpl │ │ ├── log3.qpl │ │ ├── max.qpl │ │ ├── min.qpl │ │ ├── mod.qpl │ │ ├── mul.qpl │ │ ├── neg.qpl │ │ ├── pow3.qpl │ │ ├── sign.qpl │ │ └── sub.qpl │ ├── all.qpl │ ├── as.qpl │ ├── bool.qpl │ ├── break.qpl │ ├── equal.qpl │ ├── lshift.qpl │ ├── lshiftN.qpl │ ├── print.qpl │ ├── quorum.qpl │ ├── rshift.qpl │ ├── rshiftN.qpl │ ├── types.qpl │ └── unequal.qpl │ ├── QuplaTests │ ├── Container │ │ ├── arcRadixMap.qpl │ │ ├── array.qpl │ │ ├── listMap.qpl │ │ └── radixMap.qpl │ ├── Math │ │ ├── abs.qpl │ │ ├── add.qpl │ │ ├── cmp.qpl │ │ ├── decr.qpl │ │ ├── div.qpl │ │ ├── divmod.qpl │ │ ├── even.qpl │ │ ├── float.qpl │ │ ├── fulladd.qpl │ │ ├── fullmul.qpl │ │ ├── halfadd.qpl │ │ ├── incr.qpl │ │ ├── log3.qpl │ │ ├── max.qpl │ │ ├── min.qpl │ │ ├── mod.qpl │ │ ├── mul.qpl │ │ ├── neg.qpl │ │ ├── pow3.qpl │ │ ├── sign.qpl │ │ └── sub.qpl │ ├── all.qpl │ ├── as.qpl │ ├── equal.qpl │ ├── lshift.qpl │ ├── lshiftN.qpl │ ├── rshift.qpl │ ├── rshiftN.qpl │ ├── types.qpl │ └── unequal.qpl │ ├── Test │ ├── DispatcherTest.qpl │ ├── TestCond.qpl │ └── TestStates.qpl │ ├── Verilog │ ├── b2 │ │ ├── constMin_.vl │ │ ├── constOne_.vl │ │ ├── constZero_.vl │ │ ├── isEqual_0.vl │ │ ├── isGreater_0.vl │ │ ├── isLess_0.vl │ │ ├── isMin_0.vl │ │ ├── isNegative_0.vl │ │ ├── isOne_0.vl │ │ ├── isPositive_0.vl │ │ ├── isZero_0.vl │ │ ├── merge.vl │ │ ├── neg_0.vl │ │ ├── notEqual_0.vl │ │ ├── notGreater_0.vl │ │ ├── notLess_0.vl │ │ ├── notNegative_0.vl │ │ ├── notPositive_0.vl │ │ ├── notZero_0.vl │ │ ├── not_0.vl │ │ ├── nullifyFalse_.vl │ │ └── nullifyTrue_.vl │ └── b3 │ │ ├── constMin_.vl │ │ ├── constOne_.vl │ │ ├── constZero_.vl │ │ ├── isEqual_0.vl │ │ ├── isGreater_0.vl │ │ ├── isLess_0.vl │ │ ├── isMin_0.vl │ │ ├── isNegative_0.vl │ │ ├── isOne_0.vl │ │ ├── isPositive_0.vl │ │ ├── isZero_0.vl │ │ ├── merge.vl │ │ ├── neg_0.vl │ │ ├── notEqual_0.vl │ │ ├── notGreater_0.vl │ │ ├── notLess_0.vl │ │ ├── notNegative_0.vl │ │ ├── notPositive_0.vl │ │ ├── notZero_0.vl │ │ ├── not_0.vl │ │ ├── nullifyFalse_.vl │ │ └── nullifyTrue_.vl │ ├── syntax │ ├── Config.txt │ ├── QuplaSyntax.txt │ ├── diagram.xhtml │ ├── diagram │ │ ├── ConstFuncExpr.png │ │ ├── ConstNumber.png │ │ ├── ConstSubExpr.png │ │ ├── ConstTypeName.png │ │ ├── ExecStmt.png │ │ ├── FieldExpr.png │ │ ├── LutEntry.png │ │ ├── NameExpr.png │ │ ├── QuplaSource.png │ │ ├── SizeofExpr.png │ │ ├── SubExpr.png │ │ ├── TritStructDef.png │ │ ├── TritVectorDef.png │ │ ├── VectorExpr.png │ │ ├── affectExpr.png │ │ ├── assignExpr.png │ │ ├── bitLiteral.png │ │ ├── bool.png │ │ ├── concatExpr.png │ │ ├── condExpr.png │ │ ├── constExpr.png │ │ ├── constFactor.png │ │ ├── constTerm.png │ │ ├── entityAlias.png │ │ ├── envExpr.png │ │ ├── float.png │ │ ├── funcBody.png │ │ ├── funcExpr.png │ │ ├── funcParam.png │ │ ├── funcSignature.png │ │ ├── funcStmt.png │ │ ├── hexLiteral.png │ │ ├── importStmt.png │ │ ├── integer.png │ │ ├── joinExpr.png │ │ ├── lutExpr.png │ │ ├── lutStmt.png │ │ ├── mergeExpr.png │ │ ├── name.png │ │ ├── number.png │ │ ├── postfixExpr.png │ │ ├── quplaStmt.png │ │ ├── rr-1.58.1777.png │ │ ├── sliceExpr.png │ │ ├── stateExpr.png │ │ ├── templateBody.png │ │ ├── templateStmt.png │ │ ├── templateTypeRelation.png │ │ ├── trit.png │ │ ├── tritList.png │ │ ├── tritLiteral.png │ │ ├── tritOrBool.png │ │ ├── tryteLiteral.png │ │ ├── typeExpr.png │ │ ├── typeInstantiation.png │ │ ├── typeStmt.png │ │ └── useStmt.png │ └── index.html │ └── trytes.go └── test └── java └── org └── iota └── qupla └── qupla └── parser └── TokenTest.java /.gitignore: -------------------------------------------------------------------------------- 1 | qupla.iml 2 | qupla.ipr 3 | qupla.iws 4 | out 5 | .idea 6 | build 7 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | // copyright IOTA Foundation 2 | plugins { 3 | id 'java' 4 | id 'idea' // for 'gradle idea' to generate intellij configuration 5 | } 6 | 7 | group 'org.iota' 8 | version '0.1-SNAPSHOT' 9 | 10 | sourceCompatibility = 1.8 11 | 12 | repositories { 13 | maven { url 'https://jitpack.io' } 14 | mavenCentral() 15 | } 16 | 17 | dependencies { 18 | testCompile "junit:junit:4.12" 19 | testCompile "org.mockito:mockito-core:2.+" 20 | 21 | compile fileTree(dir: 'libs', include: ['*.jar']) 22 | // compile 'org.bytedeco.javacpp-presets:llvm-platform:6.0.1-1.4.2' 23 | compile 'com.github.iotaledger:iota-java:1.0.0-beta2' 24 | compile group: 'org.zeromq', name: 'jeromq', version: '0.4.3' 25 | // 26 | // compile group: 'junit', name: 'junit', version: '4.12' 27 | // compile group: 'pl.pragmatists', name: 'JUnitParams', version: '1.1.1' 28 | // // prevents slf4j from printing to System.err, see https://www.slf4j.org/codes.html#StaticLoggerBinder 29 | compile group: 'org.slf4j', name: 'slf4j-nop', version: '1.8.0-beta2' 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/org/iota/qupla/TestFpgaClient.java: -------------------------------------------------------------------------------- 1 | package org.iota.qupla; 2 | 3 | import org.iota.qupla.abra.FpgaClient; 4 | import org.iota.qupla.helper.TritVector; 5 | 6 | import java.nio.file.Files; 7 | import java.nio.file.Paths; 8 | 9 | public class TestFpgaClient { 10 | private FpgaClient client = new FpgaClient(); 11 | 12 | public static void main(String[] args) { 13 | TestFpgaClient caller = new TestFpgaClient(); 14 | caller.converse(); 15 | } 16 | 17 | public void converse() { 18 | try { 19 | byte[] input = Files.readAllBytes(Paths.get("add_27.qbc")); 20 | byte[] output = client.process('c', input); 21 | if (output == null) { 22 | System.out.println("Config failed"); 23 | return; 24 | } 25 | 26 | final String tritString = "111000000000000000000000000" + "1-1000000000000000000000000"; 27 | final TritVector value = new TritVector(tritString); 28 | 29 | input = value.trits(); 30 | for (int i = 0; i < input.length; i++) { 31 | input[i] = TritVector.tritToBits(input[i]); 32 | } 33 | 34 | long start = System.currentTimeMillis(); 35 | for (int i = 0; i < 1000; i++) { 36 | output = client.process('d', input); 37 | } 38 | long end = System.currentTimeMillis(); 39 | Qupla.log("" + (end - start)); 40 | 41 | if (output == null) { 42 | System.out.println("Exec failed"); 43 | return; 44 | } 45 | 46 | for (int i = 0; i < output.length; i++) { 47 | output[i] = TritVector.bitsToTrit(output[i]); 48 | } 49 | 50 | System.out.println("Result: " + new TritVector(output)); 51 | } catch (Exception e) { 52 | e.printStackTrace(); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/org/iota/qupla/abra/FpgaClient.java: -------------------------------------------------------------------------------- 1 | package org.iota.qupla.abra; 2 | 3 | import java.io.BufferedOutputStream; 4 | import java.io.IOException; 5 | import java.io.InputStream; 6 | import java.io.OutputStream; 7 | import java.net.Socket; 8 | import java.net.UnknownHostException; 9 | 10 | public class FpgaClient 11 | { 12 | private String host = "192.168.7.1"; // "192.168.1.76"; 13 | private InputStream inStream; 14 | private OutputStream outStream; 15 | private int port = 6666; 16 | private Socket socket = null; 17 | 18 | public boolean connect() 19 | { 20 | try 21 | { 22 | socket = new Socket(host, port); 23 | socket.setTcpNoDelay(true); 24 | inStream = socket.getInputStream(); 25 | outStream = new BufferedOutputStream(socket.getOutputStream()); 26 | return true; 27 | } 28 | catch (UnknownHostException e) 29 | { 30 | System.err.println("Cannot find host called: " + host); 31 | } 32 | catch (IOException e) 33 | { 34 | System.err.println("Could not establish connection for " + host); 35 | } 36 | 37 | disconnect(); 38 | return false; 39 | } 40 | 41 | public void disconnect() 42 | { 43 | try 44 | { 45 | if (inStream != null) 46 | { 47 | inStream.close(); 48 | } 49 | 50 | if (outStream != null) 51 | { 52 | outStream.close(); 53 | } 54 | 55 | if (socket != null) 56 | { 57 | socket.close(); 58 | } 59 | } 60 | catch (IOException e) 61 | { 62 | System.err.println("Error in cleanup"); 63 | } 64 | 65 | inStream = null; 66 | outStream = null; 67 | socket = null; 68 | } 69 | 70 | public byte[] process(final char command, final byte[] data) 71 | { 72 | if (socket == null && !connect()) 73 | { 74 | return null; 75 | } 76 | 77 | try 78 | { 79 | final byte[] cmdLen = new byte[3]; 80 | cmdLen[0] = (byte) command; 81 | cmdLen[1] = (byte) (data.length & 0xff); 82 | cmdLen[2] = (byte) ((data.length >> 8) & 0xff); 83 | outStream.write(cmdLen); 84 | if (data.length > 0) 85 | { 86 | outStream.write(data); 87 | } 88 | outStream.flush(); 89 | 90 | int length = inStream.read(cmdLen); 91 | if (length != 3 || cmdLen[0] != 1) 92 | { 93 | System.err.println("READ FAILED"); 94 | disconnect(); 95 | return null; 96 | } 97 | 98 | length = ((cmdLen[2] & 0xff) << 8) | (cmdLen[1] & 0xff); 99 | final byte[] output = new byte[length]; 100 | if (length > 0) 101 | { 102 | length = inStream.read(output); 103 | if (length != output.length) 104 | { 105 | System.err.println("READ FAILED"); 106 | disconnect(); 107 | return null; 108 | } 109 | } 110 | 111 | return output; 112 | } 113 | catch (Exception e) 114 | { 115 | System.err.println("process failed with host " + host); 116 | e.printStackTrace(); 117 | disconnect(); 118 | return null; 119 | } 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /src/main/java/org/iota/qupla/abra/block/AbraBlockImport.java: -------------------------------------------------------------------------------- 1 | package org.iota.qupla.abra.block; 2 | 3 | import java.util.ArrayList; 4 | 5 | import org.iota.qupla.abra.block.base.AbraBaseBlock; 6 | import org.iota.qupla.abra.context.base.AbraBaseContext; 7 | 8 | public class AbraBlockImport extends AbraBaseBlock 9 | { 10 | public ArrayList blocks = new ArrayList<>(); 11 | public String hash; 12 | 13 | @Override 14 | public void eval(final AbraBaseContext context) 15 | { 16 | context.evalImport(this); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/org/iota/qupla/abra/block/AbraBlockSpecial.java: -------------------------------------------------------------------------------- 1 | package org.iota.qupla.abra.block; 2 | 3 | 4 | import org.iota.qupla.abra.block.base.AbraBaseBlock; 5 | import org.iota.qupla.abra.context.base.AbraBaseContext; 6 | import org.iota.qupla.helper.TritVector; 7 | 8 | public class AbraBlockSpecial extends AbraBaseBlock 9 | { 10 | public static final int TYPE_CONCAT = 2; 11 | public static final int TYPE_CONST = 3; 12 | public static final int TYPE_MERGE = 0; 13 | public static final int TYPE_NULLIFY_FALSE = 5; 14 | public static final int TYPE_NULLIFY_TRUE = 4; 15 | public static final int TYPE_SLICE = 1; 16 | public static final String[] names = { 17 | "merge", 18 | "slice", 19 | "concat", 20 | "const", 21 | "nullifyTrue", 22 | "nullifyFalse" 23 | }; 24 | 25 | public TritVector constantValue; 26 | public int offset; 27 | public int size; 28 | 29 | public AbraBlockSpecial(final int type) 30 | { 31 | index = type; 32 | name = names[type]; 33 | } 34 | 35 | public AbraBlockSpecial(final int type, final int size) 36 | { 37 | this(type); 38 | 39 | this.size = size; 40 | name += "_" + size; 41 | } 42 | 43 | public AbraBlockSpecial(final int type, final int size, final int offset) 44 | { 45 | this(type, size); 46 | 47 | this.offset = offset; 48 | name += "_" + offset; 49 | } 50 | 51 | public AbraBlockSpecial(final int type, final int size, final TritVector vector) 52 | { 53 | this(type, size); 54 | 55 | if (vector.isZero()) 56 | { 57 | name = "constZero_" + size; 58 | } 59 | else 60 | { 61 | final byte[] trits = vector.trits(); 62 | int len = trits.length; 63 | while (trits[len - 1] == TritVector.TRIT_ZERO) 64 | { 65 | len--; 66 | } 67 | 68 | for (int i = 0; i < len; i++) 69 | { 70 | if (trits[i] == TritVector.TRIT_MIN) 71 | { 72 | trits[i] = 'T'; 73 | } 74 | } 75 | 76 | name += "_" + new String(trits, 0, len); 77 | } 78 | 79 | constantValue = vector; 80 | } 81 | 82 | @Override 83 | public void eval(final AbraBaseContext context) 84 | { 85 | context.evalSpecial(this); 86 | } 87 | 88 | @Override 89 | public String toString() 90 | { 91 | return name + "()"; 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/main/java/org/iota/qupla/abra/block/base/AbraBaseBlock.java: -------------------------------------------------------------------------------- 1 | package org.iota.qupla.abra.block.base; 2 | 3 | import org.iota.qupla.abra.context.base.AbraBaseContext; 4 | import org.iota.qupla.exception.CodeException; 5 | import org.iota.qupla.qupla.expression.base.BaseExpr; 6 | 7 | public abstract class AbraBaseBlock 8 | { 9 | public boolean analyzed; 10 | public int index; 11 | public String name; 12 | public BaseExpr origin; 13 | 14 | public boolean couldBeLutWrapper() 15 | { 16 | return false; 17 | } 18 | 19 | protected void error(final String text) 20 | { 21 | throw new CodeException(text); 22 | } 23 | 24 | public abstract void eval(final AbraBaseContext context); 25 | 26 | public void markReferences() 27 | { 28 | } 29 | 30 | public int size() 31 | { 32 | return 1; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/org/iota/qupla/abra/block/site/AbraSiteKnot.java: -------------------------------------------------------------------------------- 1 | package org.iota.qupla.abra.block.site; 2 | 3 | import java.util.ArrayList; 4 | 5 | import org.iota.qupla.abra.block.AbraBlockSpecial; 6 | import org.iota.qupla.abra.block.base.AbraBaseBlock; 7 | import org.iota.qupla.abra.block.site.base.AbraBaseSite; 8 | import org.iota.qupla.abra.context.base.AbraBaseContext; 9 | 10 | public class AbraSiteKnot extends AbraBaseSite 11 | { 12 | public AbraBaseBlock block; 13 | public ArrayList inputs = new ArrayList<>(); 14 | 15 | public AbraSiteKnot() 16 | { 17 | } 18 | 19 | public AbraSiteKnot(final AbraSiteKnot copy) 20 | { 21 | super(copy); 22 | block = copy.block; 23 | } 24 | 25 | @Override 26 | public AbraBaseSite clone() 27 | { 28 | return new AbraSiteKnot(this); 29 | } 30 | 31 | @Override 32 | public void eval(final AbraBaseContext context) 33 | { 34 | context.evalKnot(this); 35 | } 36 | 37 | @Override 38 | public boolean isIdentical(final AbraBaseSite rhs) 39 | { 40 | if (!super.isIdentical(rhs)) 41 | { 42 | return false; 43 | } 44 | 45 | final AbraSiteKnot knot = (AbraSiteKnot) rhs; 46 | if (block.index != knot.block.index) 47 | { 48 | return false; 49 | } 50 | 51 | if (block instanceof AbraBlockSpecial && !block.name.equals(knot.block.name)) 52 | { 53 | return false; 54 | } 55 | 56 | if (inputs.size() != knot.inputs.size()) 57 | { 58 | return false; 59 | } 60 | 61 | for (int i = 0; i < inputs.size(); i++) 62 | { 63 | if (inputs.get(i) != knot.inputs.get(i)) 64 | { 65 | return false; 66 | } 67 | } 68 | 69 | return true; 70 | } 71 | 72 | @Override 73 | public void markReferences() 74 | { 75 | super.markReferences(); 76 | 77 | for (final AbraBaseSite input : inputs) 78 | { 79 | input.references++; 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/main/java/org/iota/qupla/abra/block/site/AbraSiteLatch.java: -------------------------------------------------------------------------------- 1 | package org.iota.qupla.abra.block.site; 2 | 3 | import org.iota.qupla.abra.block.site.base.AbraBaseSite; 4 | import org.iota.qupla.abra.context.base.AbraBaseContext; 5 | 6 | public class AbraSiteLatch extends AbraBaseSite 7 | { 8 | public AbraBaseSite latchSite; 9 | 10 | public AbraSiteLatch() 11 | { 12 | } 13 | 14 | public AbraSiteLatch(final AbraSiteLatch copy) 15 | { 16 | super(copy); 17 | } 18 | 19 | @Override 20 | public AbraBaseSite clone() 21 | { 22 | return new AbraSiteLatch(this); 23 | } 24 | 25 | @Override 26 | public void eval(final AbraBaseContext context) 27 | { 28 | context.evalLatch(this); 29 | } 30 | 31 | @Override 32 | public boolean isIdentical(final AbraBaseSite rhs) 33 | { 34 | return false; 35 | } 36 | 37 | @Override 38 | public void markReferences() 39 | { 40 | super.markReferences(); 41 | 42 | if (latchSite != null) 43 | { 44 | latchSite.references++; 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/org/iota/qupla/abra/block/site/AbraSiteParam.java: -------------------------------------------------------------------------------- 1 | package org.iota.qupla.abra.block.site; 2 | 3 | import org.iota.qupla.abra.block.site.base.AbraBaseSite; 4 | import org.iota.qupla.abra.context.base.AbraBaseContext; 5 | 6 | public class AbraSiteParam extends AbraBaseSite 7 | { 8 | public int offset; 9 | 10 | public AbraSiteParam() 11 | { 12 | } 13 | 14 | public AbraSiteParam(final AbraSiteParam copy) 15 | { 16 | super(copy); 17 | offset = copy.offset; 18 | } 19 | 20 | @Override 21 | public AbraBaseSite clone() 22 | { 23 | return new AbraSiteParam(this); 24 | } 25 | 26 | @Override 27 | public void eval(final AbraBaseContext context) 28 | { 29 | context.evalParam(this); 30 | } 31 | 32 | @Override 33 | public boolean isIdentical(final AbraBaseSite rhs) 34 | { 35 | return false; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/org/iota/qupla/abra/block/site/base/AbraBaseSite.java: -------------------------------------------------------------------------------- 1 | package org.iota.qupla.abra.block.site.base; 2 | 3 | import org.iota.qupla.abra.context.AbraPrintContext; 4 | import org.iota.qupla.abra.context.base.AbraBaseContext; 5 | import org.iota.qupla.exception.CodeException; 6 | import org.iota.qupla.qupla.expression.base.BaseExpr; 7 | 8 | public abstract class AbraBaseSite 9 | { 10 | public static final AbraPrintContext printer = new AbraPrintContext(null); 11 | 12 | public int index; 13 | public String name; 14 | public BaseExpr origin; 15 | public int references; 16 | public int size; 17 | public BaseExpr stmt; 18 | 19 | protected AbraBaseSite() 20 | { 21 | } 22 | 23 | protected AbraBaseSite(final AbraBaseSite copy) 24 | { 25 | index = copy.index; 26 | size = copy.size; 27 | } 28 | 29 | public abstract AbraBaseSite clone(); 30 | 31 | protected void error(final String text) 32 | { 33 | throw new CodeException(text); 34 | } 35 | 36 | public abstract void eval(final AbraBaseContext context); 37 | 38 | public void from(final BaseExpr expr) 39 | { 40 | origin = expr; 41 | size = expr.size; 42 | } 43 | 44 | public boolean isIdentical(final AbraBaseSite rhs) 45 | { 46 | if (getClass() != rhs.getClass()) 47 | { 48 | return false; 49 | } 50 | 51 | return size == rhs.size; 52 | } 53 | 54 | public void markReferences() 55 | { 56 | } 57 | 58 | @Override 59 | public String toString() 60 | { 61 | final String oldString = printer.string; 62 | printer.string = new String(new char[0]); 63 | eval(printer); 64 | final String ret = printer.string; 65 | printer.string = oldString; 66 | return ret; 67 | } 68 | 69 | public String varName() 70 | { 71 | return name == null ? "p" + index : name; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/org/iota/qupla/abra/context/AbraOrderBlockContext.java: -------------------------------------------------------------------------------- 1 | package org.iota.qupla.abra.context; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Comparator; 5 | import java.util.TreeSet; 6 | 7 | import org.iota.qupla.abra.AbraModule; 8 | import org.iota.qupla.abra.block.AbraBlockBranch; 9 | import org.iota.qupla.abra.block.AbraBlockImport; 10 | import org.iota.qupla.abra.block.AbraBlockLut; 11 | import org.iota.qupla.abra.block.AbraBlockSpecial; 12 | import org.iota.qupla.abra.block.site.AbraSiteKnot; 13 | import org.iota.qupla.abra.block.site.AbraSiteLatch; 14 | import org.iota.qupla.abra.block.site.AbraSiteParam; 15 | import org.iota.qupla.abra.context.base.AbraTritCodeBaseContext; 16 | 17 | public class AbraOrderBlockContext extends AbraTritCodeBaseContext implements Comparator 18 | { 19 | private final TreeSet input = new TreeSet<>(this); 20 | private final ArrayList output = new ArrayList<>(); 21 | 22 | @Override 23 | public int compare(final AbraBlockBranch lhs, final AbraBlockBranch rhs) 24 | { 25 | if (lhs.size != rhs.size) 26 | { 27 | return lhs.size < rhs.size ? -1 : 1; 28 | } 29 | 30 | if (lhs.index != rhs.index) 31 | { 32 | return lhs.index < rhs.index ? -1 : 1; 33 | } 34 | 35 | return 0; 36 | } 37 | 38 | @Override 39 | public void eval(final AbraModule module) 40 | { 41 | module.numberBlocks(); 42 | 43 | input.addAll(module.branches); 44 | 45 | super.eval(module); 46 | 47 | input.clear(); 48 | 49 | module.branches = output; 50 | 51 | module.blocks.clear(); 52 | module.blocks.addAll(module.luts); 53 | module.blocks.addAll(module.branches); 54 | module.blocks.addAll(module.imports); 55 | 56 | module.numberBlocks(); 57 | } 58 | 59 | @Override 60 | public void evalBranch(final AbraBlockBranch branch) 61 | { 62 | if (!input.contains(branch)) 63 | { 64 | return; 65 | } 66 | 67 | input.remove(branch); 68 | 69 | for (final AbraSiteKnot site : branch.sites) 70 | { 71 | site.eval(this); 72 | } 73 | 74 | output.add(branch); 75 | } 76 | 77 | @Override 78 | public void evalImport(final AbraBlockImport imp) 79 | { 80 | } 81 | 82 | @Override 83 | protected void evalKnotBranch(final AbraSiteKnot knot, final AbraBlockBranch block) 84 | { 85 | evalBranch(block); 86 | } 87 | 88 | @Override 89 | public void evalLatch(final AbraSiteLatch latch) 90 | { 91 | } 92 | 93 | @Override 94 | public void evalLut(final AbraBlockLut lut) 95 | { 96 | } 97 | 98 | @Override 99 | public void evalParam(final AbraSiteParam param) 100 | { 101 | } 102 | 103 | @Override 104 | public void evalSpecial(final AbraBlockSpecial block) 105 | { 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /src/main/java/org/iota/qupla/abra/context/AbraReadDebugInfoContext.java: -------------------------------------------------------------------------------- 1 | package org.iota.qupla.abra.context; 2 | 3 | import org.iota.qupla.abra.AbraModule; 4 | import org.iota.qupla.abra.block.AbraBlockBranch; 5 | import org.iota.qupla.abra.block.AbraBlockImport; 6 | import org.iota.qupla.abra.block.AbraBlockLut; 7 | import org.iota.qupla.abra.block.AbraBlockSpecial; 8 | import org.iota.qupla.abra.block.site.AbraSiteKnot; 9 | import org.iota.qupla.abra.block.site.AbraSiteLatch; 10 | import org.iota.qupla.abra.block.site.AbraSiteParam; 11 | import org.iota.qupla.abra.block.site.base.AbraBaseSite; 12 | import org.iota.qupla.abra.context.base.AbraTritCodeBaseContext; 13 | import org.iota.qupla.helper.DummyStmt; 14 | import org.iota.qupla.qupla.expression.base.BaseExpr; 15 | 16 | public class AbraReadDebugInfoContext extends AbraTritCodeBaseContext 17 | { 18 | @Override 19 | public void eval(final AbraModule module) 20 | { 21 | evalBlocks(module.luts); 22 | evalBlocks(module.branches); 23 | evalBlocks(module.imports); 24 | } 25 | 26 | @Override 27 | public void evalBranch(final AbraBlockBranch branch) 28 | { 29 | branch.name = getString(); 30 | final String stmt = getString(); 31 | if (stmt != null) 32 | { 33 | branch.origin = new DummyStmt(stmt); 34 | } 35 | 36 | evalBranchSites(branch); 37 | branch.finalStmt = getStmt(); 38 | } 39 | 40 | @Override 41 | public void evalImport(final AbraBlockImport imp) 42 | { 43 | //TODO origin? 44 | imp.name = getString(); 45 | } 46 | 47 | @Override 48 | public void evalKnot(final AbraSiteKnot knot) 49 | { 50 | evalSite(knot); 51 | } 52 | 53 | @Override 54 | public void evalLatch(final AbraSiteLatch latch) 55 | { 56 | evalSite(latch); 57 | } 58 | 59 | @Override 60 | public void evalLut(final AbraBlockLut lut) 61 | { 62 | lut.name = getString(); 63 | if (lut.name == null) 64 | { 65 | lut.name = lut.unnamed(); 66 | } 67 | 68 | final String stmt = getString(); 69 | if (stmt != null) 70 | { 71 | lut.origin = new DummyStmt(stmt); 72 | } 73 | } 74 | 75 | @Override 76 | public void evalParam(final AbraSiteParam param) 77 | { 78 | evalSite(param); 79 | } 80 | 81 | private void evalSite(final AbraBaseSite site) 82 | { 83 | site.name = getString(); 84 | site.stmt = getStmt(); 85 | } 86 | 87 | @Override 88 | public void evalSpecial(final AbraBlockSpecial block) 89 | { 90 | } 91 | 92 | private BaseExpr getStmt() 93 | { 94 | String stmt = getString(); 95 | if (stmt == null) 96 | { 97 | return null; 98 | } 99 | 100 | final BaseExpr result = new DummyStmt(stmt); 101 | BaseExpr next = result; 102 | for (stmt = getString(); stmt != null; stmt = getString()) 103 | { 104 | next.next = new DummyStmt(stmt); 105 | next = next.next; 106 | } 107 | 108 | return result; 109 | } 110 | 111 | @Override 112 | public String toString() 113 | { 114 | return toStringRead(); 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /src/main/java/org/iota/qupla/abra/context/AbraWriteDebugInfoContext.java: -------------------------------------------------------------------------------- 1 | package org.iota.qupla.abra.context; 2 | 3 | import org.iota.qupla.abra.AbraModule; 4 | import org.iota.qupla.abra.block.AbraBlockBranch; 5 | import org.iota.qupla.abra.block.AbraBlockImport; 6 | import org.iota.qupla.abra.block.AbraBlockLut; 7 | import org.iota.qupla.abra.block.AbraBlockSpecial; 8 | import org.iota.qupla.abra.block.site.AbraSiteKnot; 9 | import org.iota.qupla.abra.block.site.AbraSiteLatch; 10 | import org.iota.qupla.abra.block.site.AbraSiteParam; 11 | import org.iota.qupla.abra.block.site.base.AbraBaseSite; 12 | import org.iota.qupla.abra.context.base.AbraTritCodeBaseContext; 13 | import org.iota.qupla.qupla.expression.AssignExpr; 14 | import org.iota.qupla.qupla.expression.base.BaseExpr; 15 | 16 | public class AbraWriteDebugInfoContext extends AbraTritCodeBaseContext 17 | { 18 | @Override 19 | public void eval(final AbraModule module) 20 | { 21 | //TODO add all types to context and write them out 22 | // (vector AND struct) name/size/isFloat? 23 | 24 | evalBlocks(module.luts); 25 | evalBlocks(module.branches); 26 | evalBlocks(module.imports); 27 | 28 | //TODO generate tritcode hash so that we can create a function 29 | // in the normal tritcode that returns that hash as a constant 30 | } 31 | 32 | @Override 33 | public void evalBranch(final AbraBlockBranch branch) 34 | { 35 | putString(branch.name); 36 | putString(branch.origin == null ? null : branch.origin.toString()); 37 | evalBranchSites(branch); 38 | putStmt(branch.finalStmt); 39 | } 40 | 41 | @Override 42 | public void evalImport(final AbraBlockImport imp) 43 | { 44 | //TODO origin? 45 | putString(imp.name); 46 | } 47 | 48 | @Override 49 | public void evalKnot(final AbraSiteKnot knot) 50 | { 51 | evalSite(knot); 52 | } 53 | 54 | @Override 55 | public void evalLatch(final AbraSiteLatch latch) 56 | { 57 | evalSite(latch); 58 | } 59 | 60 | @Override 61 | public void evalLut(final AbraBlockLut lut) 62 | { 63 | final boolean isUnnamed = lut.name.equals(lut.unnamed()); 64 | putString(isUnnamed ? null : lut.name); 65 | putString(lut.origin == null ? null : lut.origin.toString()); 66 | } 67 | 68 | @Override 69 | public void evalParam(final AbraSiteParam param) 70 | { 71 | evalSite(param); 72 | } 73 | 74 | private void evalSite(final AbraBaseSite site) 75 | { 76 | putString(site.name); 77 | putStmt(site.stmt); 78 | } 79 | 80 | @Override 81 | public void evalSpecial(final AbraBlockSpecial block) 82 | { 83 | } 84 | 85 | private void putStmt(BaseExpr stmt) 86 | { 87 | while (stmt != null) 88 | { 89 | final String prefix = stmt instanceof AssignExpr ? "" : "return "; 90 | putString(prefix + stmt); 91 | stmt = stmt.next; 92 | } 93 | 94 | putString(null); 95 | } 96 | 97 | @Override 98 | public String toString() 99 | { 100 | return toStringWrite(); 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/main/java/org/iota/qupla/abra/context/base/AbraBaseContext.java: -------------------------------------------------------------------------------- 1 | package org.iota.qupla.abra.context.base; 2 | 3 | import java.util.ArrayList; 4 | 5 | import org.iota.qupla.abra.AbraModule; 6 | import org.iota.qupla.abra.block.AbraBlockBranch; 7 | import org.iota.qupla.abra.block.AbraBlockImport; 8 | import org.iota.qupla.abra.block.AbraBlockLut; 9 | import org.iota.qupla.abra.block.AbraBlockSpecial; 10 | import org.iota.qupla.abra.block.base.AbraBaseBlock; 11 | import org.iota.qupla.abra.block.site.AbraSiteKnot; 12 | import org.iota.qupla.abra.block.site.AbraSiteLatch; 13 | import org.iota.qupla.abra.block.site.AbraSiteParam; 14 | import org.iota.qupla.exception.CodeException; 15 | import org.iota.qupla.helper.BaseContext; 16 | 17 | public abstract class AbraBaseContext extends BaseContext 18 | { 19 | protected void error(final String text) 20 | { 21 | throw new CodeException(text); 22 | } 23 | 24 | public void eval(final AbraModule module) 25 | { 26 | module.numberBlocks(); 27 | 28 | //TODO determine correct order, imports first or last? 29 | evalBlocks(module.imports); 30 | evalBlocks(module.luts); 31 | evalBlocks(module.branches); 32 | } 33 | 34 | protected void evalBlocks(final ArrayList blocks) 35 | { 36 | for (final AbraBaseBlock block : blocks) 37 | { 38 | block.eval(this); 39 | } 40 | } 41 | 42 | public abstract void evalBranch(final AbraBlockBranch branch); 43 | 44 | public abstract void evalImport(final AbraBlockImport imp); 45 | 46 | public void evalKnot(final AbraSiteKnot knot) 47 | { 48 | if (knot.block instanceof AbraBlockSpecial) 49 | { 50 | evalKnotSpecial(knot, (AbraBlockSpecial) knot.block); 51 | return; 52 | } 53 | 54 | if (knot.block instanceof AbraBlockBranch) 55 | { 56 | evalKnotBranch(knot, (AbraBlockBranch) knot.block); 57 | return; 58 | } 59 | 60 | if (knot.block instanceof AbraBlockLut) 61 | { 62 | evalKnotLut(knot, (AbraBlockLut) knot.block); 63 | return; 64 | } 65 | 66 | error("WTF?"); 67 | } 68 | 69 | protected void evalKnotBranch(final AbraSiteKnot knot, final AbraBlockBranch block) 70 | { 71 | } 72 | 73 | protected void evalKnotLut(final AbraSiteKnot knot, final AbraBlockLut block) 74 | { 75 | } 76 | 77 | protected void evalKnotSpecial(final AbraSiteKnot knot, final AbraBlockSpecial block) 78 | { 79 | } 80 | 81 | public abstract void evalLatch(final AbraSiteLatch latch); 82 | 83 | public abstract void evalLut(final AbraBlockLut lut); 84 | 85 | public abstract void evalParam(final AbraSiteParam param); 86 | 87 | public abstract void evalSpecial(final AbraBlockSpecial block); 88 | } 89 | -------------------------------------------------------------------------------- /src/main/java/org/iota/qupla/abra/optimizers/ConcatenationOptimizer.java: -------------------------------------------------------------------------------- 1 | package org.iota.qupla.abra.optimizers; 2 | 3 | import java.util.ArrayList; 4 | 5 | import org.iota.qupla.abra.AbraModule; 6 | import org.iota.qupla.abra.block.AbraBlockBranch; 7 | import org.iota.qupla.abra.block.AbraBlockSpecial; 8 | import org.iota.qupla.abra.block.site.AbraSiteKnot; 9 | import org.iota.qupla.abra.block.site.base.AbraBaseSite; 10 | import org.iota.qupla.abra.optimizers.base.BaseOptimizer; 11 | 12 | public class ConcatenationOptimizer extends BaseOptimizer 13 | { 14 | public ConcatenationOptimizer(final AbraModule module, final AbraBlockBranch branch) 15 | { 16 | super(module, branch); 17 | } 18 | 19 | private void evalInputs(final ArrayList inputs) 20 | { 21 | final ArrayList outputs = new ArrayList<>(); 22 | 23 | for (final AbraBaseSite input : inputs) 24 | { 25 | if (!(input instanceof AbraSiteKnot)) 26 | { 27 | outputs.add(input); 28 | continue; 29 | } 30 | 31 | final AbraSiteKnot knot = (AbraSiteKnot) input; 32 | if (knot.block.index != AbraBlockSpecial.TYPE_CONCAT) 33 | { 34 | outputs.add(input); 35 | continue; 36 | } 37 | 38 | knot.references--; 39 | for (final AbraBaseSite knotInput : knot.inputs) 40 | { 41 | outputs.add(knotInput); 42 | knotInput.references++; 43 | } 44 | } 45 | 46 | inputs.clear(); 47 | inputs.addAll(outputs); 48 | } 49 | 50 | @Override 51 | protected void processKnotBranch(final AbraSiteKnot knot, final AbraBlockBranch block) 52 | { 53 | //TODO this will cause AbraToVerilog to fail because 54 | // verilog code expects exact number of parameters 55 | // evalInputs(knot.inputs); 56 | } 57 | 58 | @Override 59 | protected void processOutputs() 60 | { 61 | evalInputs(branch.outputs); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/org/iota/qupla/abra/optimizers/ConstantTritOptimizer.java: -------------------------------------------------------------------------------- 1 | package org.iota.qupla.abra.optimizers; 2 | 3 | import org.iota.qupla.abra.AbraModule; 4 | import org.iota.qupla.abra.block.AbraBlockBranch; 5 | import org.iota.qupla.abra.block.AbraBlockLut; 6 | import org.iota.qupla.abra.block.AbraBlockSpecial; 7 | import org.iota.qupla.abra.block.site.AbraSiteKnot; 8 | import org.iota.qupla.abra.optimizers.base.BaseOptimizer; 9 | 10 | public class ConstantTritOptimizer extends BaseOptimizer 11 | { 12 | private final AbraBlockLut lutFalse; 13 | private final AbraBlockLut lutMin; 14 | private final AbraBlockLut lutOne; 15 | private final AbraBlockLut lutTrue; 16 | private final AbraBlockLut lutZero; 17 | 18 | public ConstantTritOptimizer(final AbraModule module, final AbraBlockBranch branch) 19 | { 20 | super(module, branch); 21 | 22 | lutZero = module.luts.get(0); 23 | lutOne = module.luts.get(1); 24 | lutMin = module.luts.get(2); 25 | lutTrue = module.luts.get(3); 26 | lutFalse = module.luts.get(4); 27 | } 28 | 29 | @Override 30 | protected void processKnotSpecial(final AbraSiteKnot knot, final AbraBlockSpecial block) 31 | { 32 | if (block.size != 1) 33 | { 34 | return; 35 | } 36 | 37 | switch (block.index) 38 | { 39 | case AbraBlockSpecial.TYPE_NULLIFY_TRUE: 40 | knot.block = lutTrue; 41 | break; 42 | 43 | case AbraBlockSpecial.TYPE_NULLIFY_FALSE: 44 | knot.block = lutFalse; 45 | break; 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/org/iota/qupla/abra/optimizers/DuplicateSiteOptimizer.java: -------------------------------------------------------------------------------- 1 | package org.iota.qupla.abra.optimizers; 2 | 3 | import org.iota.qupla.abra.AbraModule; 4 | import org.iota.qupla.abra.block.AbraBlockBranch; 5 | import org.iota.qupla.abra.block.site.AbraSiteKnot; 6 | import org.iota.qupla.abra.block.site.base.AbraBaseSite; 7 | import org.iota.qupla.abra.optimizers.base.BaseOptimizer; 8 | 9 | public class DuplicateSiteOptimizer extends BaseOptimizer 10 | { 11 | public DuplicateSiteOptimizer(final AbraModule module, final AbraBlockBranch branch) 12 | { 13 | super(module, branch); 14 | } 15 | 16 | @Override 17 | protected void processKnot(final AbraSiteKnot knot) 18 | { 19 | for (int i = index + 1; i < branch.sites.size(); i++) 20 | { 21 | final AbraBaseSite next = branch.sites.get(i); 22 | if (next.isIdentical(knot)) 23 | { 24 | replaceSite(next, knot); 25 | } 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/org/iota/qupla/abra/optimizers/EmptyFunctionOptimizer.java: -------------------------------------------------------------------------------- 1 | package org.iota.qupla.abra.optimizers; 2 | 3 | import org.iota.qupla.abra.AbraModule; 4 | import org.iota.qupla.abra.block.AbraBlockBranch; 5 | import org.iota.qupla.abra.block.site.AbraSiteKnot; 6 | import org.iota.qupla.abra.block.site.AbraSiteParam; 7 | import org.iota.qupla.abra.block.site.base.AbraBaseSite; 8 | import org.iota.qupla.abra.optimizers.base.BaseOptimizer; 9 | 10 | public class EmptyFunctionOptimizer extends BaseOptimizer 11 | { 12 | public EmptyFunctionOptimizer(final AbraModule module, final AbraBlockBranch branch) 13 | { 14 | super(module, branch); 15 | } 16 | 17 | @Override 18 | protected void processKnotBranch(final AbraSiteKnot knot, final AbraBlockBranch block) 19 | { 20 | // find and disable all function calls that do nothing 21 | 22 | // must be a function call that has a single input 23 | if (knot.inputs.size() != 1) 24 | { 25 | return; 26 | } 27 | 28 | if (block.sites.size() != 0 || block.latches.size() != 0) 29 | { 30 | // not an empty function 31 | return; 32 | } 33 | 34 | if (block.inputs.size() != 1 || block.outputs.size() != 1) 35 | { 36 | // not simply passing the input back to output 37 | return; 38 | } 39 | 40 | final AbraBaseSite knotInput = knot.inputs.get(0); 41 | 42 | final AbraSiteParam input = block.inputs.get(0); 43 | if (input.size != knotInput.size) 44 | { 45 | // some slicing going on 46 | return; 47 | } 48 | 49 | final AbraBaseSite output = block.outputs.get(0); 50 | if (output != input) 51 | { 52 | // WTF? how is this even possible? 53 | return; 54 | } 55 | 56 | if (knot.block.name != null) 57 | { 58 | if (knot.block.name.startsWith("print_") || knot.block.name.startsWith("break_")) 59 | { 60 | // keep dummy print/break functions, even though they are empty 61 | return; 62 | } 63 | } 64 | 65 | // well, looks like we have a candidate 66 | replaceSite(knot, knotInput); 67 | if (knotInput.name == null) 68 | { 69 | knotInput.name = knot.name; 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/org/iota/qupla/abra/optimizers/LutFunctionWrapperOptimizer.java: -------------------------------------------------------------------------------- 1 | package org.iota.qupla.abra.optimizers; 2 | 3 | import java.util.ArrayList; 4 | 5 | import org.iota.qupla.abra.AbraModule; 6 | import org.iota.qupla.abra.block.AbraBlockBranch; 7 | import org.iota.qupla.abra.block.AbraBlockLut; 8 | import org.iota.qupla.abra.block.site.AbraSiteKnot; 9 | import org.iota.qupla.abra.block.site.base.AbraBaseSite; 10 | import org.iota.qupla.abra.optimizers.base.BaseOptimizer; 11 | 12 | public class LutFunctionWrapperOptimizer extends BaseOptimizer 13 | { 14 | public LutFunctionWrapperOptimizer(final AbraModule module, final AbraBlockBranch branch) 15 | { 16 | super(module, branch); 17 | } 18 | 19 | @Override 20 | protected void processKnotBranch(final AbraSiteKnot knot, final AbraBlockBranch block) 21 | { 22 | // replace lut wrapper function with direct lut operation 23 | 24 | if (knot.size != 1) 25 | { 26 | // knot value must be single trit 27 | return; 28 | } 29 | 30 | // all input values must be single trit 31 | for (final AbraBaseSite input : knot.inputs) 32 | { 33 | if (input.size != 1) 34 | { 35 | return; 36 | } 37 | } 38 | 39 | // max 3 1-trit inputs, 1-trit output? 40 | if (!block.couldBeLutWrapper()) 41 | { 42 | return; 43 | } 44 | 45 | if (block.sites.size() != 1 || block.latches.size() != 0) 46 | { 47 | // too much going on to be a LUT wrapper 48 | return; 49 | } 50 | 51 | if (block.inputs.size() != knot.inputs.size() || block.outputs.size() != 1) 52 | { 53 | // not simply passing the inputs to output LUT knot 54 | return; 55 | } 56 | 57 | final AbraSiteKnot site = block.sites.get(0); 58 | if (site != block.outputs.get(0)) 59 | { 60 | // definitely not a lut lookup 61 | return; 62 | } 63 | 64 | if (!(site.block instanceof AbraBlockLut) || site.inputs.size() != block.inputs.size()) 65 | { 66 | // not a lut lookup 67 | return; 68 | } 69 | 70 | // well, looks like we have a candidate 71 | // reroute knot directly to LUT 72 | final ArrayList inputs = new ArrayList<>(); 73 | for (final AbraBaseSite input : site.inputs) 74 | { 75 | final int idx = block.inputs.indexOf(input); 76 | final AbraBaseSite knotInput = knot.inputs.get(idx); 77 | inputs.add(knotInput); 78 | knotInput.references++; 79 | } 80 | 81 | for (final AbraBaseSite input : knot.inputs) 82 | { 83 | input.references--; 84 | } 85 | 86 | knot.inputs = inputs; 87 | knot.block = site.block; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/main/java/org/iota/qupla/abra/optimizers/SingleInputMergeOptimizer.java: -------------------------------------------------------------------------------- 1 | package org.iota.qupla.abra.optimizers; 2 | 3 | import org.iota.qupla.abra.AbraModule; 4 | import org.iota.qupla.abra.block.AbraBlockBranch; 5 | import org.iota.qupla.abra.block.AbraBlockSpecial; 6 | import org.iota.qupla.abra.block.site.AbraSiteKnot; 7 | import org.iota.qupla.abra.optimizers.base.BaseOptimizer; 8 | 9 | public class SingleInputMergeOptimizer extends BaseOptimizer 10 | { 11 | public SingleInputMergeOptimizer(final AbraModule module, final AbraBlockBranch branch) 12 | { 13 | super(module, branch); 14 | } 15 | 16 | @Override 17 | protected void processKnotSpecial(final AbraSiteKnot knot, final AbraBlockSpecial block) 18 | { 19 | if (block.index == AbraBlockSpecial.TYPE_MERGE && knot.inputs.size() == 1) 20 | { 21 | // this leaves unreferenced 22 | replaceSite(knot, knot.inputs.get(0)); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/org/iota/qupla/abra/optimizers/UnreferencedSiteRemover.java: -------------------------------------------------------------------------------- 1 | package org.iota.qupla.abra.optimizers; 2 | 3 | import org.iota.qupla.abra.AbraModule; 4 | import org.iota.qupla.abra.block.AbraBlockBranch; 5 | import org.iota.qupla.abra.block.site.AbraSiteKnot; 6 | import org.iota.qupla.abra.block.site.base.AbraBaseSite; 7 | import org.iota.qupla.abra.optimizers.base.BaseOptimizer; 8 | import org.iota.qupla.qupla.expression.base.BaseExpr; 9 | 10 | public class UnreferencedSiteRemover extends BaseOptimizer 11 | { 12 | public UnreferencedSiteRemover(final AbraModule module, final AbraBlockBranch branch) 13 | { 14 | super(module, branch); 15 | reverse = true; 16 | } 17 | 18 | private void moveSiteStmtToNextSite(final BaseExpr stmt) 19 | { 20 | if (stmt == null) 21 | { 22 | return; 23 | } 24 | 25 | // find last statement in chain 26 | BaseExpr last = stmt; 27 | while (last.next != null) 28 | { 29 | last = last.next; 30 | } 31 | 32 | if (index + 1 < branch.sites.size()) 33 | { 34 | // link statement(s) to next body site 35 | final AbraBaseSite site = branch.sites.get(index + 1); 36 | last.next = site.stmt; 37 | site.stmt = stmt; 38 | return; 39 | } 40 | 41 | // link statement(s) to outputs 42 | last.next = branch.finalStmt; 43 | branch.finalStmt = stmt; 44 | } 45 | 46 | @Override 47 | protected void processKnot(final AbraSiteKnot knot) 48 | { 49 | if (knot.references != 0) 50 | { 51 | return; 52 | } 53 | 54 | updateReferenceCounts(knot); 55 | 56 | moveSiteStmtToNextSite(knot.stmt); 57 | branch.sites.remove(index); 58 | } 59 | 60 | @Override 61 | public void run() 62 | { 63 | processKnots(); 64 | } 65 | 66 | private void updateReferenceCounts(final AbraSiteKnot site) 67 | { 68 | for (final AbraBaseSite input : site.inputs) 69 | { 70 | input.references--; 71 | } 72 | 73 | site.inputs.clear(); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/org/iota/qupla/dispatcher/Dispatcher.java: -------------------------------------------------------------------------------- 1 | package org.iota.qupla.dispatcher; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | 6 | import org.iota.qupla.qupla.statement.TypeStmt; 7 | 8 | public class Dispatcher extends Thread 9 | { 10 | private static Dispatcher dispatcher; 11 | private final HashMap environments = new HashMap<>(); 12 | private boolean stopRunning; 13 | 14 | public static Dispatcher getInstance() 15 | { 16 | if (dispatcher == null) 17 | { 18 | dispatcher = new Dispatcher(); 19 | dispatcher.start(); 20 | } 21 | 22 | return dispatcher; 23 | } 24 | 25 | public void cancel() 26 | { 27 | stopRunning = true; 28 | } 29 | 30 | private void finished() 31 | { 32 | synchronized (environments) 33 | { 34 | environments.clear(); 35 | } 36 | 37 | for (final Entity entity : Entity.entities) 38 | { 39 | entity.stop(); 40 | } 41 | 42 | Entity.entities.clear(); 43 | } 44 | 45 | public Environment getEnvironment(final String name, final TypeStmt typeInfo) 46 | { 47 | // find or create the named environment 48 | synchronized (environments) 49 | { 50 | final Environment env = environments.get(name); 51 | if (env != null) 52 | { 53 | if (env.typeInfo == null) 54 | { 55 | env.typeInfo = typeInfo; 56 | } 57 | return env; 58 | } 59 | 60 | final Environment newEnv = new Environment(name, typeInfo); 61 | environments.put(newEnv.name, newEnv); 62 | return newEnv; 63 | } 64 | } 65 | 66 | public ArrayList listEnvironments() 67 | { 68 | synchronized (environments) 69 | { 70 | return new ArrayList<>(environments.keySet()); 71 | } 72 | } 73 | 74 | @Override 75 | public void run() 76 | { 77 | try 78 | { 79 | while (!stopRunning) 80 | { 81 | runQuants(); 82 | sleep(200); 83 | } 84 | 85 | dispatcher = null; 86 | finished(); 87 | } 88 | catch (InterruptedException e) 89 | { 90 | e.printStackTrace(); 91 | } 92 | } 93 | 94 | private void runQuants() 95 | { 96 | // keep running as long as there are still events in the queue 97 | while (Event.dispatchCurrentQuantEvents()) 98 | { 99 | // reset all invocation limits for the next quant 100 | synchronized (environments) 101 | { 102 | for (final Environment environment : environments.values()) 103 | { 104 | environment.resetEntityLimits(); 105 | } 106 | } 107 | } 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /src/main/java/org/iota/qupla/dispatcher/Effect.java: -------------------------------------------------------------------------------- 1 | package org.iota.qupla.dispatcher; 2 | 3 | import org.iota.qupla.helper.TritVector; 4 | 5 | public class Effect 6 | { 7 | public int delay; 8 | public Environment environment; 9 | 10 | public Effect(final Environment environment, final int delay) 11 | { 12 | this.environment = environment; 13 | this.delay = delay; 14 | } 15 | 16 | public void queueEnvironmentEvents(final TritVector value) 17 | { 18 | // transform the effect into one or more entity events in the event queue 19 | environment.affect(value, delay); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/org/iota/qupla/dispatcher/Entity.java: -------------------------------------------------------------------------------- 1 | package org.iota.qupla.dispatcher; 2 | 3 | import java.util.ArrayList; 4 | 5 | import org.iota.qupla.exception.CodeException; 6 | import org.iota.qupla.helper.TritVector; 7 | 8 | public abstract class Entity 9 | { 10 | public static final ArrayList entities = new ArrayList<>(); 11 | 12 | public final ArrayList effects = new ArrayList<>(); 13 | public String id; 14 | public int invoked; 15 | public int limit; 16 | 17 | public Entity(final int limit) 18 | { 19 | this.limit = limit; 20 | entities.add(this); 21 | } 22 | 23 | public static void start(final String entityName) 24 | { 25 | try 26 | { 27 | final Class entityClass = Class.forName(entityName); 28 | entityClass.newInstance(); 29 | } 30 | catch (final Exception e) 31 | { 32 | throw new CodeException("Cannot instantiate entity class name: " + entityName); 33 | } 34 | } 35 | 36 | public void affect(final Environment env, final int delay) 37 | { 38 | final Effect effect = new Effect(env, delay); 39 | 40 | //TODO insert ordered by env id to be deterministic 41 | effects.add(effect); 42 | } 43 | 44 | public void join(final Environment env) 45 | { 46 | env.join(this); 47 | } 48 | 49 | public abstract TritVector onEffect(final TritVector effect); 50 | 51 | public void processEffect(final TritVector effect) 52 | { 53 | // have the entity process the value 54 | final TritVector returnValue = onEffect(effect); 55 | if (returnValue == null || returnValue.isNull()) 56 | { 57 | // propagation stops if null is returned (no data flow) 58 | return; 59 | } 60 | 61 | // queue any effects that the entity triggered 62 | queueEffectEvents(returnValue); 63 | } 64 | 65 | public void queueEffectEvents(final TritVector value) 66 | { 67 | // all effects for this entity have been predetermined already 68 | // from the metadata, so we just need to queue them as events 69 | for (final Effect effect : effects) 70 | { 71 | effect.queueEnvironmentEvents(value); 72 | } 73 | } 74 | 75 | public void queueEvent(final TritVector value, final int delay) 76 | { 77 | // queue an event for this entity with proper delay 78 | final Event event = new Event(this, value, delay); 79 | if (delay == 0 && invoked < limit) 80 | { 81 | // can do another invocation during the current quant 82 | invoked++; 83 | } 84 | else 85 | { 86 | // invocation limit exceeded, schedule for next quant 87 | event.quant++; 88 | } 89 | } 90 | 91 | public void resetLimit() 92 | { 93 | invoked = 0; 94 | } 95 | 96 | public void stop() 97 | { 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/main/java/org/iota/qupla/dispatcher/Environment.java: -------------------------------------------------------------------------------- 1 | package org.iota.qupla.dispatcher; 2 | 3 | import java.util.ArrayList; 4 | 5 | import org.iota.qupla.helper.TritVector; 6 | import org.iota.qupla.qupla.statement.TypeStmt; 7 | 8 | public class Environment 9 | { 10 | private final ArrayList entities = new ArrayList<>(); 11 | public String id; 12 | public String name; 13 | public TypeStmt typeInfo; 14 | 15 | public Environment(final String name, final TypeStmt typeInfo) 16 | { 17 | this.name = name; 18 | this.typeInfo = typeInfo; 19 | } 20 | 21 | public void affect(final TritVector value, final int delay) 22 | { 23 | synchronized (entities) 24 | { 25 | // create properly delayed events for all entities in this environment 26 | for (final Entity entity : entities) 27 | { 28 | entity.queueEvent(value, delay); 29 | } 30 | } 31 | } 32 | 33 | public void join(final Entity entity) 34 | { 35 | //TODO insert ordered by entity id to be deterministic 36 | synchronized (entities) 37 | { 38 | entities.add(entity); 39 | } 40 | } 41 | 42 | public void resetEntityLimits() 43 | { 44 | synchronized (entities) 45 | { 46 | for (final Entity entity : entities) 47 | { 48 | entity.resetLimit(); 49 | } 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/org/iota/qupla/dispatcher/Event.java: -------------------------------------------------------------------------------- 1 | package org.iota.qupla.dispatcher; 2 | 3 | import java.util.ArrayList; 4 | 5 | import org.iota.qupla.helper.TritVector; 6 | 7 | public class Event 8 | { 9 | public static int currentQuant; 10 | private static final ArrayList queue = new ArrayList<>(); 11 | 12 | public Entity entity; 13 | public int quant; 14 | public TritVector value; 15 | 16 | public Event(final Entity entity, final TritVector value, final int delay) 17 | { 18 | this.entity = entity; 19 | this.value = value; 20 | this.quant = currentQuant + delay; 21 | synchronized (queue) 22 | { 23 | queue.add(this); 24 | } 25 | } 26 | 27 | public static boolean dispatchCurrentQuantEvents() 28 | { 29 | if (queue.size() == 0) 30 | { 31 | return false; 32 | } 33 | 34 | // process every event in the queue that is meant to run in the current quant 35 | // we may optimize this in the future by ordering the queue by quant number 36 | int i = 0; 37 | while (i < queue.size()) 38 | { 39 | final Event event = queue.get(i); 40 | if (event.quant <= currentQuant) 41 | { 42 | synchronized (queue) 43 | { 44 | queue.remove(i); 45 | } 46 | 47 | event.dispatch(); 48 | continue; 49 | } 50 | 51 | i++; 52 | } 53 | 54 | currentQuant++; 55 | return true; 56 | } 57 | 58 | public void dispatch() 59 | { 60 | entity.processEffect(value); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/org/iota/qupla/dispatcher/entity/helper/ViewModel.java: -------------------------------------------------------------------------------- 1 | package org.iota.qupla.dispatcher.entity.helper; 2 | 3 | import java.util.ArrayList; 4 | 5 | import javax.swing.table.AbstractTableModel; 6 | import org.iota.qupla.helper.TritVector; 7 | import org.iota.qupla.qupla.expression.base.BaseExpr; 8 | import org.iota.qupla.qupla.statement.TypeStmt; 9 | 10 | public class ViewModel extends AbstractTableModel 11 | { 12 | public int columns; 13 | public boolean edit; 14 | public TypeStmt typeInfo; 15 | public final ArrayList vectors = new ArrayList<>(); 16 | 17 | public ViewModel(final TypeStmt typeInfo) 18 | { 19 | this.typeInfo = typeInfo; 20 | columns = typeInfo.struct != null ? typeInfo.struct.fields.size() + 1 : 2; 21 | } 22 | 23 | // @Override 24 | // public Class getColumnClass(final int col) 25 | // { 26 | // return col == columns - 1 ? String.class : Number.class; 27 | // } 28 | 29 | @Override 30 | public int getColumnCount() 31 | { 32 | return columns; 33 | } 34 | 35 | @Override 36 | public String getColumnName(final int col) 37 | { 38 | if (col == columns - 1) 39 | { 40 | return "Effect trit vector"; 41 | } 42 | 43 | if (typeInfo.struct == null) 44 | { 45 | return "value"; 46 | } 47 | 48 | return typeInfo.struct.fields.get(col).name; 49 | } 50 | 51 | @Override 52 | public int getRowCount() 53 | { 54 | return vectors.size(); 55 | } 56 | 57 | @Override 58 | public Object getValueAt(final int row, final int col) 59 | { 60 | final TritVector vector = vectors.get(row); 61 | 62 | if (col == columns - 1) 63 | { 64 | return new String(vector.trits()); 65 | } 66 | 67 | if (typeInfo.isFloat || typeInfo.struct == null) 68 | { 69 | return typeInfo.toString(vector); 70 | } 71 | 72 | int offset = 0; 73 | for (int i = 0; i < col; i++) 74 | { 75 | offset += typeInfo.struct.fields.get(i).size; 76 | } 77 | 78 | final BaseExpr field = typeInfo.struct.fields.get(col); 79 | final TritVector slice = vector.slicePadded(offset, field.size); 80 | return slice.toDecimal(); 81 | } 82 | 83 | @Override 84 | public boolean isCellEditable(final int row, final int col) 85 | { 86 | // if editable still cannot edit trit vector field 87 | return edit && col != columns - 1; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/main/java/org/iota/qupla/dispatcher/entity/tangle/TangleAddressListener.java: -------------------------------------------------------------------------------- 1 | package org.iota.qupla.dispatcher.entity.tangle; 2 | 3 | public class TangleAddressListener extends ZMQListener 4 | { 5 | private static final int TIMEOUT_TOLERANCE = 60000; 6 | 7 | public TangleAddressListener(String zmqAddress) 8 | { 9 | super(zmqAddress, TIMEOUT_TOLERANCE); 10 | } 11 | 12 | public static void main(String[] args) 13 | { 14 | TangleAddressListener listener = new TangleAddressListener("tcp://nodes.devnet.iota.org:5556"); 15 | listener.subscribe("999999999999999999999999999999999999999999999999999999999999999999999999999999999"); 16 | listener.start(); 17 | } 18 | 19 | private void processTxMessage(String txAddress, String txMessage) 20 | { 21 | } 22 | 23 | @Override 24 | public void processZMQMessage(String zmqMessage) 25 | { 26 | System.out.println(zmqMessage); 27 | String[] messageFragments = zmqMessage.split(" "); 28 | String address = messageFragments[0]; 29 | String transactionHash = messageFragments[1]; 30 | String txMessage = TangleInterface.getInstance().fetchByHash(transactionHash); 31 | if (txMessage != null) 32 | { 33 | processTxMessage(address, txMessage); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/org/iota/qupla/exception/CodeException.java: -------------------------------------------------------------------------------- 1 | package org.iota.qupla.exception; 2 | 3 | import org.iota.qupla.qupla.parser.Token; 4 | 5 | public class CodeException extends RuntimeException 6 | { 7 | public Token token; 8 | 9 | public CodeException(final String message) 10 | { 11 | super(message); 12 | } 13 | 14 | public CodeException(final Token token, final String message) 15 | { 16 | super(message); 17 | this.token = token; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/org/iota/qupla/exception/ExitException.java: -------------------------------------------------------------------------------- 1 | package org.iota.qupla.exception; 2 | 3 | public class ExitException extends RuntimeException 4 | { 5 | public ExitException() 6 | { 7 | super("Exiting"); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/org/iota/qupla/helper/BaseContext.java: -------------------------------------------------------------------------------- 1 | package org.iota.qupla.helper; 2 | 3 | import java.io.BufferedWriter; 4 | import java.io.File; 5 | import java.io.FileWriter; 6 | import java.io.IOException; 7 | 8 | public abstract class BaseContext extends Indentable 9 | { 10 | protected BufferedWriter out; 11 | public String string; 12 | private FileWriter writer; 13 | 14 | @Override 15 | protected void appendify(final String text) 16 | { 17 | if (string != null) 18 | { 19 | string += text; 20 | return; 21 | } 22 | 23 | if (out != null) 24 | { 25 | fileWrite(text); 26 | } 27 | } 28 | 29 | protected void fileClose() 30 | { 31 | try 32 | { 33 | if (out != null) 34 | { 35 | out.close(); 36 | out = null; 37 | } 38 | 39 | if (writer != null) 40 | { 41 | writer.close(); 42 | writer = null; 43 | } 44 | } 45 | catch (IOException e) 46 | { 47 | e.printStackTrace(); 48 | } 49 | } 50 | 51 | protected void fileOpen(final String fileName) 52 | { 53 | try 54 | { 55 | final File file = new File(fileName); 56 | writer = new FileWriter(file); 57 | out = new BufferedWriter(writer); 58 | } 59 | catch (final IOException e) 60 | { 61 | e.printStackTrace(); 62 | } 63 | } 64 | 65 | private void fileWrite(final String text) 66 | { 67 | try 68 | { 69 | out.write(text); 70 | } 71 | catch (final IOException e) 72 | { 73 | e.printStackTrace(); 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/org/iota/qupla/helper/DummyStmt.java: -------------------------------------------------------------------------------- 1 | package org.iota.qupla.helper; 2 | 3 | import org.iota.qupla.qupla.expression.base.BaseExpr; 4 | 5 | public class DummyStmt extends BaseExpr 6 | { 7 | public DummyStmt(final String text) 8 | { 9 | name = text; 10 | } 11 | 12 | @Override 13 | public void analyze() 14 | { 15 | } 16 | 17 | @Override 18 | public BaseExpr clone() 19 | { 20 | return null; 21 | } 22 | 23 | @Override 24 | public String toString() 25 | { 26 | return name; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/org/iota/qupla/helper/Indentable.java: -------------------------------------------------------------------------------- 1 | package org.iota.qupla.helper; 2 | 3 | public abstract class Indentable 4 | { 5 | private boolean mustIndent; 6 | private int spaces; 7 | 8 | public Indentable append(final String text) 9 | { 10 | if (text.length() == 0) 11 | { 12 | return this; 13 | } 14 | 15 | if (mustIndent) 16 | { 17 | mustIndent = false; 18 | for (int i = 0; i < spaces; i++) 19 | { 20 | appendify(" "); 21 | } 22 | } 23 | 24 | appendify(text); 25 | return this; 26 | } 27 | 28 | protected abstract void appendify(String text); 29 | 30 | public Indentable indent() 31 | { 32 | spaces += 2; 33 | return this; 34 | } 35 | 36 | public Indentable newline() 37 | { 38 | append("\n"); 39 | mustIndent = true; 40 | return this; 41 | } 42 | 43 | public Indentable undent() 44 | { 45 | spaces -= 2; 46 | return this; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/org/iota/qupla/helper/StateValue.java: -------------------------------------------------------------------------------- 1 | package org.iota.qupla.helper; 2 | 3 | public class StateValue 4 | { 5 | public int hash; 6 | public byte[] path; 7 | public int pathLength; 8 | public TritVector value; 9 | 10 | @Override 11 | public boolean equals(final Object o) 12 | { 13 | if (this == o) 14 | { 15 | return true; 16 | } 17 | 18 | if (o == null || getClass() != o.getClass()) 19 | { 20 | return false; 21 | } 22 | 23 | final StateValue rhs = (StateValue) o; 24 | if (pathLength != rhs.pathLength) 25 | { 26 | return false; 27 | } 28 | 29 | for (int i = 0; i < pathLength; i++) 30 | { 31 | if (path[i] != rhs.path[i]) 32 | { 33 | return false; 34 | } 35 | } 36 | 37 | return true; 38 | } 39 | 40 | @Override 41 | public int hashCode() 42 | { 43 | if (hash == 0) 44 | { 45 | // cache hash value 46 | hash = 1; 47 | for (int i = 0; i < pathLength; i++) 48 | { 49 | hash = hash * 31 + path[i]; 50 | } 51 | 52 | // make sure not to calculate again 53 | if (hash == 0) 54 | { 55 | hash = -1; 56 | } 57 | } 58 | 59 | return hash; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/org/iota/qupla/helper/TritVectorBuffer.java: -------------------------------------------------------------------------------- 1 | package org.iota.qupla.helper; 2 | 3 | public class TritVectorBuffer 4 | { 5 | private static final int INITIAL_SIZE = 27; 6 | 7 | public byte[] buffer; 8 | public int used; 9 | 10 | public TritVectorBuffer(final int size) 11 | { 12 | int newSize = INITIAL_SIZE; 13 | while (newSize < size) 14 | { 15 | newSize *= 3; 16 | } 17 | 18 | buffer = new byte[newSize]; 19 | used = size; 20 | } 21 | 22 | public void grow(final int needed) 23 | { 24 | if (buffer.length < needed) 25 | { 26 | int newSize = buffer.length * 3; 27 | while (newSize < needed) 28 | { 29 | newSize *= 3; 30 | } 31 | 32 | final byte[] newBuffer = new byte[newSize]; 33 | System.arraycopy(buffer, 0, newBuffer, 0, used); 34 | 35 | buffer = newBuffer; 36 | } 37 | } 38 | 39 | @Override 40 | public String toString() 41 | { 42 | return new String(buffer, 0, used); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/org/iota/qupla/qupla/context/base/QuplaBaseContext.java: -------------------------------------------------------------------------------- 1 | package org.iota.qupla.qupla.context.base; 2 | 3 | import org.iota.qupla.helper.BaseContext; 4 | import org.iota.qupla.qupla.expression.AssignExpr; 5 | import org.iota.qupla.qupla.expression.ConcatExpr; 6 | import org.iota.qupla.qupla.expression.CondExpr; 7 | import org.iota.qupla.qupla.expression.FuncExpr; 8 | import org.iota.qupla.qupla.expression.LutExpr; 9 | import org.iota.qupla.qupla.expression.MergeExpr; 10 | import org.iota.qupla.qupla.expression.SliceExpr; 11 | import org.iota.qupla.qupla.expression.StateExpr; 12 | import org.iota.qupla.qupla.expression.TypeExpr; 13 | import org.iota.qupla.qupla.expression.VectorExpr; 14 | import org.iota.qupla.qupla.expression.base.BaseExpr; 15 | import org.iota.qupla.qupla.expression.base.BaseSubExpr; 16 | import org.iota.qupla.qupla.parser.QuplaModule; 17 | import org.iota.qupla.qupla.statement.FuncStmt; 18 | import org.iota.qupla.qupla.statement.LutStmt; 19 | import org.iota.qupla.qupla.statement.TypeStmt; 20 | 21 | public abstract class QuplaBaseContext extends BaseContext 22 | { 23 | public QuplaBaseContext append(final String text) 24 | { 25 | return (QuplaBaseContext) super.append(text); 26 | } 27 | 28 | public void eval(final QuplaModule module) 29 | { 30 | for (final LutStmt lut : module.luts) 31 | { 32 | evalLutDefinition(lut); 33 | } 34 | 35 | for (final FuncStmt func : module.funcs) 36 | { 37 | evalFuncSignature(func); 38 | } 39 | 40 | for (final FuncStmt func : module.funcs) 41 | { 42 | evalFuncBody(func); 43 | } 44 | } 45 | 46 | public abstract void evalAssign(AssignExpr assign); 47 | 48 | public void evalBaseExpr(final BaseExpr expr) 49 | { 50 | expr.error("Cannot call eval: " + expr.toString()); 51 | } 52 | 53 | public abstract void evalConcat(ConcatExpr concat); 54 | 55 | public abstract void evalConditional(CondExpr conditional); 56 | 57 | public abstract void evalFuncBody(FuncStmt func); 58 | 59 | public abstract void evalFuncCall(FuncExpr call); 60 | 61 | public abstract void evalFuncSignature(FuncStmt func); 62 | 63 | public abstract void evalLutDefinition(LutStmt lut); 64 | 65 | public abstract void evalLutLookup(LutExpr lookup); 66 | 67 | public abstract void evalMerge(MergeExpr merge); 68 | 69 | public abstract void evalSlice(SliceExpr slice); 70 | 71 | public abstract void evalState(StateExpr state); 72 | 73 | public void evalSubExpr(final BaseSubExpr sub) 74 | { 75 | sub.expr.eval(this); 76 | } 77 | 78 | public abstract void evalType(TypeExpr type); 79 | 80 | public void evalTypeDefinition(final TypeStmt type) 81 | { 82 | evalBaseExpr(type); 83 | } 84 | 85 | public abstract void evalVector(VectorExpr vector); 86 | } 87 | -------------------------------------------------------------------------------- /src/main/java/org/iota/qupla/qupla/expression/AffectExpr.java: -------------------------------------------------------------------------------- 1 | package org.iota.qupla.qupla.expression; 2 | 3 | import org.iota.qupla.qupla.expression.base.BaseExpr; 4 | import org.iota.qupla.qupla.expression.constant.ConstNumber; 5 | import org.iota.qupla.qupla.parser.Token; 6 | import org.iota.qupla.qupla.parser.Tokenizer; 7 | 8 | public class AffectExpr extends BaseExpr 9 | { 10 | public BaseExpr delay; 11 | 12 | private AffectExpr(final AffectExpr copy) 13 | { 14 | super(copy); 15 | 16 | delay = clone(copy.delay); 17 | } 18 | 19 | public AffectExpr(final Tokenizer tokenizer) 20 | { 21 | super(tokenizer); 22 | 23 | expect(tokenizer, Token.TOK_AFFECT, "affect"); 24 | 25 | final Token varName = expect(tokenizer, Token.TOK_NAME, "environment name"); 26 | name = varName.text; 27 | 28 | if (tokenizer.tokenId() == Token.TOK_DELAY) 29 | { 30 | tokenizer.nextToken(); 31 | delay = new ConstNumber(tokenizer); 32 | } 33 | } 34 | 35 | @Override 36 | public void analyze() 37 | { 38 | if (delay != null) 39 | { 40 | delay.analyze(); 41 | } 42 | } 43 | 44 | @Override 45 | public BaseExpr clone() 46 | { 47 | return new AffectExpr(this); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/org/iota/qupla/qupla/expression/AssignExpr.java: -------------------------------------------------------------------------------- 1 | package org.iota.qupla.qupla.expression; 2 | 3 | import org.iota.qupla.qupla.context.base.QuplaBaseContext; 4 | import org.iota.qupla.qupla.expression.base.BaseExpr; 5 | import org.iota.qupla.qupla.parser.Token; 6 | import org.iota.qupla.qupla.parser.Tokenizer; 7 | 8 | public class AssignExpr extends BaseExpr 9 | { 10 | public BaseExpr expr; 11 | public int stateIndex; 12 | 13 | private AssignExpr(final AssignExpr copy) 14 | { 15 | super(copy); 16 | 17 | expr = clone(copy.expr); 18 | stateIndex = copy.stateIndex; 19 | } 20 | 21 | public AssignExpr(final Tokenizer tokenizer) 22 | { 23 | super(tokenizer); 24 | 25 | final Token varName = expect(tokenizer, Token.TOK_NAME, "variable name"); 26 | name = varName.text; 27 | 28 | for (int i = scope.size() - 1; i >= 0; i--) 29 | { 30 | final BaseExpr var = scope.get(i); 31 | if (var.name.equals(name)) 32 | { 33 | if (var instanceof StateExpr) 34 | { 35 | stateIndex = i; 36 | break; 37 | } 38 | 39 | error("Duplicate variable name: " + name); 40 | } 41 | } 42 | 43 | expect(tokenizer, Token.TOK_EQUAL, "'='"); 44 | 45 | expr = new CondExpr(tokenizer).optimize(); 46 | stackIndex = scope.size(); 47 | scope.add(this); 48 | } 49 | 50 | @Override 51 | public void analyze() 52 | { 53 | constTypeInfo = null; 54 | if (stateIndex != 0) 55 | { 56 | final BaseExpr stateVar = scope.get(stateIndex); 57 | constTypeInfo = stateVar.typeInfo; 58 | } 59 | 60 | expr.analyze(); 61 | if (size != 0 && size != expr.size) 62 | { 63 | expr.error("Expression size mismatch"); 64 | } 65 | 66 | size = expr.size; 67 | typeInfo = expr.typeInfo; 68 | 69 | if (stateIndex != 0) 70 | { 71 | final BaseExpr stateVar = scope.get(stateIndex); 72 | if (stateVar.size != size) 73 | { 74 | expr.error("State variable size mismatch"); 75 | } 76 | } 77 | 78 | scope.add(this); 79 | } 80 | 81 | @Override 82 | public BaseExpr clone() 83 | { 84 | return new AssignExpr(this); 85 | } 86 | 87 | @Override 88 | public void eval(final QuplaBaseContext context) 89 | { 90 | context.evalAssign(this); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/main/java/org/iota/qupla/qupla/expression/ConcatExpr.java: -------------------------------------------------------------------------------- 1 | package org.iota.qupla.qupla.expression; 2 | 3 | import org.iota.qupla.qupla.context.base.QuplaBaseContext; 4 | import org.iota.qupla.qupla.expression.base.BaseBinaryExpr; 5 | import org.iota.qupla.qupla.expression.base.BaseExpr; 6 | import org.iota.qupla.qupla.parser.Token; 7 | import org.iota.qupla.qupla.parser.Tokenizer; 8 | 9 | public class ConcatExpr extends BaseBinaryExpr 10 | { 11 | private ConcatExpr(final ConcatExpr copy) 12 | { 13 | super(copy); 14 | } 15 | 16 | public ConcatExpr(final Tokenizer tokenizer) 17 | { 18 | super(tokenizer); 19 | 20 | BaseExpr leaf = new PostfixExpr(tokenizer).optimize(); 21 | while (tokenizer.tokenId() == Token.TOK_CONCAT) 22 | { 23 | final ConcatExpr branch = new ConcatExpr(this); 24 | leaf = connectBranch(tokenizer, leaf, branch); 25 | branch.rhs = new PostfixExpr(tokenizer).optimize(); 26 | } 27 | 28 | lhs = leaf; 29 | } 30 | 31 | @Override 32 | public void analyze() 33 | { 34 | if (rhs != null) 35 | { 36 | constTypeInfo = null; 37 | } 38 | 39 | lhs.analyze(); 40 | size = lhs.size; 41 | 42 | if (rhs != null) 43 | { 44 | rhs.analyze(); 45 | size += rhs.size; 46 | } 47 | } 48 | 49 | @Override 50 | public BaseExpr clone() 51 | { 52 | return new ConcatExpr(this); 53 | } 54 | 55 | @Override 56 | public void eval(final QuplaBaseContext context) 57 | { 58 | context.evalConcat(this); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/org/iota/qupla/qupla/expression/CondExpr.java: -------------------------------------------------------------------------------- 1 | package org.iota.qupla.qupla.expression; 2 | 3 | import org.iota.qupla.qupla.context.base.QuplaBaseContext; 4 | import org.iota.qupla.qupla.expression.base.BaseExpr; 5 | import org.iota.qupla.qupla.parser.Token; 6 | import org.iota.qupla.qupla.parser.Tokenizer; 7 | import org.iota.qupla.qupla.statement.TypeStmt; 8 | 9 | public class CondExpr extends BaseExpr 10 | { 11 | public BaseExpr condition; 12 | public BaseExpr falseBranch; 13 | public BaseExpr trueBranch; 14 | 15 | private CondExpr(final CondExpr copy) 16 | { 17 | super(copy); 18 | 19 | condition = clone(copy.condition); 20 | trueBranch = clone(copy.trueBranch); 21 | falseBranch = clone(copy.falseBranch); 22 | } 23 | 24 | public CondExpr(final Tokenizer tokenizer) 25 | { 26 | super(tokenizer); 27 | 28 | condition = new MergeExpr(tokenizer).optimize(); 29 | 30 | if (tokenizer.tokenId() == Token.TOK_QUESTION) 31 | { 32 | tokenizer.nextToken(); 33 | 34 | trueBranch = new MergeExpr(tokenizer).optimize(); 35 | 36 | expect(tokenizer, Token.TOK_COLON, "':'"); 37 | 38 | if (tokenizer.tokenId() == Token.TOK_NULL) 39 | { 40 | tokenizer.nextToken(); 41 | return; 42 | } 43 | 44 | falseBranch = new CondExpr(tokenizer).optimize(); 45 | } 46 | } 47 | 48 | @Override 49 | public void analyze() 50 | { 51 | if (trueBranch == null) 52 | { 53 | // should have been optimized away 54 | condition.analyze(); 55 | size = condition.size; 56 | typeInfo = condition.typeInfo; 57 | return; 58 | } 59 | 60 | final TypeStmt saved = constTypeInfo; 61 | constTypeInfo = null; 62 | condition.analyze(); 63 | 64 | if (condition.size != 1) 65 | { 66 | condition.error("Condition should be single trit"); 67 | } 68 | 69 | constTypeInfo = saved; 70 | trueBranch.analyze(); 71 | 72 | if (falseBranch != null) 73 | { 74 | constTypeInfo = saved; 75 | falseBranch.analyze(); 76 | 77 | if (trueBranch.size != falseBranch.size) 78 | { 79 | falseBranch.error("Conditional branches size mismatch"); 80 | } 81 | } 82 | 83 | size = trueBranch.size; 84 | typeInfo = trueBranch.typeInfo; 85 | } 86 | 87 | @Override 88 | public BaseExpr clone() 89 | { 90 | return new CondExpr(this); 91 | } 92 | 93 | @Override 94 | public void eval(final QuplaBaseContext context) 95 | { 96 | context.evalConditional(this); 97 | } 98 | 99 | @Override 100 | public BaseExpr optimize() 101 | { 102 | if (trueBranch == null) 103 | { 104 | return condition; 105 | } 106 | 107 | return super.optimize(); 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /src/main/java/org/iota/qupla/qupla/expression/FieldExpr.java: -------------------------------------------------------------------------------- 1 | package org.iota.qupla.qupla.expression; 2 | 3 | import org.iota.qupla.qupla.expression.base.BaseExpr; 4 | import org.iota.qupla.qupla.expression.base.BaseSubExpr; 5 | import org.iota.qupla.qupla.parser.Token; 6 | import org.iota.qupla.qupla.parser.Tokenizer; 7 | 8 | public class FieldExpr extends BaseSubExpr 9 | { 10 | private FieldExpr(final FieldExpr copy) 11 | { 12 | super(copy); 13 | } 14 | 15 | public FieldExpr(final Tokenizer tokenizer) 16 | { 17 | super(tokenizer); 18 | 19 | final Token fieldName = expect(tokenizer, Token.TOK_NAME, "field name"); 20 | name = fieldName.text; 21 | 22 | expect(tokenizer, Token.TOK_EQUAL, "'='"); 23 | 24 | expr = new CondExpr(tokenizer).optimize(); 25 | } 26 | 27 | @Override 28 | public BaseExpr clone() 29 | { 30 | return new FieldExpr(this); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/org/iota/qupla/qupla/expression/JoinExpr.java: -------------------------------------------------------------------------------- 1 | package org.iota.qupla.qupla.expression; 2 | 3 | import org.iota.qupla.qupla.expression.base.BaseExpr; 4 | import org.iota.qupla.qupla.expression.constant.ConstNumber; 5 | import org.iota.qupla.qupla.parser.Token; 6 | import org.iota.qupla.qupla.parser.Tokenizer; 7 | 8 | public class JoinExpr extends BaseExpr 9 | { 10 | public BaseExpr limit; 11 | 12 | private JoinExpr(final JoinExpr copy) 13 | { 14 | super(copy); 15 | 16 | limit = clone(copy.limit); 17 | } 18 | 19 | public JoinExpr(final Tokenizer tokenizer) 20 | { 21 | super(tokenizer); 22 | 23 | expect(tokenizer, Token.TOK_JOIN, "join"); 24 | 25 | final Token varName = expect(tokenizer, Token.TOK_NAME, "environment name"); 26 | name = varName.text; 27 | 28 | if (tokenizer.tokenId() == Token.TOK_LIMIT) 29 | { 30 | tokenizer.nextToken(); 31 | limit = new ConstNumber(tokenizer); 32 | } 33 | } 34 | 35 | @Override 36 | public void analyze() 37 | { 38 | if (limit != null) 39 | { 40 | limit.analyze(); 41 | } 42 | } 43 | 44 | @Override 45 | public BaseExpr clone() 46 | { 47 | return new JoinExpr(this); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/org/iota/qupla/qupla/expression/LutExpr.java: -------------------------------------------------------------------------------- 1 | package org.iota.qupla.qupla.expression; 2 | 3 | import java.util.ArrayList; 4 | 5 | import org.iota.qupla.qupla.context.base.QuplaBaseContext; 6 | import org.iota.qupla.qupla.expression.base.BaseExpr; 7 | import org.iota.qupla.qupla.parser.Token; 8 | import org.iota.qupla.qupla.parser.Tokenizer; 9 | import org.iota.qupla.qupla.statement.LutStmt; 10 | 11 | public class LutExpr extends BaseExpr 12 | { 13 | public final ArrayList args = new ArrayList<>(); 14 | public LutStmt lut; 15 | 16 | private LutExpr(final LutExpr copy) 17 | { 18 | super(copy); 19 | 20 | cloneArray(args, copy.args); 21 | lut = copy.lut; 22 | } 23 | 24 | public LutExpr(final Tokenizer tokenizer, final Token identifier) 25 | { 26 | super(tokenizer, identifier); 27 | 28 | expect(tokenizer, Token.TOK_ARRAY_OPEN, "'['"); 29 | 30 | args.add(new MergeExpr(tokenizer).optimize()); 31 | while (tokenizer.tokenId() == Token.TOK_COMMA) 32 | { 33 | tokenizer.nextToken(); 34 | args.add(new MergeExpr(tokenizer).optimize()); 35 | } 36 | 37 | expect(tokenizer, Token.TOK_ARRAY_CLOSE, "']'"); 38 | } 39 | 40 | @Override 41 | public void analyze() 42 | { 43 | lut = (LutStmt) findEntity(LutStmt.class, "lut"); 44 | size = lut.size; 45 | 46 | if (lut.inputSize > args.size()) 47 | { 48 | error("Missing argument for LUT: " + name); 49 | } 50 | 51 | if (lut.inputSize < args.size()) 52 | { 53 | error("Extra argument to LUT: " + name); 54 | } 55 | 56 | for (final BaseExpr arg : args) 57 | { 58 | arg.analyze(); 59 | if (arg.size != 1) 60 | { 61 | arg.error("LUT argument should be a single trit"); 62 | } 63 | } 64 | } 65 | 66 | @Override 67 | public BaseExpr clone() 68 | { 69 | return new LutExpr(this); 70 | } 71 | 72 | @Override 73 | public void eval(final QuplaBaseContext context) 74 | { 75 | context.evalLutLookup(this); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/main/java/org/iota/qupla/qupla/expression/MergeExpr.java: -------------------------------------------------------------------------------- 1 | package org.iota.qupla.qupla.expression; 2 | 3 | import org.iota.qupla.qupla.context.base.QuplaBaseContext; 4 | import org.iota.qupla.qupla.expression.base.BaseBinaryExpr; 5 | import org.iota.qupla.qupla.expression.base.BaseExpr; 6 | import org.iota.qupla.qupla.parser.Token; 7 | import org.iota.qupla.qupla.parser.Tokenizer; 8 | 9 | public class MergeExpr extends BaseBinaryExpr 10 | { 11 | private MergeExpr(final MergeExpr copy) 12 | { 13 | super(copy); 14 | } 15 | 16 | public MergeExpr(final Tokenizer tokenizer) 17 | { 18 | super(tokenizer); 19 | 20 | BaseExpr leaf = new ConcatExpr(tokenizer).optimize(); 21 | while (tokenizer.tokenId() == Token.TOK_MERGE) 22 | { 23 | final MergeExpr branch = new MergeExpr(this); 24 | leaf = connectBranch(tokenizer, leaf, branch); 25 | branch.rhs = new ConcatExpr(tokenizer).optimize(); 26 | } 27 | 28 | lhs = leaf; 29 | } 30 | 31 | @Override 32 | public void analyze() 33 | { 34 | lhs.analyze(); 35 | size = lhs.size; 36 | 37 | if (rhs != null) 38 | { 39 | rhs.analyze(); 40 | if (rhs.size != size) 41 | { 42 | rhs.error("Invalid merge input size"); 43 | } 44 | } 45 | } 46 | 47 | @Override 48 | public BaseExpr clone() 49 | { 50 | return new MergeExpr(this); 51 | } 52 | 53 | @Override 54 | public void eval(final QuplaBaseContext context) 55 | { 56 | context.evalMerge(this); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/org/iota/qupla/qupla/expression/NameExpr.java: -------------------------------------------------------------------------------- 1 | package org.iota.qupla.qupla.expression; 2 | 3 | import org.iota.qupla.qupla.expression.base.BaseExpr; 4 | import org.iota.qupla.qupla.parser.Token; 5 | import org.iota.qupla.qupla.parser.Tokenizer; 6 | 7 | public class NameExpr extends BaseExpr 8 | { 9 | public BaseExpr type; 10 | 11 | private NameExpr(final NameExpr copy) 12 | { 13 | super(copy); 14 | 15 | type = clone(copy.type); 16 | } 17 | 18 | public NameExpr(final Tokenizer tokenizer, final String what) 19 | { 20 | super(tokenizer); 21 | 22 | final Token varName = expect(tokenizer, Token.TOK_NAME, what); 23 | name = varName.text; 24 | } 25 | 26 | @Override 27 | public void analyze() 28 | { 29 | if (type != null) 30 | { 31 | type.analyze(); 32 | typeInfo = type.typeInfo; 33 | size = type.size; 34 | } 35 | } 36 | 37 | @Override 38 | public BaseExpr clone() 39 | { 40 | return new NameExpr(this); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/org/iota/qupla/qupla/expression/PostfixExpr.java: -------------------------------------------------------------------------------- 1 | package org.iota.qupla.qupla.expression; 2 | 3 | import org.iota.qupla.qupla.expression.base.BaseExpr; 4 | import org.iota.qupla.qupla.expression.base.BaseSubExpr; 5 | import org.iota.qupla.qupla.parser.Token; 6 | import org.iota.qupla.qupla.parser.Tokenizer; 7 | 8 | public class PostfixExpr extends BaseSubExpr 9 | { 10 | private PostfixExpr(final PostfixExpr copy) 11 | { 12 | super(copy); 13 | } 14 | 15 | public PostfixExpr(final Tokenizer tokenizer) 16 | { 17 | super(tokenizer); 18 | 19 | switch (tokenizer.tokenId()) 20 | { 21 | case Token.TOK_FUNC_OPEN: 22 | expr = new SubExpr(tokenizer); 23 | return; 24 | 25 | case Token.TOK_LITERAL_BITS: 26 | case Token.TOK_LITERAL_FALSE: 27 | case Token.TOK_LITERAL_FLOAT: 28 | case Token.TOK_LITERAL_HEX: 29 | case Token.TOK_LITERAL_NUMBER: 30 | case Token.TOK_LITERAL_TRITS: 31 | case Token.TOK_LITERAL_TRUE: 32 | case Token.TOK_LITERAL_TRYTES: 33 | case Token.TOK_MINUS: 34 | expr = new ValueExpr(tokenizer); 35 | return; 36 | 37 | case Token.TOK_SIZEOF: 38 | expr = new SizeofExpr(tokenizer); 39 | return; 40 | } 41 | 42 | final Token varName = expect(tokenizer, Token.TOK_NAME, "variable name"); 43 | name = varName.text; 44 | 45 | // local scope variable name supersedes outer scope name 46 | for (int i = scope.size() - 1; i >= 0; i--) 47 | { 48 | final BaseExpr var = scope.get(i); 49 | if (var.name.equals(name)) 50 | { 51 | expr = new SliceExpr(tokenizer, varName); 52 | return; 53 | } 54 | } 55 | 56 | switch (tokenizer.tokenId()) 57 | { 58 | case Token.TOK_TEMPL_OPEN: 59 | case Token.TOK_FUNC_OPEN: 60 | expr = new FuncExpr(tokenizer, varName); 61 | return; 62 | 63 | case Token.TOK_ARRAY_OPEN: 64 | expr = new LutExpr(tokenizer, varName); 65 | return; 66 | 67 | case Token.TOK_GROUP_OPEN: 68 | expr = new TypeExpr(tokenizer, varName); 69 | return; 70 | } 71 | 72 | expect(tokenizer, 0, "'{', '(', '<', or '['"); 73 | } 74 | 75 | @Override 76 | public BaseExpr clone() 77 | { 78 | return new PostfixExpr(this); 79 | } 80 | 81 | @Override 82 | public BaseExpr optimize() 83 | { 84 | return expr; 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/main/java/org/iota/qupla/qupla/expression/SizeofExpr.java: -------------------------------------------------------------------------------- 1 | package org.iota.qupla.qupla.expression; 2 | 3 | import org.iota.qupla.qupla.expression.base.BaseExpr; 4 | import org.iota.qupla.qupla.expression.constant.ConstTypeName; 5 | import org.iota.qupla.qupla.parser.Token; 6 | import org.iota.qupla.qupla.parser.Tokenizer; 7 | 8 | public class SizeofExpr extends VectorExpr 9 | { 10 | public BaseExpr constTypeName; 11 | 12 | private SizeofExpr(final SizeofExpr copy) 13 | { 14 | super(copy); 15 | 16 | constTypeName = clone(copy.constTypeName); 17 | } 18 | 19 | public SizeofExpr(final Tokenizer tokenizer) 20 | { 21 | super(tokenizer); 22 | 23 | expect(tokenizer, Token.TOK_SIZEOF, "sizeof"); 24 | 25 | constTypeName = new ConstTypeName(tokenizer); 26 | } 27 | 28 | @Override 29 | public void analyze() 30 | { 31 | constTypeName.analyze(); 32 | name = "" + constTypeName.size; 33 | 34 | super.analyze(); 35 | } 36 | 37 | @Override 38 | public BaseExpr clone() 39 | { 40 | return new SizeofExpr(this); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/org/iota/qupla/qupla/expression/StateExpr.java: -------------------------------------------------------------------------------- 1 | package org.iota.qupla.qupla.expression; 2 | 3 | import org.iota.qupla.helper.TritVector; 4 | import org.iota.qupla.qupla.context.base.QuplaBaseContext; 5 | import org.iota.qupla.qupla.expression.base.BaseExpr; 6 | import org.iota.qupla.qupla.expression.constant.ConstTypeName; 7 | import org.iota.qupla.qupla.parser.Token; 8 | import org.iota.qupla.qupla.parser.Tokenizer; 9 | 10 | public class StateExpr extends BaseExpr 11 | { 12 | public BaseExpr stateType; 13 | public TritVector zero; 14 | 15 | private StateExpr(final StateExpr copy) 16 | { 17 | super(copy); 18 | 19 | stateType = clone(copy.stateType); 20 | zero = copy.zero == null ? null : new TritVector(copy.zero); 21 | } 22 | 23 | public StateExpr(final Tokenizer tokenizer) 24 | { 25 | super(tokenizer); 26 | 27 | expect(tokenizer, Token.TOK_STATE, "state"); 28 | 29 | stateType = new ConstTypeName(tokenizer); 30 | 31 | final Token varName = expect(tokenizer, Token.TOK_NAME, "variable name"); 32 | name = varName.text; 33 | 34 | for (int i = scope.size() - 1; i >= 0; i--) 35 | { 36 | final BaseExpr var = scope.get(i); 37 | if (var.name.equals(name)) 38 | { 39 | error("Duplicate variable name: " + name); 40 | } 41 | } 42 | 43 | stackIndex = scope.size(); 44 | scope.add(this); 45 | } 46 | 47 | @Override 48 | public void analyze() 49 | { 50 | stateType.analyze(); 51 | size = stateType.size; 52 | typeInfo = stateType.typeInfo; 53 | 54 | zero = new TritVector(size, TritVector.TRIT_ZERO); 55 | 56 | scope.add(this); 57 | } 58 | 59 | @Override 60 | public BaseExpr clone() 61 | { 62 | return new StateExpr(this); 63 | } 64 | 65 | @Override 66 | public void eval(final QuplaBaseContext context) 67 | { 68 | context.evalState(this); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/org/iota/qupla/qupla/expression/SubExpr.java: -------------------------------------------------------------------------------- 1 | package org.iota.qupla.qupla.expression; 2 | 3 | import org.iota.qupla.qupla.expression.base.BaseExpr; 4 | import org.iota.qupla.qupla.expression.base.BaseSubExpr; 5 | import org.iota.qupla.qupla.parser.Token; 6 | import org.iota.qupla.qupla.parser.Tokenizer; 7 | 8 | public class SubExpr extends BaseSubExpr 9 | { 10 | private SubExpr(final SubExpr copy) 11 | { 12 | super(copy); 13 | } 14 | 15 | public SubExpr(final Tokenizer tokenizer) 16 | { 17 | super(tokenizer); 18 | 19 | expect(tokenizer, Token.TOK_FUNC_OPEN, "'('"); 20 | 21 | expr = new CondExpr(tokenizer).optimize(); 22 | 23 | expect(tokenizer, Token.TOK_FUNC_CLOSE, "')'"); 24 | } 25 | 26 | @Override 27 | public BaseExpr clone() 28 | { 29 | return new SubExpr(this); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/org/iota/qupla/qupla/expression/VectorExpr.java: -------------------------------------------------------------------------------- 1 | package org.iota.qupla.qupla.expression; 2 | 3 | import org.iota.qupla.helper.TritConverter; 4 | import org.iota.qupla.helper.TritVector; 5 | import org.iota.qupla.qupla.context.base.QuplaBaseContext; 6 | import org.iota.qupla.qupla.expression.base.BaseExpr; 7 | import org.iota.qupla.qupla.parser.Tokenizer; 8 | 9 | public abstract class VectorExpr extends BaseExpr 10 | { 11 | public TritVector vector; 12 | 13 | protected VectorExpr(final VectorExpr copy) 14 | { 15 | super(copy); 16 | 17 | vector = new TritVector(copy.vector); 18 | } 19 | 20 | public VectorExpr(final Tokenizer tokenizer) 21 | { 22 | super(tokenizer); 23 | 24 | vector = new TritVector(0, TritVector.TRIT_NULL); 25 | 26 | name = ""; 27 | } 28 | 29 | @Override 30 | public void analyze() 31 | { 32 | // are we assigning to a known type? 33 | if (constTypeInfo == null) 34 | { 35 | vector = new TritVector(TritConverter.fromDecimal(name)); 36 | size = vector.size(); 37 | return; 38 | } 39 | 40 | // is this a float type? 41 | if (constTypeInfo.isFloat) 42 | { 43 | final BaseExpr mantissa = constTypeInfo.struct.fields.get(0); 44 | final BaseExpr exponent = constTypeInfo.struct.fields.get(1); 45 | vector = new TritVector(TritConverter.fromFloat(name, mantissa.size, exponent.size)); 46 | size = mantissa.size + exponent.size; 47 | return; 48 | } 49 | 50 | if (name.indexOf('.') >= 0) 51 | { 52 | error("Unexpected float constant: " + name); 53 | } 54 | 55 | vector = new TritVector(TritConverter.fromDecimal(name)); 56 | size = vector.size(); 57 | if (size > constTypeInfo.size) 58 | { 59 | error("Constant value '" + name + "' exceeds " + constTypeInfo.size + " trits"); 60 | } 61 | 62 | size = constTypeInfo.size; 63 | if (vector.size() < size) 64 | { 65 | vector = TritVector.concat(vector, new TritVector(size - vector.size(), TritVector.TRIT_ZERO)); 66 | } 67 | } 68 | 69 | @Override 70 | public void eval(final QuplaBaseContext context) 71 | { 72 | context.evalVector(this); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/org/iota/qupla/qupla/expression/base/BaseBinaryExpr.java: -------------------------------------------------------------------------------- 1 | package org.iota.qupla.qupla.expression.base; 2 | 3 | import org.iota.qupla.qupla.parser.Token; 4 | import org.iota.qupla.qupla.parser.Tokenizer; 5 | 6 | public abstract class BaseBinaryExpr extends BaseExpr 7 | { 8 | public BaseExpr lhs; 9 | public Token operator; 10 | public BaseExpr rhs; 11 | 12 | protected BaseBinaryExpr(final BaseBinaryExpr copy) 13 | { 14 | super(copy); 15 | 16 | lhs = clone(copy.lhs); 17 | operator = copy.operator; 18 | rhs = clone(copy.rhs); 19 | } 20 | 21 | protected BaseBinaryExpr(final Tokenizer tokenizer) 22 | { 23 | super(tokenizer); 24 | } 25 | 26 | protected BaseExpr connectBranch(final Tokenizer tokenizer, BaseExpr leaf, final BaseBinaryExpr branch) 27 | { 28 | branch.lhs = leaf; 29 | branch.origin = leaf.origin; 30 | 31 | branch.operator = tokenizer.currentToken(); 32 | tokenizer.nextToken(); 33 | 34 | return branch; 35 | } 36 | 37 | public BaseExpr optimize() 38 | { 39 | return rhs == null ? lhs : this; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/org/iota/qupla/qupla/expression/base/BaseSubExpr.java: -------------------------------------------------------------------------------- 1 | package org.iota.qupla.qupla.expression.base; 2 | 3 | import org.iota.qupla.qupla.context.base.QuplaBaseContext; 4 | import org.iota.qupla.qupla.parser.Tokenizer; 5 | 6 | public abstract class BaseSubExpr extends BaseExpr 7 | { 8 | public BaseExpr expr; 9 | 10 | protected BaseSubExpr(final BaseSubExpr copy) 11 | { 12 | super(copy); 13 | 14 | expr = clone(copy.expr); 15 | } 16 | 17 | protected BaseSubExpr(final Tokenizer tokenizer) 18 | { 19 | super(tokenizer); 20 | } 21 | 22 | @Override 23 | public void analyze() 24 | { 25 | expr.analyze(); 26 | size = expr.size; 27 | typeInfo = expr.typeInfo; 28 | } 29 | 30 | @Override 31 | public void eval(final QuplaBaseContext context) 32 | { 33 | context.evalSubExpr(this); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/org/iota/qupla/qupla/expression/constant/ConstExpr.java: -------------------------------------------------------------------------------- 1 | package org.iota.qupla.qupla.expression.constant; 2 | 3 | import org.iota.qupla.qupla.expression.base.BaseBinaryExpr; 4 | import org.iota.qupla.qupla.expression.base.BaseExpr; 5 | import org.iota.qupla.qupla.parser.Token; 6 | import org.iota.qupla.qupla.parser.Tokenizer; 7 | 8 | public class ConstExpr extends BaseBinaryExpr 9 | { 10 | private ConstExpr(final ConstExpr copy) 11 | { 12 | super(copy); 13 | } 14 | 15 | public ConstExpr(final Tokenizer tokenizer) 16 | { 17 | super(tokenizer); 18 | 19 | BaseExpr leaf = new ConstTerm(tokenizer).optimize(); 20 | while (tokenizer.tokenId() == Token.TOK_PLUS || tokenizer.tokenId() == Token.TOK_MINUS) 21 | { 22 | final ConstExpr branch = new ConstExpr(this); 23 | leaf = connectBranch(tokenizer, leaf, branch); 24 | branch.rhs = new ConstTerm(tokenizer).optimize(); 25 | } 26 | 27 | lhs = leaf; 28 | } 29 | 30 | @Override 31 | public void analyze() 32 | { 33 | lhs.analyze(); 34 | size = lhs.size; 35 | 36 | if (rhs != null) 37 | { 38 | rhs.analyze(); 39 | switch (operator.id) 40 | { 41 | case Token.TOK_PLUS: 42 | size += rhs.size; 43 | break; 44 | 45 | case Token.TOK_MINUS: 46 | size -= rhs.size; 47 | break; 48 | } 49 | } 50 | } 51 | 52 | @Override 53 | public BaseExpr clone() 54 | { 55 | return new ConstExpr(this); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/org/iota/qupla/qupla/expression/constant/ConstFactor.java: -------------------------------------------------------------------------------- 1 | package org.iota.qupla.qupla.expression.constant; 2 | 3 | import java.util.ArrayList; 4 | 5 | import org.iota.qupla.qupla.expression.NameExpr; 6 | import org.iota.qupla.qupla.expression.base.BaseExpr; 7 | import org.iota.qupla.qupla.expression.base.BaseSubExpr; 8 | import org.iota.qupla.qupla.parser.Token; 9 | import org.iota.qupla.qupla.parser.Tokenizer; 10 | 11 | public class ConstFactor extends BaseSubExpr 12 | { 13 | public final ArrayList fields = new ArrayList<>(); 14 | public boolean negative; 15 | 16 | private ConstFactor(final ConstFactor copy) 17 | { 18 | super(copy); 19 | 20 | fields.addAll(copy.fields); 21 | negative = copy.negative; 22 | } 23 | 24 | public ConstFactor(final Tokenizer tokenizer) 25 | { 26 | super(tokenizer); 27 | 28 | switch (tokenizer.tokenId()) 29 | { 30 | case Token.TOK_FUNC_OPEN: 31 | expr = new ConstSubExpr(tokenizer); 32 | return; 33 | 34 | case Token.TOK_MINUS: 35 | tokenizer.nextToken(); 36 | negative = !negative; 37 | expr = new ConstFactor(tokenizer); 38 | return; 39 | 40 | case Token.TOK_LITERAL_NUMBER: 41 | expr = new ConstNumber(tokenizer); 42 | return; 43 | } 44 | 45 | final Token varName = expect(tokenizer, Token.TOK_NAME, "variable name"); 46 | name = varName.text; 47 | if (tokenizer.tokenId() == Token.TOK_FUNC_OPEN || tokenizer.tokenId() == Token.TOK_TEMPL_OPEN) 48 | { 49 | expr = new ConstFuncExpr(tokenizer, varName); 50 | return; 51 | } 52 | 53 | expr = new ConstTypeName(tokenizer, varName); 54 | while (tokenizer.tokenId() == Token.TOK_DOT) 55 | { 56 | tokenizer.nextToken(); 57 | 58 | fields.add(new NameExpr(tokenizer, "field name")); 59 | } 60 | } 61 | 62 | @Override 63 | public void analyze() 64 | { 65 | expr.analyze(); 66 | typeInfo = expr.typeInfo; 67 | size = negative ? -expr.size : expr.size; 68 | 69 | String fieldPath = name; 70 | for (final BaseExpr field : fields) 71 | { 72 | if (typeInfo == null || typeInfo.struct == null) 73 | { 74 | error("Expected structured trit vector: " + fieldPath); 75 | } 76 | 77 | boolean found = false; 78 | for (final BaseExpr structField : typeInfo.struct.fields) 79 | { 80 | if (structField.name.equals(field.name)) 81 | { 82 | found = true; 83 | typeInfo = structField.typeInfo; 84 | size = structField.size; 85 | break; 86 | } 87 | } 88 | 89 | if (!found) 90 | { 91 | error("Invalid structured trit vector field name: " + field); 92 | } 93 | 94 | fieldPath += "." + field; 95 | } 96 | } 97 | 98 | @Override 99 | public BaseExpr clone() 100 | { 101 | return new ConstFactor(this); 102 | } 103 | 104 | @Override 105 | public BaseExpr optimize() 106 | { 107 | return negative || fields.size() != 0 ? this : expr; 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /src/main/java/org/iota/qupla/qupla/expression/constant/ConstFuncExpr.java: -------------------------------------------------------------------------------- 1 | package org.iota.qupla.qupla.expression.constant; 2 | 3 | import org.iota.qupla.helper.TritConverter; 4 | import org.iota.qupla.qupla.context.QuplaEvalContext; 5 | import org.iota.qupla.qupla.expression.FuncExpr; 6 | import org.iota.qupla.qupla.expression.base.BaseExpr; 7 | import org.iota.qupla.qupla.parser.Token; 8 | import org.iota.qupla.qupla.parser.Tokenizer; 9 | 10 | public class ConstFuncExpr extends FuncExpr 11 | { 12 | private ConstFuncExpr(final ConstFuncExpr copy) 13 | { 14 | super(copy); 15 | } 16 | 17 | public ConstFuncExpr(final Tokenizer tokenizer, final Token identifier) 18 | { 19 | super(tokenizer, identifier); 20 | } 21 | 22 | @Override 23 | public void analyze() 24 | { 25 | super.analyze(); 26 | 27 | if (!wasAnalyzed()) 28 | { 29 | return; 30 | } 31 | 32 | final QuplaEvalContext context = new QuplaEvalContext(); 33 | eval(context); 34 | size = TritConverter.toInt(context.value.trits()); 35 | typeInfo = null; 36 | } 37 | 38 | @Override 39 | public BaseExpr clone() 40 | { 41 | return new ConstFuncExpr(this); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/org/iota/qupla/qupla/expression/constant/ConstNumber.java: -------------------------------------------------------------------------------- 1 | package org.iota.qupla.qupla.expression.constant; 2 | 3 | import org.iota.qupla.qupla.expression.base.BaseExpr; 4 | import org.iota.qupla.qupla.parser.Token; 5 | import org.iota.qupla.qupla.parser.Tokenizer; 6 | 7 | public class ConstNumber extends BaseExpr 8 | { 9 | private ConstNumber(final ConstNumber copy) 10 | { 11 | super(copy); 12 | } 13 | 14 | public ConstNumber(final Tokenizer tokenizer) 15 | { 16 | super(tokenizer); 17 | 18 | final Token number = expect(tokenizer, Token.TOK_LITERAL_NUMBER, "number"); 19 | name = number.text; 20 | } 21 | 22 | @Override 23 | public void analyze() 24 | { 25 | size = Integer.parseInt(name); 26 | } 27 | 28 | @Override 29 | public BaseExpr clone() 30 | { 31 | return new ConstNumber(this); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/org/iota/qupla/qupla/expression/constant/ConstSubExpr.java: -------------------------------------------------------------------------------- 1 | package org.iota.qupla.qupla.expression.constant; 2 | 3 | import org.iota.qupla.qupla.expression.base.BaseExpr; 4 | import org.iota.qupla.qupla.expression.base.BaseSubExpr; 5 | import org.iota.qupla.qupla.parser.Token; 6 | import org.iota.qupla.qupla.parser.Tokenizer; 7 | 8 | public class ConstSubExpr extends BaseSubExpr 9 | { 10 | private ConstSubExpr(final ConstSubExpr copy) 11 | { 12 | super(copy); 13 | } 14 | 15 | public ConstSubExpr(final Tokenizer tokenizer) 16 | { 17 | super(tokenizer); 18 | 19 | expect(tokenizer, Token.TOK_FUNC_OPEN, "'('"); 20 | 21 | expr = new ConstExpr(tokenizer).optimize(); 22 | 23 | expect(tokenizer, Token.TOK_FUNC_CLOSE, "')'"); 24 | } 25 | 26 | @Override 27 | public BaseExpr clone() 28 | { 29 | return new ConstSubExpr(this); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/org/iota/qupla/qupla/expression/constant/ConstTerm.java: -------------------------------------------------------------------------------- 1 | package org.iota.qupla.qupla.expression.constant; 2 | 3 | import org.iota.qupla.qupla.expression.base.BaseBinaryExpr; 4 | import org.iota.qupla.qupla.expression.base.BaseExpr; 5 | import org.iota.qupla.qupla.parser.Token; 6 | import org.iota.qupla.qupla.parser.Tokenizer; 7 | 8 | public class ConstTerm extends BaseBinaryExpr 9 | { 10 | private ConstTerm(final ConstTerm copy) 11 | { 12 | super(copy); 13 | } 14 | 15 | public ConstTerm(final Tokenizer tokenizer) 16 | { 17 | super(tokenizer); 18 | 19 | BaseExpr leaf = new ConstFactor(tokenizer).optimize(); 20 | while (tokenizer.tokenId() == Token.TOK_MUL || tokenizer.tokenId() == Token.TOK_DIV || tokenizer.tokenId() == Token.TOK_MOD) 21 | { 22 | final ConstTerm branch = new ConstTerm(this); 23 | leaf = connectBranch(tokenizer, leaf, branch); 24 | branch.rhs = new ConstFactor(tokenizer).optimize(); 25 | } 26 | 27 | lhs = leaf; 28 | } 29 | 30 | @Override 31 | public void analyze() 32 | { 33 | lhs.analyze(); 34 | size = lhs.size; 35 | 36 | if (rhs != null) 37 | { 38 | rhs.analyze(); 39 | switch (operator.id) 40 | { 41 | case Token.TOK_MUL: 42 | size *= rhs.size; 43 | break; 44 | 45 | case Token.TOK_DIV: 46 | if (rhs.size == 0) 47 | { 48 | rhs.error("Divide by zero in constant expression"); 49 | } 50 | 51 | size /= rhs.size; 52 | break; 53 | 54 | case Token.TOK_MOD: 55 | if (rhs.size == 0) 56 | { 57 | rhs.error("Divide by zero in constant expression"); 58 | } 59 | 60 | size %= rhs.size; 61 | break; 62 | } 63 | } 64 | } 65 | 66 | @Override 67 | public BaseExpr clone() 68 | { 69 | return new ConstTerm(this); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/org/iota/qupla/qupla/parser/QuplaSource.java: -------------------------------------------------------------------------------- 1 | package org.iota.qupla.qupla.parser; 2 | 3 | import org.iota.qupla.qupla.expression.base.BaseExpr; 4 | import org.iota.qupla.qupla.statement.ExecStmt; 5 | import org.iota.qupla.qupla.statement.FuncStmt; 6 | import org.iota.qupla.qupla.statement.ImportStmt; 7 | import org.iota.qupla.qupla.statement.LutStmt; 8 | import org.iota.qupla.qupla.statement.TemplateStmt; 9 | import org.iota.qupla.qupla.statement.TypeStmt; 10 | import org.iota.qupla.qupla.statement.UseStmt; 11 | 12 | public class QuplaSource extends BaseExpr 13 | { 14 | public String pathName; 15 | 16 | public QuplaSource(final Tokenizer tokenizer, final String pathName) 17 | { 18 | super(tokenizer); 19 | 20 | this.pathName = pathName; 21 | module.currentSource = this; 22 | 23 | origin = tokenizer.nextToken(); 24 | 25 | while (tokenizer.tokenId() != Token.TOK_EOF) 26 | { 27 | switch (tokenizer.tokenId()) 28 | { 29 | case Token.TOK_EVAL: 30 | case Token.TOK_TEST: 31 | module.execs.add(new ExecStmt(tokenizer)); 32 | break; 33 | 34 | case Token.TOK_FUNC: 35 | module.funcs.add(new FuncStmt(tokenizer)); 36 | break; 37 | 38 | case Token.TOK_IMPORT: 39 | module.imports.add(new ImportStmt(tokenizer)); 40 | break; 41 | 42 | case Token.TOK_LUT: 43 | module.luts.add(new LutStmt(tokenizer)); 44 | break; 45 | 46 | case Token.TOK_TEMPLATE: 47 | module.templates.add(new TemplateStmt(tokenizer)); 48 | break; 49 | 50 | case Token.TOK_TYPE: 51 | module.types.add(new TypeStmt(tokenizer)); 52 | break; 53 | 54 | case Token.TOK_USE: 55 | module.uses.add(new UseStmt(tokenizer)); 56 | break; 57 | 58 | default: 59 | final Token token = tokenizer.currentToken(); 60 | error(token, "Unexpected token: '" + token.text + "'"); 61 | } 62 | } 63 | } 64 | 65 | @Override 66 | public void analyze() 67 | { 68 | } 69 | 70 | @Override 71 | public BaseExpr clone() 72 | { 73 | return null; 74 | } 75 | 76 | @Override 77 | public String toString() 78 | { 79 | return pathName; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/main/java/org/iota/qupla/qupla/statement/ExecStmt.java: -------------------------------------------------------------------------------- 1 | package org.iota.qupla.qupla.statement; 2 | 3 | import org.iota.qupla.helper.TritVector; 4 | import org.iota.qupla.qupla.expression.FuncExpr; 5 | import org.iota.qupla.qupla.expression.ValueExpr; 6 | import org.iota.qupla.qupla.expression.VectorExpr; 7 | import org.iota.qupla.qupla.expression.base.BaseExpr; 8 | import org.iota.qupla.qupla.parser.Token; 9 | import org.iota.qupla.qupla.parser.Tokenizer; 10 | 11 | public class ExecStmt extends BaseExpr 12 | { 13 | public VectorExpr expected; 14 | public BaseExpr expr; 15 | public int type; 16 | 17 | private ExecStmt(final ExecStmt copy) 18 | { 19 | super(copy); 20 | expected = copy.expected; 21 | expr = copy.expr; 22 | } 23 | 24 | public ExecStmt(final Tokenizer tokenizer) 25 | { 26 | super(tokenizer); 27 | 28 | type = tokenizer.tokenId(); 29 | tokenizer.nextToken(); 30 | 31 | if (type == Token.TOK_TEST) 32 | { 33 | expected = new ValueExpr(tokenizer); 34 | expected.expect(tokenizer, Token.TOK_EQUAL, "'='"); 35 | } 36 | 37 | final Token funcName = expect(tokenizer, Token.TOK_NAME, "func name"); 38 | expr = new FuncExpr(tokenizer, funcName); 39 | } 40 | 41 | @Override 42 | public void analyze() 43 | { 44 | // make sure we always start at call index zero, 45 | // or else state variables won't work correctly 46 | callNr = 0; 47 | 48 | expr.analyze(); 49 | typeInfo = expr.typeInfo; 50 | 51 | if (expected != null) 52 | { 53 | // make sure expected and expr are same type (integer/float) 54 | constTypeInfo = expr.typeInfo; 55 | expected.analyze(); 56 | constTypeInfo = null; 57 | } 58 | } 59 | 60 | @Override 61 | public BaseExpr clone() 62 | { 63 | return new ExecStmt(this); 64 | } 65 | 66 | public boolean succeed(final TritVector result) 67 | { 68 | if (expected.vector.equals(result)) 69 | { 70 | return true; 71 | } 72 | 73 | if (!typeInfo.isFloat || expected.vector.size() != result.size()) 74 | { 75 | return false; 76 | } 77 | 78 | // when it's a float allow least significant bit to differ 79 | int size = result.size() - 1; 80 | return expected.vector.slice(1, size).equals(result.slice(1, size)); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/main/java/org/iota/qupla/qupla/statement/ImportStmt.java: -------------------------------------------------------------------------------- 1 | package org.iota.qupla.qupla.statement; 2 | 3 | import org.iota.qupla.qupla.expression.base.BaseExpr; 4 | import org.iota.qupla.qupla.parser.QuplaModule; 5 | import org.iota.qupla.qupla.parser.Token; 6 | import org.iota.qupla.qupla.parser.Tokenizer; 7 | 8 | public class ImportStmt extends BaseExpr 9 | { 10 | public QuplaModule importModule; 11 | 12 | private ImportStmt(final ImportStmt copy) 13 | { 14 | super(copy); 15 | importModule = copy.importModule; 16 | } 17 | 18 | public ImportStmt(final Tokenizer tokenizer) 19 | { 20 | super(tokenizer); 21 | 22 | expect(tokenizer, Token.TOK_IMPORT, "import"); 23 | 24 | final Token firstPart = expect(tokenizer, Token.TOK_NAME, "module name"); 25 | name = firstPart.text; 26 | } 27 | 28 | @Override 29 | public void analyze() 30 | { 31 | importModule = QuplaModule.parse(name); 32 | size = 1; 33 | } 34 | 35 | @Override 36 | public BaseExpr clone() 37 | { 38 | return new ImportStmt(this); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/org/iota/qupla/qupla/statement/LutStmt.java: -------------------------------------------------------------------------------- 1 | package org.iota.qupla.qupla.statement; 2 | 3 | import java.util.ArrayList; 4 | 5 | import org.iota.qupla.helper.TritVector; 6 | import org.iota.qupla.qupla.expression.base.BaseExpr; 7 | import org.iota.qupla.qupla.parser.Token; 8 | import org.iota.qupla.qupla.parser.Tokenizer; 9 | import org.iota.qupla.qupla.statement.helper.LutEntry; 10 | 11 | public class LutStmt extends BaseExpr 12 | { 13 | private static final int[] tableSize = { 14 | 0, 15 | 3, 16 | 9, 17 | 27 18 | }; 19 | 20 | public final ArrayList entries = new ArrayList<>(); 21 | public int inputSize; 22 | public TritVector[] lookup; 23 | public TritVector undefined; 24 | 25 | public LutStmt(final LutStmt copy) 26 | { 27 | super(copy); 28 | 29 | entries.addAll(copy.entries); 30 | inputSize = copy.inputSize; 31 | lookup = copy.lookup; 32 | undefined = copy.undefined; 33 | } 34 | 35 | public LutStmt(final Tokenizer tokenizer) 36 | { 37 | super(tokenizer); 38 | 39 | expect(tokenizer, Token.TOK_LUT, "lut"); 40 | 41 | final Token lutName = expect(tokenizer, Token.TOK_NAME, "LUT name"); 42 | name = lutName.text; 43 | module.checkDuplicateName(module.luts, this); 44 | 45 | expect(tokenizer, Token.TOK_GROUP_OPEN, "'{'"); 46 | 47 | do 48 | { 49 | entries.add(new LutEntry(tokenizer)); 50 | } 51 | while (tokenizer.tokenId() != Token.TOK_GROUP_CLOSE); 52 | 53 | tokenizer.nextToken(); 54 | } 55 | 56 | public static int index(final TritVector value) 57 | { 58 | int index = 0; 59 | for (int i = 0; i < value.size(); i++) 60 | { 61 | index *= 3; 62 | final byte trit = value.trit(i); 63 | if (trit != TritVector.TRIT_MIN) 64 | { 65 | index += trit == TritVector.TRIT_ZERO ? 1 : 2; 66 | } 67 | } 68 | 69 | return index; 70 | } 71 | 72 | @Override 73 | public void analyze() 74 | { 75 | final LutEntry first = entries.get(0); 76 | inputSize = first.inputs.length(); 77 | size = first.outputs.length(); 78 | lookup = new TritVector[tableSize[inputSize]]; 79 | for (final LutEntry entry : entries) 80 | { 81 | entry.analyze(); 82 | if (entry.inputs.length() != inputSize) 83 | { 84 | entry.error("Expected " + inputSize + " input trits"); 85 | } 86 | 87 | if (entry.outputs.length() != size) 88 | { 89 | entry.error("Expected " + size + " output trits"); 90 | } 91 | 92 | final TritVector input = new TritVector(entry.inputs); 93 | final int lutIndex = index(input); 94 | if (lookup[lutIndex] != null) 95 | { 96 | entry.error("Duplicate input trits"); 97 | } 98 | 99 | lookup[lutIndex] = new TritVector(entry.outputs); 100 | } 101 | 102 | undefined = new TritVector(size, TritVector.TRIT_NULL); 103 | } 104 | 105 | @Override 106 | public BaseExpr clone() 107 | { 108 | return new LutStmt(this); 109 | } 110 | 111 | @Override 112 | public String toString() 113 | { 114 | return "lut " + name; 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /src/main/java/org/iota/qupla/qupla/statement/helper/LutEntry.java: -------------------------------------------------------------------------------- 1 | package org.iota.qupla.qupla.statement.helper; 2 | 3 | import org.iota.qupla.helper.TritConverter; 4 | import org.iota.qupla.qupla.expression.base.BaseExpr; 5 | import org.iota.qupla.qupla.parser.Token; 6 | import org.iota.qupla.qupla.parser.Tokenizer; 7 | 8 | public class LutEntry extends BaseExpr 9 | { 10 | public final String inputs; 11 | public final String outputs; 12 | 13 | private LutEntry(final LutEntry copy) 14 | { 15 | super(copy); 16 | 17 | inputs = copy.inputs; 18 | outputs = copy.outputs; 19 | } 20 | 21 | public LutEntry(final Tokenizer tokenizer) 22 | { 23 | super(tokenizer); 24 | 25 | inputs = parseTritList(tokenizer); 26 | expect(tokenizer, Token.TOK_EQUAL, "'='"); 27 | outputs = parseTritList(tokenizer); 28 | } 29 | 30 | @Override 31 | public void analyze() 32 | { 33 | } 34 | 35 | @Override 36 | public BaseExpr clone() 37 | { 38 | return new LutEntry(this); 39 | } 40 | 41 | private String parseTrit(final Tokenizer tokenizer) 42 | { 43 | final Token trit = tokenizer.currentToken(); 44 | switch (trit.id) 45 | { 46 | case Token.TOK_LITERAL_FALSE: 47 | tokenizer.nextToken(); 48 | return TritConverter.BOOL_FALSE; 49 | 50 | case Token.TOK_LITERAL_TRUE: 51 | tokenizer.nextToken(); 52 | return TritConverter.BOOL_TRUE; 53 | 54 | case Token.TOK_MINUS: 55 | tokenizer.nextToken(); 56 | return trit.text; 57 | } 58 | 59 | expect(tokenizer, Token.TOK_LITERAL_NUMBER, "trit value, 'false', or 'true'"); 60 | if (trit.text.length() != 1 || trit.text.charAt(0) > '1') 61 | { 62 | error(trit, "Invalid trit value"); 63 | } 64 | 65 | return trit.text; 66 | } 67 | 68 | private String parseTritList(final Tokenizer tokenizer) 69 | { 70 | String trits = parseTrit(tokenizer); 71 | while (tokenizer.tokenId() == Token.TOK_COMMA) 72 | { 73 | tokenizer.nextToken(); 74 | trits += parseTrit(tokenizer); 75 | } 76 | 77 | return trits; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/main/java/org/iota/qupla/qupla/statement/helper/TritStructDef.java: -------------------------------------------------------------------------------- 1 | package org.iota.qupla.qupla.statement.helper; 2 | 3 | import java.util.ArrayList; 4 | 5 | import org.iota.qupla.qupla.expression.NameExpr; 6 | import org.iota.qupla.qupla.expression.base.BaseExpr; 7 | import org.iota.qupla.qupla.expression.constant.ConstTypeName; 8 | import org.iota.qupla.qupla.parser.Token; 9 | import org.iota.qupla.qupla.parser.Tokenizer; 10 | 11 | public class TritStructDef extends BaseExpr 12 | { 13 | public final ArrayList fields = new ArrayList<>(); 14 | 15 | public TritStructDef(final TritStructDef copy) 16 | { 17 | super(copy); 18 | 19 | cloneArray(fields, copy.fields); 20 | } 21 | 22 | public TritStructDef(final Tokenizer tokenizer, final Token identifier) 23 | { 24 | super(tokenizer, identifier); 25 | 26 | expect(tokenizer, Token.TOK_GROUP_OPEN, "'{'"); 27 | 28 | do 29 | { 30 | final ConstTypeName fieldType = new ConstTypeName(tokenizer); 31 | 32 | final NameExpr field = new NameExpr(tokenizer, "field name"); 33 | field.type = fieldType; 34 | 35 | fields.add(field); 36 | } 37 | while (tokenizer.tokenId() != Token.TOK_GROUP_CLOSE); 38 | 39 | tokenizer.nextToken(); 40 | } 41 | 42 | @Override 43 | public void analyze() 44 | { 45 | for (final BaseExpr field : fields) 46 | { 47 | field.analyze(); 48 | size += field.size; 49 | } 50 | } 51 | 52 | @Override 53 | public BaseExpr clone() 54 | { 55 | return new TritStructDef(this); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/org/iota/qupla/qupla/statement/helper/TritVectorDef.java: -------------------------------------------------------------------------------- 1 | package org.iota.qupla.qupla.statement.helper; 2 | 3 | import org.iota.qupla.qupla.expression.base.BaseExpr; 4 | import org.iota.qupla.qupla.expression.constant.ConstExpr; 5 | import org.iota.qupla.qupla.parser.Token; 6 | import org.iota.qupla.qupla.parser.Tokenizer; 7 | 8 | public class TritVectorDef extends BaseExpr 9 | { 10 | public BaseExpr typeExpr; 11 | 12 | public TritVectorDef(final TritVectorDef copy) 13 | { 14 | super(copy); 15 | 16 | typeExpr = clone(copy.typeExpr); 17 | } 18 | 19 | public TritVectorDef(final Tokenizer tokenizer, final Token identifier) 20 | { 21 | super(tokenizer, identifier); 22 | 23 | expect(tokenizer, Token.TOK_ARRAY_OPEN, "'['"); 24 | 25 | typeExpr = new ConstExpr(tokenizer).optimize(); 26 | 27 | expect(tokenizer, Token.TOK_ARRAY_CLOSE, "']'"); 28 | } 29 | 30 | @Override 31 | public void analyze() 32 | { 33 | typeExpr.analyze(); 34 | typeInfo = typeExpr.typeInfo; 35 | size = typeExpr.size; 36 | if (size <= 0) 37 | { 38 | error("Invalid trit vector size value"); 39 | } 40 | } 41 | 42 | @Override 43 | public BaseExpr clone() 44 | { 45 | return new TritVectorDef(this); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/resources/Examples/DispatcherTest.qpl: -------------------------------------------------------------------------------- 1 | // tests Entity-Environment-Effect processing by the Qubic Dispatcher 2 | 3 | // note that it is common sense to create specific functions when you 4 | // want to use them in combination with environments and have them wrap 5 | // the more generic, reusable functions. This keeps the generic functions 6 | // 'clean' and also will allow you to have a more specific structured trit 7 | // vector as input that provides more info you can filter on, like an 8 | // invocation id which would allow you to discern between return values 9 | // from a shared environment so that you only process results that were 10 | // intended for you 11 | 12 | 13 | // note that we have two environments: 'first' and 'second' 14 | 15 | // this function will be called from the top level 16 | // it affects environment 'first', which means that its result 17 | // will be posted as an affect to that environment 18 | func Int firstOne (Int val) { 19 | affect first 20 | return val 21 | } 22 | 23 | // this function joins environment 'first', which means it will get sent 24 | // the effects posted to this environment by firstOne() in the next wave 25 | // it also affects environment 'second', which means that its result 26 | // will be posted as an affect to that environment 27 | func Int nextOne (Int val) { 28 | join first 29 | affect second 30 | return val 31 | } 32 | 33 | // finally, this function joins environment 'second', which means it will get sent 34 | // the effects posted to this environment by nextOne() in the next wave 35 | // since it does not affect any environments processing will stop after this wave 36 | func Int lastOne (Int val) { 37 | join second 38 | return val 39 | } 40 | 41 | eval firstOne(12) 42 | eval firstOne(13) 43 | -------------------------------------------------------------------------------- /src/main/resources/Examples/Factorial.qpl: -------------------------------------------------------------------------------- 1 | // returns the n-th factorial number 2 | // Java equivalent: 3 | // return (n == 0) ? 1 : (n * factorial(n - 1)) 4 | 5 | // data point: the maximum value for n! which still fits: 6 | // in a Huge integer is 33: 8683317618811886495518194401280000000 7 | // in a Hash integer is 78: 11324281178206297831457521158732046228731749579488251990048962825668835325234200766245086213177344000000000000000000 8 | 9 | template factorial { 10 | func T factorial (T n) { 11 | isZero = isZero[sign(n)] 12 | return isZero ? 1 : mul(n, factorial(decr(n))) 13 | } 14 | } 15 | 16 | 17 | test 1 = factorial(0) 18 | test 1 = factorial(1) 19 | test 2 = factorial(2) 20 | test 6 = factorial(3) 21 | test 24 = factorial(4) 22 | test 120 = factorial(5) 23 | test 720 = factorial(6) 24 | test 8683317618811886495518194401280000000 = factorial(33) 25 | test 8683317618811886495518194401280000000 = factorial(33) 26 | 27 | // highest possible input value that still fits in a Hash result is 78 28 | eval factorial(78) 29 | 30 | // see what happens when it won't fit 31 | eval factorial(79) 32 | -------------------------------------------------------------------------------- /src/main/resources/Examples/Sorting.qpl: -------------------------------------------------------------------------------- 1 | //import Qupla 2 | // 3 | //type E [Tiny] 4 | //type Pair [E*2] 5 | //type size [E*8] 6 | // 7 | ////terminal values for pairs 8 | //func Pair sorting(Bool up, Pair a) { 9 | // return mul(isLess[cmp(a[0:E], a[E:E])], up) ? a[0:E] & a[E:E] : a[E:E] & a[0:E] 10 | //} 11 | // 12 | //func Pair merge(Bool up, Pair a) { 13 | // return mul(isLess[cmp(a[0:E], a[E:E])], up) ? a[0:E] & a[E:E] : a[E:E] & a[0:E] 14 | //} 15 | // 16 | //func Pair compare (Bool up, Pair a) { 17 | // return mul(isLess[cmp(a[0:E], a[E:E])], up) ? a[0:E] & a[E:E] : a[E:E] & a[0:E] 18 | //} 19 | // 20 | //template compare { 21 | // type Half [L / 2] 22 | // type Q [L - 2*E] 23 | // 24 | // func L compare(Bool up, L a) { 25 | // c = isLess[cmp(a[0:E], a[Half:E])] 26 | // r = compare(up, a[E:Half - E] & a[Half+E: Half - E]) 27 | // return mul(c,up) ? a[0:E] & r[0:Half - E] & a[Half:E] & r[Half - E: Half - E] : 28 | // a[Half:E] & r[0:Half - E] & a[0:E] & r[Half - E: Half - E] 29 | // } 30 | //} 31 | // 32 | //template sorting { 33 | // type Half [L / 2] 34 | // type Q [L-2*E] 35 | // func L merge (Bool up, L a) { 36 | // b = compare(up, a) 37 | // return merge(up, b[0:Half]) & merge(up, b[Half:Half]) 38 | // } 39 | // 40 | // func L sorting (Bool up, L a) { 41 | // return merge(up, sorting(1, a[0:Half]) & sorting(-1, a[Half:Half])) 42 | // } 43 | // 44 | // func size tt1 (Bool up) { 45 | // return sub((as(1) & as(2) & as(3) & as(4) & as(5) & as(6) & as(7) & as(8)), sorting(up, as(4) & as(6) & as(8) & as(1) & as(2) & as(3) & as(7) & as(5))) 46 | // } 47 | //} -------------------------------------------------------------------------------- /src/main/resources/Examples/ThreeXplusOne.qpl: -------------------------------------------------------------------------------- 1 | import Qupla 2 | 3 | // ThreeXplusOne calculates and prints sequence x(n+1) = isEven(x(n)) ? x(n)/2 : 3*x(n)+1 4 | // It is a proven fact (by experiment) that with any positive integer x(0) < 5 x 2^60 5 | // this sequence always reaches 1 after a finite number of steps. 6 | // Maybe someone already proved it for any positive integer :) 7 | // E.g. starting with x(0) = 27 sequence comes to value 1 after 110 steps. 8 | // Run with -eval 9 | // Idea by lunfardo 10 | 11 | // check this video, too: https://www.youtube.com/watch?v=m4CjXk_b8zo 12 | 13 | template ThreeXplusOne { 14 | func T threeXplusOne(T n){ 15 | dummy = print(n) 16 | is2 = equal(n, 2) 17 | return is2 ? 1 : threeXplusOneDo(n) 18 | } 19 | 20 | func T threeXplusOneDo(T n){ 21 | isEven = even(n) 22 | return threeXplusOne(isEven ? div(n, 2) : mul3add1(n)) 23 | } 24 | 25 | func T mul3add1(T n){ 26 | mul3 = rshift(n) 27 | return incr(mul3) 28 | } 29 | } 30 | 31 | // 110 steps 32 | eval threeXplusOne(27) 33 | 34 | //169 steps 35 | eval threeXplusOne(26171) 36 | -------------------------------------------------------------------------------- /src/main/resources/Examples/bin2trin.qpl: -------------------------------------------------------------------------------- 1 | import Qupla 2 | 3 | // convert input value from 'binary' trit value to trinary value 4 | // 'binary' input trits can only be 0 or 1 5 | 6 | template bin2trin 7 | { 8 | func T bin2trin(T val) 9 | { 10 | return bin2trin2(val, 0, 1) 11 | } 12 | 13 | func T bin2trin2(T remain , T sum, T power) 14 | { 15 | newSum = isOne[remain[0]] ? add(sum, power) : sum 16 | done = isZero[sign(remain)] 17 | return done ? sum : bin2trin2(lshift(remain), newSum, add(power, power)) 18 | } 19 | } 20 | 21 | 22 | test 0 = bin2trin(0) 23 | test 1 = bin2trin(1) 24 | test 2 = bin2trin(3) 25 | test 3 = bin2trin(4) 26 | test 15 = bin2trin(40) 27 | test 255 = bin2trin(3280) 28 | test 65535 = bin2trin(21523360) 29 | test 4294967295 = bin2trin(926510094425920) 30 | // some of the tests may be grained with zeroes inbetween the 111...111 sequence, don't worry when calculating 2^n-1 and (3^n-1)/2 yourown 31 | test 340282366920938463463374607431768211455 = bin2trin(5895092288869291585760436430706259332839105796137920554548480) 32 | test 115792089237316195423570985008687907853269984665640564039457584007913129639935 33 | = bin2trin(69504226188572366382469893394830651557109425404264568995802412215018036314883217970500884577054804760905832770274449717760) 34 | test 13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006084095 35 | = bin2trin(9661674916144457552727034361009790527700732880801664275092268814451233373207768500008969714893014677195041164647293059752576754550666470442049020239364319771280275066863699741389031161203686169060521699834121138295895752329492941497636218270720) 36 | test 179769308128688554841593914336777228061788645087206598745762043938980733953745707508027864856415641942640823241898028769893055642878690194031277212647185337028480491457581597864186726890708791588267512013107914692314913190551492247774529330958055264124819053398988059396676162108264800478523162911021390102523 37 | = bin2trin(186695924370069331493319608213469809026120840269878529864401083138484546852557016082547942836221729172284179845394434319822072666510763444429975462187449479415343223072455417061004069708018863884709587406765210511026171923411791023565100951052266843751891497803359615503592287914493445124195050471647146311769968524981088534884337335397635320260306267407703218825677345201222906845325815734555633487154320091345760111767956553023832139344844800265683541905371098976094347829428199236771564) 38 | -------------------------------------------------------------------------------- /src/main/resources/Examples/helix.qpl: -------------------------------------------------------------------------------- 1 | // CfB's helix logic gate 2 | 3 | lut helix { 4 | //A B C X Y Z // rotate inputs right 5 | -,-,- = -,-,- // 6 6 | -,-,0 = 0,-,- // 4 7 | -,-,1 = -,1,- // 5 8 | -,0,- = -,-,0 // 4 9 | -,0,0 = 0,0,- // 2 10 | -,0,1 = -,0,1 // 3 11 | -,1,- = 1,-,- // 5 12 | -,1,0 = -,1,0 // 3 13 | -,1,1 = 1,-,1 // 4 14 | 0,-,- = -,0,- // 4 15 | 0,-,0 = -,0,0 // 2 16 | 0,-,1 = 0,-,1 // 3 17 | 0,0,- = 0,-,0 // 2 18 | 0,0,0 = 0,0,0 // 0 19 | 0,0,1 = 1,0,0 // 1 20 | 0,1,- = 0,1,- // 3 21 | 0,1,0 = 0,0,1 // 1 22 | 0,1,1 = 1,1,0 // 2 23 | 1,-,- = -,-,1 // 5 24 | 1,-,0 = 1,-,0 // 3 25 | 1,-,1 = 1,1,- // 4 26 | 1,0,- = 1,0,- // 3 27 | 1,0,0 = 0,1,0 // 1 28 | 1,0,1 = 0,1,1 // 2 29 | 1,1,- = -,1,1 // 4 30 | 1,1,0 = 1,0,1 // 2 31 | 1,1,1 = 1,1,1 // 3 32 | } 33 | -------------------------------------------------------------------------------- /src/main/resources/FpgaServer/Layout.h: -------------------------------------------------------------------------------- 1 | #ifndef H_LAYOUT 2 | #define H_LAYOUT 3 | 4 | #include 5 | #include 6 | 7 | 8 | typedef struct 9 | { 10 | uint16_t lutValues[4]; 11 | } LutDef; 12 | 13 | typedef struct 14 | { 15 | uint16_t lutIndex; 16 | uint16_t nrOfInputs; 17 | uint16_t * inputIndexes; 18 | } SiteDef; 19 | 20 | typedef struct 21 | { 22 | uint16_t nrOfBlockInputTrits; 23 | uint16_t nrOfSites; 24 | SiteDef * siteDefs; 25 | uint16_t nrOfBlockOutputTrits; 26 | uint16_t * outputIndexes; 27 | uint8_t * outputTrits; 28 | } BlockDef; 29 | 30 | typedef struct 31 | { 32 | uint16_t nrOfLuts; 33 | LutDef * lutDefs; 34 | uint16_t nrOfBlocks; 35 | BlockDef * blockDefs; 36 | } AbraLayout; 37 | 38 | 39 | extern void printLayout(AbraLayout *layout); 40 | extern AbraLayout * readLayout(uint8_t *addr); 41 | extern void saveLayout(AbraLayout *layout, char filename[31]); 42 | extern bool verifyLayout(uint8_t * addr, int u8fileSize); 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /src/main/resources/FpgaServer/Qlut.h: -------------------------------------------------------------------------------- 1 | #ifndef H_QLUT 2 | #define H_QLUT 3 | 4 | #include "Layout.h" 5 | 6 | 7 | typedef struct 8 | { 9 | int fd; 10 | uint32_t * config; 11 | uint16_t * proc; 12 | uint8_t * data; 13 | } Qlut; 14 | 15 | extern void qlutClose(Qlut * qlut); 16 | extern Qlut * qlutOpen(); 17 | extern void qlutProcessData(Qlut * qlut); 18 | extern void qlutReadData(Qlut * qlut, AbraLayout * layout); 19 | extern void qlutWaitComplete(Qlut * qlut); 20 | extern void qlutWaitIdle(Qlut * qlut); 21 | extern void qlutWriteConfig(Qlut * qlut, AbraLayout * layout); 22 | extern void qlutWriteData(Qlut * qlut, uint8_t * data, int length); 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /src/main/resources/FpgaServer/soc_system.rbf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iotaledger-archive/qupla/13af581737d3f3f36944f268817295d5e0f78c94/src/main/resources/FpgaServer/soc_system.rbf -------------------------------------------------------------------------------- /src/main/resources/GameOfLife/GolHash.qpl: -------------------------------------------------------------------------------- 1 | import Curl 2 | 3 | func Hash golHash (Hash id) { 4 | curl = curlAbsorb(0, id, 27) 5 | result = curlSqueeze(curl, 27) 6 | return result.hash 7 | } 8 | 9 | template golSign { 10 | type Col [T] 11 | type Row [T] 12 | type Grid [Row * Col] 13 | type Hashes [Grid / Hash] 14 | func Hash golSign(Hash id, Grid grid) { 15 | curl = curlAbsorb(0, id, 27) 16 | result = curlSqueeze(curl, 27) 17 | return golHashGrid(grid, result.curlState) 18 | } 19 | 20 | func Hash golHashGrid(Grid grid, CurlState scratch) { 21 | result = curlSqueeze(golHashGridLoop(grid, scratch, all(1)), 27) 22 | return result.hash 23 | } 24 | 25 | func CurlState golHashGridLoop(Grid grid, CurlState curl, Hashes rowShifter) 26 | { 27 | // check if row shifter is done 28 | rowShifterIsDone = isZero[rowShifter[0]] 29 | return rowShifterIsDone ? curl : golHashGridRow(grid, curl, rowShifter) 30 | } 31 | 32 | func CurlState golHashGridRow(Grid grid, CurlState curl, Hashes rowShifter) 33 | { 34 | newGrid = grid[Hash : Grid - Hash] & as(0) 35 | newCurl = curlAbsorb(curl, grid[0 : Hash], 27) 36 | return golHashGridLoop(newGrid, newCurl, lshift(rowShifter)) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/resources/Qupla/Container/arcRadixMap.qpl: -------------------------------------------------------------------------------- 1 | // implements a simple reference counted key/value storage 2 | // needs to be wrapped in an entity function and accessed through 3 | // sending effects to work correctly 4 | 5 | template arcRadixMap 6 | { 7 | type Traversal { 8 | Trit cmd 9 | K key 10 | V value 11 | } 12 | 13 | type Arc { 14 | V value 15 | Int count 16 | } 17 | 18 | func V arcRadixMap (Trit cmd, K key, V value) { 19 | param = Traversal { 20 | cmd = cmd 21 | key = key 22 | value = value 23 | } 24 | return arcRadixTraverse(param) 25 | } 26 | 27 | func V arcRadixTraverse (Traversal param) { 28 | // note that for readability we should probably split this function 29 | // into two functions, one for the case where we call leaf() and one 30 | // for the case where we do the traverse() and determine nextParam, 31 | // but that would effectively double the length of the recursive call 32 | // path, so for storage efficiency reasons we keep them together as one 33 | 34 | keyZero = isZero[sign(param.key)] 35 | 36 | keyTrit = param.key[0] 37 | return keyZero ? arcRadixLeaf(param) : 38 | isOne [keyTrit] ? arcRadixTraverse(arcRadixTraverseNext(keyZero, param)) : 39 | isZero[keyTrit] ? arcRadixTraverse(arcRadixTraverseNext(keyZero, param)) : 40 | isMin [keyTrit] ? arcRadixTraverse(arcRadixTraverseNext(keyZero, param)) : null 41 | } 42 | 43 | func Traversal arcRadixTraverseNext (Bool keyZero, Traversal param) { 44 | return not[keyZero] ? Traversal { 45 | cmd = param.cmd 46 | key = lshift(param.key) 47 | value = param.value 48 | } : null 49 | } 50 | 51 | func V arcRadixLeaf (Traversal param) { 52 | state Arc arc 53 | 54 | oldValue = arc 55 | 56 | cmd = param.cmd 57 | arc = isZero[cmd] ? oldValue : 58 | isOne [cmd] ? arcRadixLeafSet(oldValue, param.value) : 59 | isMin [cmd] ? arcRadixLeafRemove(oldValue) : null 60 | 61 | return oldValue.value 62 | } 63 | 64 | func Arc arcRadixLeafSet (Arc arc, V value) { 65 | return Arc { 66 | value = value 67 | count = incr(arc.count) 68 | } 69 | } 70 | 71 | func Arc arcRadixLeafRemove (Arc arc) { 72 | count = decr(arc.count) 73 | sign = sign(count) 74 | return isZero[sign] ? 0 : 75 | isPositive[sign] ? Arc { 76 | value = arc.value 77 | count = count 78 | } : null 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/main/resources/Qupla/Container/array.qpl: -------------------------------------------------------------------------------- 1 | // implements a simple array storage 2 | // needs to be wrapped in an entity function and accessed through 3 | // sending effects to work correctly 4 | 5 | template array 6 | { 7 | func T array (Trit cmd, Tiny index, T value) { 8 | state T cell 9 | 10 | found = isZero[sign(index)] 11 | cell = and[found, isOne[cmd]] ? value : null 12 | return found ? cell : array(cmd, decr(index), value) 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/resources/Qupla/Container/listMap.qpl: -------------------------------------------------------------------------------- 1 | // implements a simple key/value storage 2 | // needs to be wrapped in an entity function and accessed through 3 | // sending effects to work correctly 4 | 5 | template listMap 6 | { 7 | type State { 8 | Trit next 9 | K key 10 | V value 11 | } 12 | 13 | type ReturnState { 14 | State s 15 | V ret 16 | } 17 | 18 | func V listMap (Trit cmd, K key, V value) { 19 | state State s 20 | 21 | oldState = s 22 | deeper = and[unequal(key, oldState.key), isOne[oldState.next]] 23 | 24 | newState = not[deeper] ? listMapProcess(cmd, key, value, oldState) : null 25 | s = deeper ? oldState : newState.s 26 | return deeper ? listMap(cmd, key, value) : newState.ret 27 | } 28 | 29 | func ReturnState listMapProcess (Trit cmd, K key, V value, State s) { 30 | return ReturnState { 31 | s = State { 32 | next = isOne [cmd] ? 1 : s.next 33 | key = key 34 | value = isOne [cmd] ? value : isMin[cmd] ? 0 : s.value 35 | } 36 | ret = s.value 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/resources/Qupla/Container/radixMap.qpl: -------------------------------------------------------------------------------- 1 | // implements a simple key/value storage 2 | // needs to be wrapped in an entity function and accessed through 3 | // sending effects to work correctly 4 | 5 | template radixMap 6 | { 7 | type Traversal { 8 | Trit cmd 9 | K key 10 | V value 11 | } 12 | 13 | func V radixMap (Trit cmd, K key, V value) { 14 | param = Traversal { 15 | cmd = cmd 16 | key = key 17 | value = value 18 | } 19 | return radixMapTraverse(param) 20 | } 21 | 22 | func V radixMapTraverse (Traversal param) { 23 | // note that for readability we should probably split this function 24 | // into two functions, one for the case where we call leaf() and one 25 | // for the case where we do the traverse() and determine nextParam, 26 | // but that would effectively double the length of the recursive call 27 | // path, so for storage efficiency reasons we keep them together as one 28 | 29 | keyZero = isZero[sign(param.key)] 30 | 31 | keyTrit = param.key[0] 32 | return keyZero ? radixMapLeaf(param) : 33 | isOne [keyTrit] ? radixMapTraverse(radixMapTraverseNext(keyZero, param)) : 34 | isZero[keyTrit] ? radixMapTraverse(radixMapTraverseNext(keyZero, param)) : 35 | isMin [keyTrit] ? radixMapTraverse(radixMapTraverseNext(keyZero, param)) : null 36 | } 37 | 38 | func Traversal radixMapTraverseNext (Bool keyZero, Traversal param) { 39 | return not[keyZero] ? Traversal { 40 | cmd = param.cmd 41 | key = lshift(param.key) 42 | value = param.value 43 | } : null 44 | } 45 | 46 | func V radixMapLeaf (Traversal param) { 47 | state V value 48 | 49 | oldValue = value 50 | 51 | cmd = param.cmd 52 | value = isZero[cmd] ? oldValue : isOne[cmd] ? param.value : isMin[cmd] ? 0 : null 53 | 54 | return oldValue 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/resources/Qupla/Math/abs.qpl: -------------------------------------------------------------------------------- 1 | // returns val < 0 ? -val : val 2 | 3 | template abs { 4 | func T abs (T val) { 5 | return isNegative[sign(val)] ? neg(val) : val 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/main/resources/Qupla/Math/add.qpl: -------------------------------------------------------------------------------- 1 | // returns lhs + rhs 2 | 3 | template add { 4 | func T add (T lhs, T rhs) { 5 | // use full adder but don't return the carry trit 6 | sum = fullAdd(lhs, rhs, 0) 7 | return sum.value 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/main/resources/Qupla/Math/cmp.qpl: -------------------------------------------------------------------------------- 1 | // LUT logic: return (trit1 < trit2) ? - : (trit1 > trit2) ? 1 : 0; 2 | lut cmp { 3 | -,- = 0 4 | 0,- = 1 5 | 1,- = 1 6 | -,0 = - 7 | 0,0 = 0 8 | 1,0 = 1 9 | -,1 = - 10 | 0,1 = - 11 | 1,1 = 0 12 | } 13 | 14 | // LUT logic: return (Bool) (trit1 < 0) 15 | lut isLess { 16 | - = true 17 | 0 = false 18 | 1 = false 19 | } 20 | 21 | // LUT logic: return (Bool) (trit1 > 0) 22 | lut isGreater { 23 | - = false 24 | 0 = false 25 | 1 = true 26 | } 27 | 28 | // LUT logic: return (Bool) (trit1 == 0) 29 | lut isEqual { 30 | - = false 31 | 0 = true 32 | 1 = false 33 | } 34 | 35 | // LUT logic: return (Bool) (trit1 >= 0) 36 | lut notLess { 37 | - = false 38 | 0 = true 39 | 1 = true 40 | } 41 | 42 | // LUT logic: return (Bool) (trit1 <= 0) 43 | lut notGreater { 44 | - = true 45 | 0 = true 46 | 1 = false 47 | } 48 | 49 | // LUT logic: return (Bool) (trit1 != 0) 50 | lut notEqual { 51 | - = true 52 | 0 = false 53 | 1 = true 54 | } 55 | 56 | 57 | // returns (Bool) ((lhs < rhs) ? - : (lhs > rhs) ? 1 : 0) 58 | 59 | func Trit cmp (Trit lhs, Trit rhs) { 60 | return cmp[lhs, rhs] 61 | } 62 | 63 | template cmp3 = A + B + C { 64 | type A [T / 3] 65 | type B [T / 3] 66 | type C [T / 3] 67 | 68 | func Trit cmp (T lhs, T rhs) { 69 | val0 = cmp(lhs[0 : A], rhs[0 : A]) 70 | val1 = cmp(lhs[A : B], rhs[A : B]) 71 | val2 = cmp(lhs[A + B : C], rhs[A + B : C]) 72 | return sign[val0, val1, val2] 73 | } 74 | } 75 | 76 | template cmp { 77 | type A [T - T / 2] 78 | type B [T - A] 79 | 80 | func Trit cmp (T lhs, T rhs) { 81 | val0 = cmp(lhs[0 : A], rhs[0 : A]) 82 | val1 = cmp(lhs[A : B], rhs[A : B]) 83 | return sign2[val0, val1] 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/main/resources/Qupla/Math/decr.qpl: -------------------------------------------------------------------------------- 1 | // returns val - 1 2 | 3 | template decr { 4 | func T decr (T val) { 5 | halfSum = halfAdd(val, -) 6 | return halfSum.value 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/main/resources/Qupla/Math/div.qpl: -------------------------------------------------------------------------------- 1 | // returns lhs / rhs 2 | 3 | template div { 4 | type T2 { 5 | T quotient 6 | T remainder 7 | } 8 | 9 | func T div (T lhs, T rhs) { 10 | ret = divMod(lhs, rhs) 11 | return ret.quotient 12 | } 13 | 14 | func T ceilDiv (T lhs, T rhs) { 15 | ret = ceilDivMod(lhs, rhs) 16 | return ret.quotient 17 | } 18 | 19 | func T floorDiv (T lhs, T rhs) { 20 | ret = floorDivMod(lhs, rhs) 21 | return ret.quotient 22 | } 23 | 24 | func T roundDiv (T lhs, T rhs) { 25 | ret = roundDivMod(lhs, rhs) 26 | return ret.quotient 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/resources/Qupla/Math/even.qpl: -------------------------------------------------------------------------------- 1 | // LUT logic: return (Bool) (((trit1 + trit2 + trit3) & 1) == 0 ? 1 : 0) 2 | lut even { 3 | -,-,- = false 4 | 0,-,- = true 5 | 1,-,- = false 6 | -,0,- = true 7 | 0,0,- = false 8 | 1,0,- = true 9 | -,1,- = false 10 | 0,1,- = true 11 | 1,1,- = false 12 | -,-,0 = true 13 | 0,-,0 = false 14 | 1,-,0 = true 15 | -,0,0 = false 16 | 0,0,0 = true 17 | 1,0,0 = false 18 | -,1,0 = true 19 | 0,1,0 = false 20 | 1,1,0 = true 21 | -,-,1 = false 22 | 0,-,1 = true 23 | 1,-,1 = false 24 | -,0,1 = true 25 | 0,0,1 = false 26 | 1,0,1 = true 27 | -,1,1 = false 28 | 0,1,1 = true 29 | 1,1,1 = false 30 | } 31 | 32 | // returns (Bool) ((val & 1) == 0 ? 1 : 0) 33 | 34 | func Bool even (Trit val) { 35 | return isZero[val] 36 | } 37 | 38 | func Bool even (Tryte val) { 39 | return even[val[0], val[1], val[2]] 40 | } 41 | 42 | template even3 = A + B + C { 43 | type A [T / 3] 44 | type B [T / 3] 45 | type C [T / 3] 46 | 47 | func Bool even (T val) { 48 | val0 = even(val[0 : A]) 49 | val1 = even(val[A : B]) 50 | val2 = even(val[A + B : C]) 51 | return xor3[val0, val1, val2] 52 | } 53 | } 54 | 55 | template even { 56 | type A [T - T / 2] 57 | type B [T - A] 58 | 59 | func Bool even (T val) { 60 | val0 = even(val[0 : A]) 61 | val1 = even(val[A : B]) 62 | return xor[val0, val1] 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/resources/Qupla/Math/fulladd.qpl: -------------------------------------------------------------------------------- 1 | // LUT logic: return sum(trit1 + trit2 + trit3) 2 | lut fullAddSum { 3 | -,-,- = 0 4 | -,-,0 = 1 5 | -,-,1 = - 6 | -,0,- = 1 7 | -,0,0 = - 8 | -,0,1 = 0 9 | -,1,- = - 10 | -,1,0 = 0 11 | -,1,1 = 1 12 | 0,-,- = 1 13 | 0,-,0 = - 14 | 0,-,1 = 0 15 | 0,0,- = - 16 | 0,0,0 = 0 17 | 0,0,1 = 1 18 | 0,1,- = 0 19 | 0,1,0 = 1 20 | 0,1,1 = - 21 | 1,-,- = - 22 | 1,-,0 = 0 23 | 1,-,1 = 1 24 | 1,0,- = 0 25 | 1,0,0 = 1 26 | 1,0,1 = - 27 | 1,1,- = 1 28 | 1,1,0 = - 29 | 1,1,1 = 0 30 | } 31 | 32 | // LUT logic: return carry(trit1 + trit2 + trit3) 33 | lut fullAddCarry { 34 | -,-,- = - 35 | -,-,0 = - 36 | -,-,1 = 0 37 | -,0,- = - 38 | -,0,0 = 0 39 | -,0,1 = 0 40 | -,1,- = 0 41 | -,1,0 = 0 42 | -,1,1 = 0 43 | 0,-,- = - 44 | 0,-,0 = 0 45 | 0,-,1 = 0 46 | 0,0,- = 0 47 | 0,0,0 = 0 48 | 0,0,1 = 0 49 | 0,1,- = 0 50 | 0,1,0 = 0 51 | 0,1,1 = 1 52 | 1,-,- = 0 53 | 1,-,0 = 0 54 | 1,-,1 = 0 55 | 1,0,- = 0 56 | 1,0,0 = 0 57 | 1,0,1 = 1 58 | 1,1,- = 0 59 | 1,1,0 = 1 60 | 1,1,1 = 1 61 | } 62 | 63 | // note: types Carry, TritCarry, and TryteCarry are defined in halfAdd.qpl 64 | 65 | // returns lhs + rhs + carry 66 | 67 | func TritCarry fullAdd (Trit lhs, Trit rhs, Carry carry) { 68 | return TritCarry { 69 | value = fullAddSum[lhs, rhs, carry] 70 | carry = fullAddCarry[lhs, rhs, carry] 71 | } 72 | } 73 | 74 | func TryteCarry fullAdd (Tryte lhs, Tryte rhs, Carry carry) { 75 | sum0 = fullAddSum[lhs[0], rhs[0], carry] 76 | carry0 = fullAddCarry[lhs[0], rhs[0], carry] 77 | sum1 = fullAddSum[lhs[1], rhs[1], carry0] 78 | carry1 = fullAddCarry[lhs[1], rhs[1], carry0] 79 | return TryteCarry { 80 | value = sum0 & sum1 & fullAddSum[lhs[2], rhs[2], carry1] 81 | carry = fullAddCarry[lhs[2], rhs[2], carry1] 82 | } 83 | } 84 | 85 | template fullAdd3 = A + B + C { 86 | type A [T / 3] 87 | type B [T / 3] 88 | type C [T / 3] 89 | type TCarry { 90 | T value 91 | Carry carry 92 | } 93 | 94 | func TCarry fullAdd (T lhs, T rhs, Carry carry) { 95 | add0 = fullAdd(lhs[0 : A], rhs[0 : A], carry) 96 | add1 = fullAdd(lhs[A : B], rhs[A : B], add0.carry) 97 | add2 = fullAdd(lhs[A + B : C], rhs[A + B : C], add1.carry) 98 | return TCarry { 99 | value = add0.value & add1.value & add2.value 100 | carry = add2.carry 101 | } 102 | } 103 | } 104 | 105 | 106 | template fullAdd { 107 | type A [T - T / 2] 108 | type B [T - A] 109 | type TCarry { 110 | T value 111 | Carry carry 112 | } 113 | 114 | func TCarry fullAdd (T lhs, T rhs, Carry carry) { 115 | add0 = fullAdd(lhs[0 : A], rhs[0 : A], carry) 116 | add1 = fullAdd(lhs[A : B], rhs[A : B], add0.carry) 117 | return TCarry { 118 | value = add0.value & add1.value 119 | carry = add1.carry 120 | } 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /src/main/resources/Qupla/Math/halfadd.qpl: -------------------------------------------------------------------------------- 1 | // LUT logic: return sum(trit1 + trit2) 2 | lut halfAddSum { 3 | -,- = 1 // -1 + -1 = 1, carry -1 4 | -,0 = - // -1 + 0 = -1, carry 0 5 | -,1 = 0 // -1 + 1 = 0, carry 0 6 | 0,- = - // 0 + -1 = -1, carry 0 7 | 0,0 = 0 // 0 + 0 = 0, carry 0 8 | 0,1 = 1 // 0 + 1 = 1, carry 0 9 | 1,- = 0 // 1 + -1 = 0, carry 0 10 | 1,0 = 1 // 1 + 0 = 1, carry 0 11 | 1,1 = - // 1 + 1 = -1, carry 1 12 | } 13 | 14 | // LUT logic: return carry(trit1 + trit2) 15 | lut halfAddCarry { 16 | -,- = - // -1 + -1 = 1, carry -1 17 | -,0 = 0 // -1 + 0 = -1, carry 0 18 | -,1 = 0 // -1 + 1 = 0, carry 0 19 | 0,- = 0 // 0 + -1 = -1, carry 0 20 | 0,0 = 0 // 0 + 0 = 0, carry 0 21 | 0,1 = 0 // 0 + 1 = 1, carry 0 22 | 1,- = 0 // 1 + -1 = 0, carry 0 23 | 1,0 = 0 // 1 + 0 = 1, carry 0 24 | 1,1 = 1 // 1 + 1 = -1, carry 1 25 | } 26 | 27 | 28 | type TritCarry { 29 | Trit value 30 | Carry carry 31 | } 32 | 33 | type TryteCarry { 34 | Tryte value 35 | Carry carry 36 | } 37 | 38 | 39 | // returns val + carry 40 | 41 | func TritCarry halfAdd (Trit val, Carry carry) { 42 | return TritCarry { 43 | value = halfAddSum[val, carry] 44 | carry = halfAddCarry[val, carry] 45 | } 46 | } 47 | 48 | func TryteCarry halfAdd (Tryte val, Carry carry) { 49 | sum0 = halfAddSum[val[0], carry] 50 | carry0 = halfAddCarry[val[0], carry] 51 | sum1 = halfAddSum[val[1], carry0] 52 | carry1 = halfAddCarry[val[1], carry0] 53 | return TryteCarry { 54 | value = sum0 & sum1 & halfAddSum[val[2], carry1] 55 | carry = halfAddCarry[val[2], carry1] 56 | } 57 | } 58 | 59 | template halfAdd3 = A + B + C { 60 | type A [T / 3] 61 | type B [T / 3] 62 | type C [T / 3] 63 | type TCarry { 64 | T value 65 | Carry carry 66 | } 67 | 68 | func TCarry halfAdd (T val, Carry carry) { 69 | add0 = halfAdd(val[0 : A], carry) 70 | add1 = halfAdd(val[A : B], add0.carry) 71 | add2 = halfAdd(val[A + B : C], add1.carry) 72 | return TCarry { 73 | value = add0.value & add1.value & add2.value 74 | carry = add2.carry 75 | } 76 | } 77 | } 78 | 79 | template halfAdd { 80 | type A [T - T / 2] 81 | type B [T - A] 82 | type TCarry { 83 | T value 84 | Carry carry 85 | } 86 | 87 | func TCarry halfAdd (T val, Carry carry) { 88 | add0 = halfAdd(val[0 : A], carry) 89 | add1 = halfAdd(val[A : B], add0.carry) 90 | return TCarry { 91 | value = add0.value & add1.value 92 | carry = add1.carry 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/main/resources/Qupla/Math/incr.qpl: -------------------------------------------------------------------------------- 1 | // returns val + 1 2 | 3 | template incr { 4 | func T incr (T val) { 5 | halfSum = halfAdd(val, 1) 6 | return halfSum.value 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/main/resources/Qupla/Math/log3.qpl: -------------------------------------------------------------------------------- 1 | // returns (int) floor(log3(val)) 2 | 3 | template log3 { 4 | func Tiny log3 (T val) { 5 | // only defined for val > 0 6 | return sign(val) ? log3check(val, 3, 0) : null 7 | } 8 | 9 | func Tiny log3check (T val, T power, Tiny log) { 10 | // if the power trit has shifted enough we are done 11 | done = isLess[cmp(val, power)] 12 | return done ? log : log3checkMore(val, power, log) 13 | } 14 | 15 | func Tiny log3checkMore (T val, T power, Tiny log) { 16 | // when power trit shifted out of T entirely we are done as well 17 | done = isZero[sign(power)] 18 | return done ? log : log3checkNext(val, power, log) 19 | } 20 | 21 | func Tiny log3checkNext(T val, T power, Tiny log) { 22 | return log3check(val, rshift(power), incr(log)) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/resources/Qupla/Math/max.qpl: -------------------------------------------------------------------------------- 1 | // returns lhs > rhs ? lhs : rhs 2 | 3 | template max { 4 | func T max (T lhs, T rhs) { 5 | return isGreater[cmp(lhs, rhs)] ? lhs : rhs 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/main/resources/Qupla/Math/min.qpl: -------------------------------------------------------------------------------- 1 | // returns lhs < rhs ? lhs : rhs 2 | 3 | template min { 4 | func T min (T lhs, T rhs) { 5 | return isLess[cmp(lhs, rhs)] ? lhs : rhs 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/main/resources/Qupla/Math/mod.qpl: -------------------------------------------------------------------------------- 1 | // returns lhs % rhs 2 | 3 | template mod { 4 | type T2 { 5 | T quotient 6 | T remainder 7 | } 8 | 9 | func T mod (T lhs, T rhs) { 10 | ret = divMod(lhs, rhs) 11 | return ret.remainder 12 | } 13 | 14 | func T ceilMod (T lhs, T rhs) { 15 | ret = ceilDivMod(lhs, rhs) 16 | return ret.remainder 17 | } 18 | 19 | func T floorMod (T lhs, T rhs) { 20 | ret = floorDivMod(lhs, rhs) 21 | return ret.remainder 22 | } 23 | 24 | func T roundMod (T lhs, T rhs) { 25 | ret = roundDivMod(lhs, rhs) 26 | return ret.remainder 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/resources/Qupla/Math/mul.qpl: -------------------------------------------------------------------------------- 1 | // returns lhs * rhs 2 | 3 | template mul { 4 | func T mul (T lhs, T rhs) { 5 | // use full multiplier but don't return the overflow 6 | product = fullMul(lhs, rhs) 7 | return product[0 : T] 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/main/resources/Qupla/Math/neg.qpl: -------------------------------------------------------------------------------- 1 | // LUT logic: return -trit1 2 | lut neg { 3 | - = 1 4 | 0 = 0 5 | 1 = - 6 | } 7 | 8 | // note that making an entire trit-vector's value negative 9 | // can be done by simply negating every trit in the vector 10 | 11 | // returns -val 12 | 13 | func Trit neg (Trit val) { 14 | return neg[val] 15 | } 16 | 17 | template neg3 = A + B + C { 18 | type A [T / 3] 19 | type B [T / 3] 20 | type C [T / 3] 21 | 22 | func T neg (T val) { 23 | val0 = neg(val[0 : A]) 24 | val1 = neg(val[A : B]) 25 | val2 = neg(val[A + B : C]) 26 | return val0 & val1 & val2 27 | } 28 | } 29 | 30 | template neg { 31 | type A [T - T / 2] 32 | type B [T - A] 33 | 34 | func T neg (T val) { 35 | val0 = neg(val[0 : A]) 36 | val1 = neg(val[A : B]) 37 | return val0 & val1 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/resources/Qupla/Math/pow3.qpl: -------------------------------------------------------------------------------- 1 | // returns 3^power 2 | 3 | template pow3 { 4 | func T pow3 (Tiny power) { 5 | // only defined for power >= 0 6 | return notNegative[sign(power)] ? pow3loop(1, power) : null 7 | } 8 | 9 | func T pow3loop (T val, Tiny power) { 10 | return isZero[sign(power)] ? val : pow3loop(rshift(val), decr(power)) 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/main/resources/Qupla/Math/sign.qpl: -------------------------------------------------------------------------------- 1 | // LUT logic: return the sign of a 3-trit value with least significant trit first 2 | // return sign(trit1, trit2, trit3) 3 | // note that the sign of a trit *is* the trit, so we start at Tryte instead 4 | lut sign { 5 | -,-,- = - 6 | 0,-,- = - 7 | 1,-,- = - 8 | -,0,- = - 9 | 0,0,- = - 10 | 1,0,- = - 11 | -,1,- = - 12 | 0,1,- = - 13 | 1,1,- = - 14 | -,-,0 = - 15 | 0,-,0 = - 16 | 1,-,0 = - 17 | -,0,0 = - 18 | 0,0,0 = 0 19 | 1,0,0 = 1 20 | -,1,0 = 1 21 | 0,1,0 = 1 22 | 1,1,0 = 1 23 | -,-,1 = 1 24 | 0,-,1 = 1 25 | 1,-,1 = 1 26 | -,0,1 = 1 27 | 0,0,1 = 1 28 | 1,0,1 = 1 29 | -,1,1 = 1 30 | 0,1,1 = 1 31 | 1,1,1 = 1 32 | } 33 | 34 | lut sign2 { 35 | -,- = - 36 | 0,- = - 37 | 1,- = - 38 | -,0 = - 39 | 0,0 = 0 40 | 1,0 = 1 41 | -,1 = 1 42 | 0,1 = 1 43 | 1,1 = 1 44 | } 45 | 46 | // returns (val < 0) ? - : (val > 0) : 1 : 0 47 | 48 | func Trit sign (Trit val) { 49 | return val 50 | } 51 | 52 | template sign3 = A + B + C { 53 | type A [T / 3] 54 | type B [T / 3] 55 | type C [T / 3] 56 | 57 | func Trit sign (T val) { 58 | val0 = sign(val[0 : A]) 59 | val1 = sign(val[A : B]) 60 | val2 = sign(val[A + B : C]) 61 | return sign[val0, val1, val2] 62 | } 63 | } 64 | 65 | template sign { 66 | type A [T - T / 2] 67 | type B [T - A] 68 | 69 | func Trit sign (T val) { 70 | val0 = sign(val[0 : A]) 71 | val1 = sign(val[A : B]) 72 | return sign2[val0, val1] 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/main/resources/Qupla/Math/sub.qpl: -------------------------------------------------------------------------------- 1 | // returns lhs - rhs 2 | 3 | // implement subtraction by adding the negative value 4 | // exploits that A - B is equivalent to A + (-B) 5 | 6 | template sub { 7 | func T sub (T lhs, T rhs) { 8 | // use full adder but don't return the carry trit 9 | sum = fullAdd(lhs, neg(rhs), 0) 10 | return sum.value 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/main/resources/Qupla/all.qpl: -------------------------------------------------------------------------------- 1 | // returns a trit vector that repeats the input trit 2 | // passing 1 will generate the maximum value for the return type 3 | // passing 0 will generate zero for the return type (pretty useless) 4 | // passing - will generate the minimum value for the return type 5 | 6 | func Trit all (Trit val) { 7 | return val 8 | } 9 | 10 | template all3 = A + B + C { 11 | type A [T / 3] 12 | type B [T / 3] 13 | type C [T / 3] 14 | 15 | func T all(Trit val) { 16 | val0 = all(val) 17 | val1 = all(val) 18 | val2 = all(val) 19 | return val0 & val1 & val2 20 | } 21 | } 22 | 23 | template all { 24 | type A [T - T / 2] 25 | type B [T - A] 26 | 27 | func T all(Trit val) { 28 | val0 = all(val) 29 | val1 = all(val) 30 | return val0 & val1 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/resources/Qupla/as.qpl: -------------------------------------------------------------------------------- 1 | // returns val 2 | 3 | // this function can be used as a cast operator 4 | // for constants to cast them to specific size 5 | // it can be handy in this case for example: 6 | // return f(a) & as(12) & f(b) 7 | 8 | template as { 9 | func T as (T val) { 10 | return val 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/main/resources/Qupla/break.qpl: -------------------------------------------------------------------------------- 1 | // returns val 2 | 3 | // this function can be used to set a breakpoint in the Qupla code. 4 | // the interpreter will intecept usage of break to achieve this 5 | // You can set a breakpoint in the Java debugger at the corresponding 6 | // location in QuplaEvalContext.interceptCall 7 | 8 | 9 | template break { 10 | func T break (T val) { 11 | return val 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/resources/Qupla/equal.qpl: -------------------------------------------------------------------------------- 1 | // LUT logic: return (Bool) (trit1 == trit2) 2 | lut equal { 3 | -,- = true 4 | -,0 = false 5 | -,1 = false 6 | 0,- = false 7 | 0,0 = true 8 | 0,1 = false 9 | 1,- = false 10 | 1,0 = false 11 | 1,1 = true 12 | } 13 | 14 | // LUT logic: return (Bool) (trit1 == -) 15 | lut isMin { 16 | - = true 17 | 0 = false 18 | 1 = false 19 | } 20 | 21 | // LUT logic: return (Bool) (trit1 < 0) 22 | lut isNegative { 23 | - = true 24 | 0 = false 25 | 1 = false 26 | } 27 | 28 | // LUT logic: return (Bool) (trit1 == 1) 29 | lut isOne { 30 | - = false 31 | 0 = false 32 | 1 = true 33 | } 34 | 35 | // LUT logic: return (Bool) (trit1 > 0) 36 | lut isPositive { 37 | - = false 38 | 0 = false 39 | 1 = true 40 | } 41 | 42 | // LUT logic: return (Bool) (trit1 == 0) 43 | lut isZero { 44 | - = false 45 | 0 = true 46 | 1 = false 47 | } 48 | 49 | // LUT logic: return (Bool) (trit1 >= 0) 50 | lut notNegative { 51 | - = false 52 | 0 = true 53 | 1 = true 54 | } 55 | 56 | // LUT logic: return (Bool) (trit1 <= 0) 57 | lut notPositive { 58 | - = true 59 | 0 = true 60 | 1 = false 61 | } 62 | 63 | // LUT logic: return (Bool) (trit1 != 0) 64 | lut notZero { 65 | - = true 66 | 0 = false 67 | 1 = true 68 | } 69 | 70 | 71 | // returns (Bool) lhs == rhs 72 | 73 | func Bool equal(Trit lhs, Trit rhs) { 74 | return equal[lhs, rhs] 75 | } 76 | 77 | template equal3 = A + B + C { 78 | type A [T / 3] 79 | type B [T / 3] 80 | type C [T / 3] 81 | 82 | func Bool equal(T lhs, T rhs) { 83 | val0 = equal(lhs[0 : A], rhs[0 : A]) 84 | val1 = equal(lhs[A : B], rhs[A : B]) 85 | val2 = equal(lhs[A + B : C], rhs[A + B : C]) 86 | return and3[val0, val1, val2] 87 | } 88 | } 89 | 90 | template equal { 91 | type A [T - T / 2] 92 | type B [T - A] 93 | 94 | func Bool equal(T lhs, T rhs) { 95 | val0 = equal(lhs[0 : A], rhs[0 : A]) 96 | val1 = equal(lhs[A : B], rhs[A : B]) 97 | return and[val0, val1] 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/main/resources/Qupla/lshift.qpl: -------------------------------------------------------------------------------- 1 | // returns val << 1 2 | 3 | template lshift { 4 | func T lshift (T val) { 5 | return val[1 : T - 1] & 0 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/main/resources/Qupla/lshiftN.qpl: -------------------------------------------------------------------------------- 1 | // returns n < 0 ? val >> -n : val << n 2 | 3 | // special thanks to our community member hello_world for the inspiration 4 | 5 | template lshiftN { 6 | // P is largest power of 3 smaller than T 7 | type P [pow3(log3(decr(sizeof T)))] 8 | 9 | func T lshiftN (T val, Tiny n) 10 | { 11 | // if n is negative do shift right instead 12 | flip = isNegative[sign(n)] 13 | return flip ? rshiftNLimit(val, neg(n)) : lshiftNLimit(val, n) 14 | } 15 | 16 | func T lshiftNLimit (T val, Tiny n) 17 | { 18 | // if we shift out all trits return zero 19 | zero = notLess[cmp(n, sizeof T)] 20 | return zero ? 0 : lshiftN2(val, n) 21 | } 22 | } 23 | 24 | // make sure we first match against the Trit version of lshiftN2() 25 | // so that we instantiate this one in favor of the one in lshiftN3 26 | // note that P is not used but we're matching against 2 template 27 | // parameters (T and Q) in lshiftN2(val, n) 28 | template lshiftN2 { 29 | func T lshiftN2 (T val, Tiny n) 30 | { 31 | // n can only be 0, 1, or 2, in which case trit 0 is 0, 1, or - 32 | n0 = n[0] 33 | zero = isZero[n0] ? val : null 34 | one = n0 ? val[1 : T - 1] & 0 : null 35 | two = isMin[n0] ? val[2 : T - 2] & 0 & 0 : null 36 | return zero | one | two 37 | } 38 | } 39 | 40 | template lshiftN3 { 41 | type Q [P / 3] 42 | 43 | func T lshiftN2 (T val, Tiny n) 44 | { 45 | // go to next-lower power of 3? 46 | //TODO use 1 or 2 trits of n to determine this once we know log3(P) 47 | // similar to how we do it in lshiftN2() above 48 | less = isLess[cmp(n, sizeof P)] 49 | return less ? lshiftN2(val, n) : lshiftN2Shift(val, n) 50 | } 51 | 52 | func T lshiftN2Shift (T val, Tiny n) 53 | { 54 | // shift val by current power of 3 55 | newVal = val[P : T - P] & as

(0) 56 | newN = sub(n, sizeof P) 57 | return lshiftN2(newVal, newN) 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/resources/Qupla/print.qpl: -------------------------------------------------------------------------------- 1 | // returns val 2 | 3 | // this function can be used to print a value to the console 4 | // the interpreter will intecept usage of print to achieve this 5 | 6 | template print { 7 | func T print (T val) { 8 | return val 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/main/resources/Qupla/quorum.qpl: -------------------------------------------------------------------------------- 1 | // returns (val1 == val2) ? val1 : 2 | // (val2 == val3) ? val2 : 3 | // (val3 == val1) ? val3 : null 4 | 5 | // determine quorum result 6 | 7 | template quorum { 8 | func T quorum(T val1, T val2, T val3) { 9 | equal1 = equal(val1, val2) 10 | equal2 = and[not[equal1], equal(val2, val3)] 11 | equal3 = and[not[equal2], equal(val3, val1)] 12 | return (equal1 ? val1 : null) | (equal2 ? val2 : null) | (equal3 ? val3 : null) 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/resources/Qupla/rshift.qpl: -------------------------------------------------------------------------------- 1 | // returns val >> 1 2 | 3 | template rshift { 4 | func T rshift (T val) { 5 | return 0 & val[0 : T - 1] 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/main/resources/Qupla/rshiftN.qpl: -------------------------------------------------------------------------------- 1 | // returns n < 0 ? val << -n : val >> n 2 | 3 | // special thanks to our community member hello_world for the inspiration 4 | 5 | template rshiftN { 6 | // P is largest power of 3 smaller than T 7 | type P [pow3(log3(decr(sizeof T)))] 8 | 9 | func T rshiftN (T val, Tiny n) 10 | { 11 | // if n is negative do shift left instead 12 | flip = isNegative[sign(n)] 13 | return flip ? lshiftNLimit(val, neg(n)) : rshiftNLimit(val, n) 14 | } 15 | 16 | func T rshiftNLimit (T val, Tiny n) 17 | { 18 | // if we shift out all trits return zero 19 | zero = notLess[cmp(n, sizeof T)] 20 | return zero ? 0 : rshiftN2(val, n) 21 | } 22 | } 23 | 24 | // make sure we first match against the Trit version of rshiftN2() 25 | // so that we instantiate this one in favor of the one in rshiftN3 26 | template rshiftN2 { 27 | func T rshiftN2 (T val, Tiny n) 28 | { 29 | // n can only be 0, 1, or 2, in which case trit 0 is 0, 1, or - 30 | n0 = n[0] 31 | zero = isZero[n0] ? val : null 32 | one = n0 ? 0 & val[0 : T - 1] : null 33 | two = isMin[n0] ? 0 & 0 & val[0 : T - 2] : null 34 | return zero | one | two 35 | } 36 | } 37 | 38 | template rshiftN3 { 39 | type Q [P / 3] 40 | 41 | func T rshiftN2 (T val, Tiny n) 42 | { 43 | // go to next-lower power of 3? 44 | //TODO use 1 or 2 trits of n to determine this once we know log3(P) 45 | // similar to how we do it in rshiftN2() above 46 | less = isLess[cmp(n, sizeof P)] 47 | return less ? rshiftN2(val, n) : rshiftN2Shift(val, n) 48 | } 49 | 50 | func T rshiftN2Shift (T val, Tiny n) 51 | { 52 | // shift val by current power of 3 53 | newVal = as

(0) & val[0 : T - P] 54 | newN = sub(n, sizeof P) 55 | return rshiftN2(newVal, newN) 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/resources/Qupla/types.qpl: -------------------------------------------------------------------------------- 1 | // define some standard trit lengths we will use in our examples 2 | // note that you can define the optimal trit size for any type's 3 | // range to reduce energy requirements accordingly, but for 4 | // simplicity we'll only define power-of-3 sized types for now 5 | 6 | type Trit [1] // -/+ 1 7 | type Tryte [3] // -/+ 13 8 | type Tiny [9] // -/+ 9,841 9 | type Int [27] // -/+ 3,812,798,742,493 10 | type Huge [81] // -/+ 221,713,244,121,518,884,974,124,815,309,574,946,401 11 | type Hash [243] // standard 81 trytes hash value 12 | type Hash3 [729] 13 | type Hash9 [2187] 14 | type Signature [6561] 15 | 16 | // double-width and quad-width integer types for use in mul/div/mod operations 17 | type Trit2 [2] // -/+ 4 18 | type Trit4 [4] // -/+ 40 19 | type Tryte2 [6] // -/+ 364 20 | type Tryte4 [12] // -/+ 265,720 21 | type Tiny2 [18] // -/+ 193,710,244 22 | type Tiny4 [36] // -/+ 75,047,317,648,499,560 23 | type Int2 [54] // -/+ 29,074,868,501,520,029,845,195,084 24 | type Int4 [108] 25 | type Huge2 [162] 26 | type Huge4 [324] 27 | type Hash2 [486] 28 | type Hash4 [972] 29 | 30 | // define a convenience type to make code more readable 31 | // should always be a binary boolean value false or true 32 | // (note: this convention is not (yet) enforced by Qupla) 33 | type Bool [Trit] 34 | 35 | type Carry [Trit] 36 | 37 | // here's how to define a named structured trit vector 38 | // it consists of the concatenation of all sub-vectors 39 | // its total size is the sum of all sub-vector sizes 40 | // note that structures themselves can contain structures 41 | 42 | type TinyFloat { 43 | Tiny mantissa // -/+ 9,841 44 | Tryte exponent // -/+ 3^13 45 | } 46 | type Float { // slightly larger than IEEE 754 32-bit float 47 | Tiny2 mantissa // -/+ 193,710,244 48 | Tryte2 exponent // -/+ 3^364 49 | } 50 | type Double { // slightly larger than IEEE 754 64-bit double 51 | Tiny4 mantissa // -/+ 75,047,317,648,499,560 52 | Tiny exponent // -/+ 3^9,841 53 | } 54 | type HugeFloat { 55 | Int2 mantissa // -/+ 29,074,868,501,520,029,845,195,084 56 | Tiny2 exponent // -/+ 3^193,710,244 57 | } 58 | 59 | // attachment sub-structure layout 60 | type Attachment { 61 | Int timestamp 62 | Int timestampLowerBound 63 | Int timestampUpperBound 64 | } 65 | 66 | // sample future IOTA transaction layout 67 | type Transaction { 68 | Signature signature 69 | Hash extraDataDigest 70 | Hash address 71 | Huge value 72 | Int issuanceTimestamp 73 | Int timelockLowerBound 74 | Int timelockUpperBound 75 | Huge bundle 76 | Hash trunk 77 | Hash branch 78 | Huge tag 79 | Attachment attachment 80 | Huge nonce 81 | } 82 | -------------------------------------------------------------------------------- /src/main/resources/Qupla/unequal.qpl: -------------------------------------------------------------------------------- 1 | // LUT logic: return (Bool) (trit1 != trit2) 2 | lut unequal { 3 | -,- = false 4 | -,0 = true 5 | -,1 = true 6 | 0,- = true 7 | 0,0 = false 8 | 0,1 = true 9 | 1,- = true 10 | 1,0 = true 11 | 1,1 = false 12 | } 13 | 14 | // returns (Bool) (lhs != rhs) 15 | 16 | func Bool unequal(Trit lhs, Trit rhs) { 17 | return unequal[lhs, rhs] 18 | } 19 | 20 | template unequal3 = A + B + C { 21 | type A [T / 3] 22 | type B [T / 3] 23 | type C [T / 3] 24 | 25 | func Bool unequal(T lhs, T rhs) { 26 | val0 = unequal(lhs[0 : A], rhs[0 : A]) 27 | val1 = unequal(lhs[A : B], rhs[A : B]) 28 | val2 = unequal(lhs[A + B : C], rhs[A + B : C]) 29 | return or3[val0, val1, val2] 30 | } 31 | } 32 | 33 | template unequal { 34 | type A [T - T / 2] 35 | type B [T - A] 36 | 37 | func Bool unequal(T lhs, T rhs) { 38 | val0 = unequal(lhs[0 : A], rhs[0 : A]) 39 | val1 = unequal(lhs[A : B], rhs[A : B]) 40 | return or[val0, val1] 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/resources/QuplaTests/Container/arcRadixMap.qpl: -------------------------------------------------------------------------------- 1 | // retrieve hash key 123456 from initial state 2 | test 0 = arcRadixMap(0, 123456, 0) 3 | 4 | // store 999999 under hash key 123456 5 | test 0 = arcRadixMap(1, 123456, 999999) 6 | 7 | // verify hash key 123456 was set 8 | test 999999 = arcRadixMap(0, 123456, 0) 9 | 10 | // store 999999 under hash key 123456 again 11 | test 999999 = arcRadixMap(1, 123456, 999999) 12 | 13 | // verify hash key 123456 was set 14 | test 999999 = arcRadixMap(0, 123456, 0) 15 | 16 | // remove hash key 123456 17 | test 999999 = arcRadixMap(-, 123456, 0) 18 | 19 | // verify hash key 123456 still set 20 | test 999999 = arcRadixMap(0, 123456, 0) 21 | 22 | // remove hash key 123456 again 23 | test 999999 = arcRadixMap(-, 123456, 0) 24 | 25 | // verify hash key 123456 was removed 26 | test 0 = arcRadixMap(0, 123456, 0) 27 | -------------------------------------------------------------------------------- /src/main/resources/QuplaTests/Container/array.qpl: -------------------------------------------------------------------------------- 1 | test 0 = array(0, 0, 1) 2 | test 0 = array(1, 0, 1) 3 | test 1 = array(0, 0, 0) 4 | 5 | test 0 = array(0, 1, 2) 6 | test 0 = array(1, 1, 2) 7 | test 2 = array(0, 1, 0) 8 | test 1 = array(0, 0, 0) 9 | 10 | test 1 = array(1, 0, 3) 11 | test 3 = array(0, 0, 0) 12 | test 2 = array(0, 1, 0) 13 | -------------------------------------------------------------------------------- /src/main/resources/QuplaTests/Container/listMap.qpl: -------------------------------------------------------------------------------- 1 | test 0 = listMap(0, 123456, 789) 2 | test 0 = listMap(1, 123456, 789) 3 | test 789 = listMap(0, 123456, 0) 4 | test 789 = listMap(-, 123456, 0) 5 | test 0 = listMap(0, 123456, 789) 6 | 7 | test 0 = listMap(0, 654321, 987) 8 | test 0 = listMap(1, 654321, 987) 9 | test 987 = listMap(0, 654321, 0) 10 | test 987 = listMap(-, 654321, 0) 11 | test 0 = listMap(0, 654321, 987) 12 | 13 | test 0 = listMap(1, 123456, 789) 14 | test 0 = listMap(1, 654321, 987) 15 | test 789 = listMap(0, 123456, 0) 16 | test 987 = listMap(0, 654321, 0) 17 | test 789 = listMap(-, 123456, 0) 18 | test 987 = listMap(-, 654321, 0) 19 | test 0 = listMap(0, 123456, 789) 20 | test 0 = listMap(0, 654321, 987) 21 | -------------------------------------------------------------------------------- /src/main/resources/QuplaTests/Container/radixMap.qpl: -------------------------------------------------------------------------------- 1 | // retrieve hash key 123456 from initial state 2 | test 0 = radixMap(0, 123456, 0) 3 | 4 | // store 999999 under hash key 123456 5 | test 0 = radixMap(1, 123456, 999999) 6 | 7 | // verify hash key 123456 was set 8 | test 999999 = radixMap(0, 123456, 0) 9 | 10 | // remove hash key 123456 11 | test 999999 = radixMap(-, 123456, 0) 12 | 13 | // verify hash key 123456 was removed 14 | test 0 = radixMap(0, 123456, 0) 15 | -------------------------------------------------------------------------------- /src/main/resources/QuplaTests/Math/abs.qpl: -------------------------------------------------------------------------------- 1 | test 0 = abs(0) 2 | test 1 = abs(1) 3 | test 1 = abs(-1) 4 | test 2 = abs(2) 5 | test 2 = abs(-2) 6 | test 999 = abs(999) 7 | test 999 = abs(-999) 8 | -------------------------------------------------------------------------------- /src/main/resources/QuplaTests/Math/add.qpl: -------------------------------------------------------------------------------- 1 | test 0 = add( 0, 0) 2 | 3 | test 1 = add( 0, 1) 4 | test 1 = add( 1, 0) 5 | test 2 = add( 1, 1) 6 | test 2 = add( 0, 2) 7 | test 2 = add( 2, 0) 8 | test 3 = add( 1, 2) 9 | test 3 = add( 2, 1) 10 | test 4 = add( 2, 2) 11 | 12 | test -1 = add( 0, -1) 13 | test -1 = add(-1, 0) 14 | test -2 = add(-1, -1) 15 | test -2 = add( 0, -2) 16 | test -2 = add(-2, 0) 17 | test -3 = add(-1, -2) 18 | test -3 = add(-2, -1) 19 | test -4 = add(-2, -2) 20 | 21 | test 0 = add( 1, -1) 22 | test -1 = add( 1, -2) 23 | test 1 = add( 2, -1) 24 | test 0 = add( 2, -2) 25 | 26 | test 0 = add(-1, 1) 27 | test 1 = add(-1, 2) 28 | test -1 = add(-2, 1) 29 | test 0 = add(-2, 2) 30 | 31 | test 6 = add( 3, 3) 32 | test 0 = add( 3, -3) 33 | test 0 = add(-3, 3) 34 | test -6 = add(-3, -3) 35 | -------------------------------------------------------------------------------- /src/main/resources/QuplaTests/Math/cmp.qpl: -------------------------------------------------------------------------------- 1 | test 0 = cmp(-1, -1) 2 | test - = cmp(-1, 0) 3 | test - = cmp(-1, 1) 4 | test 1 = cmp(0, -1) 5 | test 0 = cmp(0, 0) 6 | test - = cmp(0, 1) 7 | test 1 = cmp(1, -1) 8 | test 1 = cmp(1, 0) 9 | test 0 = cmp(1, 1) 10 | test - = cmp(10, 20) 11 | test 1 = cmp(20, 10) 12 | test - = cmp(-30, 40) 13 | test 1 = cmp(40, -30) 14 | test 1 = cmp(50, -60) 15 | test - = cmp(-60, 50) 16 | test 1 = cmp(-70, -80) 17 | test - = cmp(-80, -70) 18 | test 0 = cmp(90, 90) 19 | test 0 = cmp(-100, -100) 20 | 21 | test 0 = cmp(-1, -1) 22 | test - = cmp(-1, 0) 23 | test - = cmp(-1, 1) 24 | test 1 = cmp(0, -1) 25 | test 0 = cmp(0, 0) 26 | test - = cmp(0, 1) 27 | test 1 = cmp(1, -1) 28 | test 1 = cmp(1, 0) 29 | test 0 = cmp(1, 1) 30 | test - = cmp(10, 20) 31 | test 1 = cmp(20, 10) 32 | test - = cmp(-30, 40) 33 | test 1 = cmp(40, -30) 34 | test 1 = cmp(50, -60) 35 | test - = cmp(-60, 50) 36 | test 1 = cmp(-70, -80) 37 | test - = cmp(-80, -70) 38 | test 0 = cmp(90, 90) 39 | test 0 = cmp(-100, -100) 40 | -------------------------------------------------------------------------------- /src/main/resources/QuplaTests/Math/decr.qpl: -------------------------------------------------------------------------------- 1 | test -2 = decr(-1) 2 | test -1 = decr(0) 3 | test 0 = decr(1) 4 | test 1 = decr(2) 5 | test 2 = decr(3) 6 | 7 | test -2 = decr(-1) 8 | test -1 = decr(0) 9 | test 0 = decr(1) 10 | test 1 = decr(2) 11 | test 2 = decr(3) 12 | -------------------------------------------------------------------------------- /src/main/resources/QuplaTests/Math/div.qpl: -------------------------------------------------------------------------------- 1 | test 0 = div( 0, 0) 2 | 3 | test 0 = div( 0, 1) 4 | //test 0 = div( 1, 0) 5 | test 1 = div( 1, 1) 6 | test 0 = div( 0, 2) 7 | //test 0 = div( 2, 0) 8 | test 0 = div( 1, 2) 9 | test 2 = div( 2, 1) 10 | test 1 = div( 2, 2) 11 | 12 | test 0 = div( 0, -1) 13 | //test 0 = div(-1, 0) 14 | test 1 = div(-1, -1) 15 | test 0 = div( 0, -2) 16 | //test 0 = div(-2, 0) 17 | test 0 = div(-1, -2) 18 | test 2 = div(-2, -1) 19 | test 1 = div(-2, -2) 20 | 21 | test -1 = div( 1, -1) 22 | test 0 = div( 1, -2) 23 | test -2 = div( 2, -1) 24 | test -1 = div( 2, -2) 25 | 26 | test -1 = div(-1, 1) 27 | test 0 = div(-1, 2) 28 | test -2 = div(-2, 1) 29 | test -1 = div(-2, 2) 30 | 31 | test 1 = div( 3, 3) 32 | test -1 = div( 3, -3) 33 | test -1 = div(-3, 3) 34 | test 1 = div(-3, -3) 35 | -------------------------------------------------------------------------------- /src/main/resources/QuplaTests/Math/divmod.qpl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iotaledger-archive/qupla/13af581737d3f3f36944f268817295d5e0f78c94/src/main/resources/QuplaTests/Math/divmod.qpl -------------------------------------------------------------------------------- /src/main/resources/QuplaTests/Math/even.qpl: -------------------------------------------------------------------------------- 1 | test true = even(0) 2 | test false = even(1) 3 | test true = even(2) 4 | test false = even(3) 5 | test true = even(4) 6 | test false = even(5) 7 | test true = even(6) 8 | test false = even(7) 9 | test true = even(8) 10 | test false = even(9) 11 | test true = even(10) 12 | test false = even(11) 13 | test true = even(12) 14 | test false = even(13) 15 | test true = even(14) 16 | test false = even(15) 17 | test true = even(16) 18 | test false = even(17) 19 | test true = even(18) 20 | test false = even(19) 21 | test false = even(-1) 22 | test true = even(-2) 23 | test false = even(-3) 24 | test true = even(-4) 25 | test false = even(-5) 26 | test true = even(-6) 27 | test false = even(-7) 28 | test true = even(-8) 29 | test false = even(-9) 30 | test true = even(-10) 31 | test false = even(-11) 32 | test true = even(-12) 33 | test false = even(-13) 34 | test true = even(-14) 35 | test false = even(-15) 36 | test true = even(-16) 37 | test false = even(-17) 38 | test true = even(-18) 39 | test false = even(-19) 40 | -------------------------------------------------------------------------------- /src/main/resources/QuplaTests/Math/fulladd.qpl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iotaledger-archive/qupla/13af581737d3f3f36944f268817295d5e0f78c94/src/main/resources/QuplaTests/Math/fulladd.qpl -------------------------------------------------------------------------------- /src/main/resources/QuplaTests/Math/fullmul.qpl: -------------------------------------------------------------------------------- 1 | test 16 = fullMul(4, 4) 2 | test 25 = fullMul(5, 5) 3 | test 36 = fullMul(6, 6) 4 | test 49 = fullMul(7, 7) 5 | test 64 = fullMul(8, 8) 6 | test 81 = fullMul(9, 9) 7 | test 100 = fullMul(10, 10) 8 | test 121 = fullMul(11, 11) 9 | test 144 = fullMul(12, 12) 10 | test 169 = fullMul(13, 13) 11 | test 132496 = fullMul(364, 364) 12 | 13 | test 10758400 = fullMul(3280, 3280) 14 | test 43046721 = fullMul(6561, 6561) 15 | test 96805921 = fullMul(9839, 9839) 16 | test 96825600 = fullMul(9840, 9840) 17 | test 96845281 = fullMul(9841, 9841) 18 | test 871666576 = fullMul(29524, 29524) 19 | -------------------------------------------------------------------------------- /src/main/resources/QuplaTests/Math/halfadd.qpl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iotaledger-archive/qupla/13af581737d3f3f36944f268817295d5e0f78c94/src/main/resources/QuplaTests/Math/halfadd.qpl -------------------------------------------------------------------------------- /src/main/resources/QuplaTests/Math/incr.qpl: -------------------------------------------------------------------------------- 1 | test -2 = incr(-3) 2 | test -1 = incr(-2) 3 | test 0 = incr(-1) 4 | test 1 = incr(0) 5 | test 2 = incr(1) 6 | 7 | test -2 = incr(-3) 8 | test -1 = incr(-2) 9 | test 0 = incr(-1) 10 | test 1 = incr(0) 11 | test 2 = incr(1) 12 | -------------------------------------------------------------------------------- /src/main/resources/QuplaTests/Math/log3.qpl: -------------------------------------------------------------------------------- 1 | test 0 = log3(1) 2 | test 0 = log3(2) 3 | test 1 = log3(3) 4 | test 1 = log3(4) 5 | test 1 = log3(5) 6 | test 1 = log3(6) 7 | test 1 = log3(7) 8 | test 1 = log3(8) 9 | test 2 = log3(9) 10 | test 2 = log3(10) 11 | test 2 = log3(11) 12 | test 2 = log3(12) 13 | test 2 = log3(13) 14 | test 2 = log3(14) 15 | test 2 = log3(15) 16 | test 2 = log3(16) 17 | test 2 = log3(17) 18 | test 2 = log3(18) 19 | test 2 = log3(19) 20 | test 2 = log3(20) 21 | test 2 = log3(21) 22 | test 2 = log3(22) 23 | test 2 = log3(23) 24 | test 2 = log3(24) 25 | test 2 = log3(25) 26 | test 2 = log3(26) 27 | test 3 = log3(27) 28 | test 3 = log3(28) 29 | test 3 = log3(29) 30 | 31 | test 3 = log3(80) 32 | test 4 = log3(81) 33 | test 4 = log3(82) 34 | 35 | test 4 = log3(242) 36 | test 5 = log3(243) 37 | test 5 = log3(244) 38 | 39 | test 5 = log3(728) 40 | test 6 = log3(729) 41 | test 6 = log3(730) 42 | 43 | test 6 = log3(2186) 44 | test 7 = log3(2187) 45 | test 7 = log3(2188) 46 | 47 | test 7 = log3(6560) 48 | test 8 = log3(6561) 49 | test 8 = log3(6562) 50 | 51 | test 7 = log3(6560) 52 | test 8 = log3(6561) 53 | test 8 = log3(6562) 54 | 55 | test 8 = log3(9841) 56 | -------------------------------------------------------------------------------- /src/main/resources/QuplaTests/Math/max.qpl: -------------------------------------------------------------------------------- 1 | test -1 = max(-1, -2) 2 | test -1 = max(-2, -1) 3 | test 0 = max(-1, 0) 4 | test 0 = max(0, -1) 5 | test 1 = max(-1, 1) 6 | test 1 = max(1, -1) 7 | test 1 = max(1, 0) 8 | test 1 = max(0, 1) 9 | test 2 = max(1, 2) 10 | test 2 = max(2, 1) 11 | -------------------------------------------------------------------------------- /src/main/resources/QuplaTests/Math/min.qpl: -------------------------------------------------------------------------------- 1 | test -2 = min(-1, -2) 2 | test -2 = min(-2, -1) 3 | test -1 = min(-1, 0) 4 | test -1 = min(0, -1) 5 | test -1 = min(-1, 1) 6 | test -1 = min(1, -1) 7 | test 0 = min(1, 0) 8 | test 0 = min(0, 1) 9 | test 1 = min(1, 2) 10 | test 1 = min(2, 1) 11 | -------------------------------------------------------------------------------- /src/main/resources/QuplaTests/Math/mod.qpl: -------------------------------------------------------------------------------- 1 | test 0 = mod( 0, 0) 2 | 3 | test 0 = mod( 0, 1) 4 | //test 0 = mod( 1, 0) 5 | test 0 = mod( 1, 1) 6 | test 0 = mod( 0, 2) 7 | //test 0 = mod( 2, 0) 8 | test 1 = mod( 1, 2) 9 | test 0 = mod( 2, 1) 10 | test 0 = mod( 2, 2) 11 | 12 | test 0 = mod( 0, -1) 13 | //test 0 = mod(-1, 0) 14 | test 0 = mod(-1, -1) 15 | test 0 = mod( 0, -2) 16 | //test 0 = mod(-2, 0) 17 | test -1 = mod(-1, -2) 18 | test 0 = mod(-2, -1) 19 | test 0 = mod(-2, -2) 20 | 21 | test 0 = mod( 1, -1) 22 | test 1 = mod( 1, -2) 23 | test 0 = mod( 2, -1) 24 | test 0 = mod( 2, -2) 25 | 26 | test 0 = mod(-1, 1) 27 | test -1 = mod(-1, 2) 28 | test 0 = mod(-2, 1) 29 | test 0 = mod(-2, 2) 30 | 31 | test 0 = mod( 3, 3) 32 | test 0 = mod( 3, -3) 33 | test 0 = mod(-3, 3) 34 | test 0 = mod(-3, -3) 35 | -------------------------------------------------------------------------------- /src/main/resources/QuplaTests/Math/mul.qpl: -------------------------------------------------------------------------------- 1 | test 0 = mul( 0, 0) 2 | 3 | test 0 = mul( 0, 1) 4 | test 0 = mul( 1, 0) 5 | test 1 = mul( 1, 1) 6 | test 0 = mul( 0, 2) 7 | test 0 = mul( 2, 0) 8 | test 2 = mul( 1, 2) 9 | test 2 = mul( 2, 1) 10 | test 4 = mul( 2, 2) 11 | 12 | test 0 = mul( 0, -1) 13 | test 0 = mul(-1, 0) 14 | test 1 = mul(-1, -1) 15 | test 0 = mul( 0, -2) 16 | test 0 = mul(-2, 0) 17 | test 2 = mul(-1, -2) 18 | test 2 = mul(-2, -1) 19 | test 4 = mul(-2, -2) 20 | 21 | test -1 = mul( 1, -1) 22 | test -2 = mul( 1, -2) 23 | test -2 = mul( 2, -1) 24 | test -4 = mul( 2, -2) 25 | 26 | test -1 = mul(-1, 1) 27 | test -2 = mul(-1, 2) 28 | test -2 = mul(-2, 1) 29 | test -4 = mul(-2, 2) 30 | 31 | test 9 = mul( 3, 3) 32 | test -9 = mul( 3, -3) 33 | test -9 = mul(-3, 3) 34 | test 9 = mul(-3, -3) 35 | 36 | test 200 = mul(10, 20) 37 | test -1200 = mul(-30, 40) 38 | test -3000 = mul(50, -60) 39 | test 5600 = mul(-70, -80) 40 | -------------------------------------------------------------------------------- /src/main/resources/QuplaTests/Math/neg.qpl: -------------------------------------------------------------------------------- 1 | test 99 = neg(-99) 2 | test 1 = neg(-1) 3 | test 0 = neg(0) 4 | test -1 = neg(1) 5 | test -99 = neg(99) 6 | 7 | test 99 = neg(-99) 8 | test 1 = neg(-1) 9 | test 0 = neg(0) 10 | test -1 = neg(1) 11 | test -99 = neg(99) 12 | -------------------------------------------------------------------------------- /src/main/resources/QuplaTests/Math/pow3.qpl: -------------------------------------------------------------------------------- 1 | test 1 = pow3(0) 2 | test 3 = pow3(1) 3 | test 9 = pow3(2) 4 | test 27 = pow3(3) 5 | test 81 = pow3(4) 6 | test 243 = pow3(5) 7 | test 729 = pow3(6) 8 | test 2187 = pow3(7) 9 | test 6561 = pow3(8) 10 | test 19683 = pow3(9) 11 | test 59049 = pow3(10) 12 | test 177147 = pow3(11) 13 | test 531441 = pow3(12) 14 | test 1594323 = pow3(13) 15 | test 4782969 = pow3(14) 16 | test 14348907 = pow3(15) 17 | test 43046721 = pow3(16) 18 | test 129140163 = pow3(17) 19 | test 387420489 = pow3(18) 20 | test 1162261467 = pow3(19) 21 | test 3486784401 = pow3(20) 22 | test 10460353203 = pow3(21) 23 | -------------------------------------------------------------------------------- /src/main/resources/QuplaTests/Math/sign.qpl: -------------------------------------------------------------------------------- 1 | test - = sign(-99) 2 | test - = sign(-1) 3 | test 0 = sign(0) 4 | test 1 = sign(1) 5 | test 1 = sign(99) 6 | 7 | test - = sign(-99) 8 | test - = sign(-1) 9 | test 0 = sign(0) 10 | test 1 = sign(1) 11 | test 1 = sign(99) 12 | -------------------------------------------------------------------------------- /src/main/resources/QuplaTests/Math/sub.qpl: -------------------------------------------------------------------------------- 1 | test 0 = sub( 0, 0) 2 | 3 | test -1 = sub( 0, 1) 4 | test 1 = sub( 1, 0) 5 | test 0 = sub( 1, 1) 6 | test -2 = sub( 0, 2) 7 | test 2 = sub( 2, 0) 8 | test -1 = sub( 1, 2) 9 | test 1 = sub( 2, 1) 10 | test 0 = sub( 2, 2) 11 | 12 | test 1 = sub( 0, -1) 13 | test -1 = sub(-1, 0) 14 | test 0 = sub(-1, -1) 15 | test 2 = sub( 0, -2) 16 | test -2 = sub(-2, 0) 17 | test 1 = sub(-1, -2) 18 | test -1 = sub(-2, -1) 19 | test 0 = sub(-2, -2) 20 | 21 | test 2 = sub( 1, -1) 22 | test 3 = sub( 1, -2) 23 | test 3 = sub( 2, -1) 24 | test 4 = sub( 2, -2) 25 | 26 | test -2 = sub(-1, 1) 27 | test -3 = sub(-1, 2) 28 | test -3 = sub(-2, 1) 29 | test -4 = sub(-2, 2) 30 | 31 | test 0 = sub( 3, 3) 32 | test 6 = sub( 3, -3) 33 | test -6 = sub(-3, 3) 34 | test 0 = sub(-3, -3) 35 | -------------------------------------------------------------------------------- /src/main/resources/QuplaTests/all.qpl: -------------------------------------------------------------------------------- 1 | import Qupla 2 | 3 | test 1 = all(1) 4 | test 13 = all(1) 5 | test 9841 = all(1) 6 | test 3812798742493 = all(1) 7 | test -221713244121518884974124815309574946401 = all(-) 8 | test 0 = all(0) 9 | test 221713244121518884974124815309574946401 = all(1) 10 | -------------------------------------------------------------------------------- /src/main/resources/QuplaTests/equal.qpl: -------------------------------------------------------------------------------- 1 | test true = equal(-1, -1) 2 | test false = equal(-1, 0) 3 | test false = equal(-1, 1) 4 | test false = equal(0, -1) 5 | test true = equal(0, 0) 6 | test false = equal(0, 1) 7 | test false = equal(1, -1) 8 | test false = equal(1, 0) 9 | test true = equal(1, 1) 10 | test false = equal(10, 20) 11 | test false = equal(-30, 40) 12 | test false = equal(50, -60) 13 | test false = equal(-70, -80) 14 | test true = equal(90, 90) 15 | -------------------------------------------------------------------------------- /src/main/resources/QuplaTests/lshift.qpl: -------------------------------------------------------------------------------- 1 | test 0 = lshift(0) 2 | test 0 = lshift(1) 3 | test 1 = lshift(2) 4 | test 1 = lshift(3) 5 | test 3 = lshift(9) 6 | test 0 = lshift(-1) 7 | test -1 = lshift(-2) 8 | test -1 = lshift(-3) 9 | test -3 = lshift(-9) 10 | -------------------------------------------------------------------------------- /src/main/resources/QuplaTests/rshift.qpl: -------------------------------------------------------------------------------- 1 | test 0 = rshift(0) 2 | test 3 = rshift(1) 3 | test 6 = rshift(2) 4 | test 9 = rshift(3) 5 | test 0 = rshift(9) 6 | test -3 = rshift(-1) 7 | test -6 = rshift(-2) 8 | test -9 = rshift(-3) 9 | test 0 = rshift(-9) 10 | -------------------------------------------------------------------------------- /src/main/resources/QuplaTests/types.qpl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iotaledger-archive/qupla/13af581737d3f3f36944f268817295d5e0f78c94/src/main/resources/QuplaTests/types.qpl -------------------------------------------------------------------------------- /src/main/resources/QuplaTests/unequal.qpl: -------------------------------------------------------------------------------- 1 | test false = unequal(-1, -1) 2 | test true = unequal(-1, 0) 3 | test true = unequal(-1, 1) 4 | test true = unequal(0, -1) 5 | test false = unequal(0, 0) 6 | test true = unequal(0, 1) 7 | test true = unequal(1, -1) 8 | test true = unequal(1, 0) 9 | test false = unequal(1, 1) 10 | test true = unequal(10, 20) 11 | test true = unequal(-30, 40) 12 | test true = unequal(50, -60) 13 | test true = unequal(-70, -80) 14 | test false = unequal(90, 90) 15 | -------------------------------------------------------------------------------- /src/main/resources/Test/DispatcherTest.qpl: -------------------------------------------------------------------------------- 1 | // tests Entity-Environment-Effect processing by the Qubic Dispatcher 2 | 3 | // note that it is common sense to create specific functions when you 4 | // want to use them in combination with environments and have them wrap 5 | // the more generic, reusable functions. This keeps the generic functions 6 | // 'clean' and also will allow you to have a more specific structured trit 7 | // vector as input that provides more info you can filter on, like an 8 | // invocation id which would allow you to discern between return values 9 | // from a shared environment so that you only process results that were 10 | // intended for you 11 | 12 | type Dummy [9] 13 | // note that we have two environments: 'first' and 'second' 14 | 15 | // this function will be called from the top level 16 | // it affects environment 'first', which means that its result 17 | // will be posted as an affect to that environment 18 | func Dummy firstOne (Dummy val) { 19 | affect first 20 | return val 21 | } 22 | 23 | // this function joins environment 'first', which means it will get sent 24 | // the effects posted to this environment by firstOne() in the next wave 25 | // it also affects environment 'second', which means that its result 26 | // will be posted as an affect to that environment 27 | func Dummy nextOne (Dummy val) { 28 | join first 29 | affect second 30 | return val 31 | } 32 | 33 | // finally, this function joins environment 'second', which means it will get sent 34 | // the effects posted to this environment by nextOne() in the next wave 35 | // since it does not affect any environments processing will stop after this wave 36 | func Dummy lastOne (Dummy val) { 37 | join second 38 | return val 39 | } 40 | 41 | eval firstOne(12) 42 | eval firstOne(13) 43 | -------------------------------------------------------------------------------- /src/main/resources/Test/TestCond.qpl: -------------------------------------------------------------------------------- 1 | func Trit TestCond (Trit in) 2 | { 3 | return isZero[in] ? 0 : isOne[in] ? 1 : - 4 | } 5 | -------------------------------------------------------------------------------- /src/main/resources/Test/TestStates.qpl: -------------------------------------------------------------------------------- 1 | import Qupla 2 | 3 | template teststates{ 4 | func Bool leaf (T x){ 5 | state T v 6 | d1 = print(v) 7 | d2 = print(x) 8 | v = x 9 | return equal(d1, d2) 10 | } 11 | 12 | func Bool leaf3 (T x){ 13 | t1 = leaf(as(1)) 14 | t2 = leaf(as(2)) 15 | t3 = leaf(as(3)) 16 | return or3[t1, t2, t3] 17 | } 18 | } 19 | 20 | eval leaf3(100) 21 | -------------------------------------------------------------------------------- /src/main/resources/Verilog/b2/constMin_.vl: -------------------------------------------------------------------------------- 1 | function [1:0] constMin__lut( 2 | input [0:0] a0 3 | , input [0:0] a1 4 | ); 5 | begin 6 | constMin__lut = { a0 | a1, 1'b0 }; 7 | end 8 | endfunction 9 | -------------------------------------------------------------------------------- /src/main/resources/Verilog/b2/constOne_.vl: -------------------------------------------------------------------------------- 1 | function [1:0] constOne__lut( 2 | input [0:0] a0 3 | , input [0:0] a1 4 | ); 5 | begin 6 | constOne__lut = { 1'b0, a0 | a1 }; 7 | end 8 | endfunction 9 | -------------------------------------------------------------------------------- /src/main/resources/Verilog/b2/constZero_.vl: -------------------------------------------------------------------------------- 1 | function [1:0] constZero__lut( 2 | input [0:0] a0 3 | , input [0:0] a1 4 | ); 5 | wire [0:0] x0; 6 | begin 7 | x0 = a0 | a1; 8 | constZero__lut = { x0, x0 }; 9 | end 10 | endfunction 11 | -------------------------------------------------------------------------------- /src/main/resources/Verilog/b2/isEqual_0.vl: -------------------------------------------------------------------------------- 1 | function [1:0] isEqual_0_lut( 2 | input [0:0] a0 3 | , input [0:0] a1 4 | ); 5 | begin 6 | isEqual_0_lut = { a0 ^ a1, a0 & a1 }; 7 | end 8 | endfunction 9 | -------------------------------------------------------------------------------- /src/main/resources/Verilog/b2/isGreater_0.vl: -------------------------------------------------------------------------------- 1 | function [1:0] isGreater_0_lut( 2 | input [0:0] a0 3 | , input [0:0] a1 4 | ); 5 | begin 6 | isGreater_0_lut = { a0 , !a0 & a1 }; 7 | end 8 | endfunction 9 | -------------------------------------------------------------------------------- /src/main/resources/Verilog/b2/isLess_0.vl: -------------------------------------------------------------------------------- 1 | function [1:0] isLess_0_lut( 2 | input [0:0] a0 3 | , input [0:0] a1 4 | ); 5 | begin 6 | isLess_0_lut = { a1, a0 & !a1 }; 7 | end 8 | endfunction 9 | -------------------------------------------------------------------------------- /src/main/resources/Verilog/b2/isMin_0.vl: -------------------------------------------------------------------------------- 1 | function [1:0] isMin_0_lut( 2 | input [0:0] a0 3 | , input [0:0] a1 4 | ); 5 | begin 6 | isMin_0_lut = { a1, a0 & !a1 }; 7 | end 8 | endfunction 9 | -------------------------------------------------------------------------------- /src/main/resources/Verilog/b2/isNegative_0.vl: -------------------------------------------------------------------------------- 1 | function [1:0] isNegative_0_lut( 2 | input [0:0] a0 3 | , input [0:0] a1 4 | ); 5 | begin 6 | isNegative_0_lut = { a1, a0 & !a1 }; 7 | end 8 | endfunction 9 | -------------------------------------------------------------------------------- /src/main/resources/Verilog/b2/isOne_0.vl: -------------------------------------------------------------------------------- 1 | function [1:0] isOne_0_lut( 2 | input [0:0] a0 3 | , input [0:0] a1 4 | ); 5 | begin 6 | isOne_0_lut = { a0 , !a0 & a1 }; 7 | end 8 | endfunction 9 | -------------------------------------------------------------------------------- /src/main/resources/Verilog/b2/isPositive_0.vl: -------------------------------------------------------------------------------- 1 | function [1:0] isPositive_0_lut( 2 | input [0:0] a0 3 | , input [0:0] a1 4 | ); 5 | begin 6 | isPositive_0_lut = { a0 , !a0 & a1 }; 7 | end 8 | endfunction 9 | -------------------------------------------------------------------------------- /src/main/resources/Verilog/b2/isZero_0.vl: -------------------------------------------------------------------------------- 1 | function [1:0] isZero_0_lut( 2 | input [0:0] a0 3 | , input [0:0] a1 4 | ); 5 | begin 6 | isZero_0_lut = { a0 ^ a1, a0 & a1 }; 7 | end 8 | endfunction 9 | -------------------------------------------------------------------------------- /src/main/resources/Verilog/b2/merge.vl: -------------------------------------------------------------------------------- 1 | reg [0:0] x; 2 | 3 | function [1:0] merge__1( 4 | input [0:0] a0 5 | , input [0:0] a1 6 | , input [0:0] b0 7 | , input [0:0] b1 8 | ); 9 | begin 10 | x = (a0 | a1) & (b0 | b1); 11 | merge__1 = { a0 | b0, a1 | b1 }; 12 | end 13 | endfunction 14 | -------------------------------------------------------------------------------- /src/main/resources/Verilog/b2/neg_0.vl: -------------------------------------------------------------------------------- 1 | function [1:0] neg_0_lut( 2 | input [0:0] a0 3 | , input [0:0] a1 4 | ); 5 | begin 6 | neg_0_lut = { a1, a0 }; 7 | end 8 | endfunction 9 | -------------------------------------------------------------------------------- /src/main/resources/Verilog/b2/notEqual_0.vl: -------------------------------------------------------------------------------- 1 | function [1:0] notEqual_0_lut( 2 | input [0:0] a0 3 | , input [0:0] a1 4 | ); 5 | begin 6 | notEqual_0_lut = { a0 & a1, a0 ^ a1 }; 7 | end 8 | endfunction 9 | -------------------------------------------------------------------------------- /src/main/resources/Verilog/b2/notGreater_0.vl: -------------------------------------------------------------------------------- 1 | function [1:0] notGreater_0_lut( 2 | input [0:0] a0 3 | , input [0:0] a1 4 | ); 5 | begin 6 | notGreater_0_lut = { !a0 & a1, a0 }; 7 | end 8 | endfunction 9 | -------------------------------------------------------------------------------- /src/main/resources/Verilog/b2/notLess_0.vl: -------------------------------------------------------------------------------- 1 | function [1:0] notLess_0_lut( 2 | input [0:0] a0 3 | , input [0:0] a1 4 | ); 5 | begin 6 | notLess_0_lut = { a0 & !a1, a1 }; 7 | end 8 | endfunction 9 | -------------------------------------------------------------------------------- /src/main/resources/Verilog/b2/notNegative_0.vl: -------------------------------------------------------------------------------- 1 | function [1:0] notNegative_0_lut( 2 | input [0:0] a0 3 | , input [0:0] a1 4 | ); 5 | begin 6 | notNegative_0_lut = { a0 & !a1, a1 }; 7 | end 8 | endfunction 9 | -------------------------------------------------------------------------------- /src/main/resources/Verilog/b2/notPositive_0.vl: -------------------------------------------------------------------------------- 1 | function [1:0] notPositive_0_lut( 2 | input [0:0] a0 3 | , input [0:0] a1 4 | ); 5 | begin 6 | notPositive_0_lut = { !a0 & a1, a0 }; 7 | end 8 | endfunction 9 | -------------------------------------------------------------------------------- /src/main/resources/Verilog/b2/notZero_0.vl: -------------------------------------------------------------------------------- 1 | function [1:0] notZero_0_lut( 2 | input [0:0] a0 3 | , input [0:0] a1 4 | ); 5 | begin 6 | notZero_0_lut = { a0 & a1, a0 ^ a1 }; 7 | end 8 | endfunction 9 | -------------------------------------------------------------------------------- /src/main/resources/Verilog/b2/not_0.vl: -------------------------------------------------------------------------------- 1 | function [1:0] not_0_lut( 2 | input [0:0] a0 3 | , input [0:0] a1 4 | ); 5 | begin 6 | not_0_lut = (a0 ^ a1) ? { a1, a0 } : 2'b00; 7 | end 8 | endfunction 9 | -------------------------------------------------------------------------------- /src/main/resources/Verilog/b2/nullifyFalse_.vl: -------------------------------------------------------------------------------- 1 | function [1:0] nullifyFalse__lut( 2 | input [0:0] c0 3 | , input [0:0] c1 4 | , input [0:0] v0 5 | , input [0:0] v1 6 | ); 7 | wire [0:0] x0; 8 | begin 9 | x0 = c0 & !c1; 10 | nullifyFalse__lut = { x0 & v0, x1 & v1 }; 11 | end 12 | endfunction 13 | -------------------------------------------------------------------------------- /src/main/resources/Verilog/b2/nullifyTrue_.vl: -------------------------------------------------------------------------------- 1 | function [1:0] nullifyTrue__lut( 2 | input [0:0] c0 3 | , input [0:0] c1 4 | , input [0:0] v0 5 | , input [0:0] v1 6 | ); 7 | wire [0:0] x0; 8 | begin 9 | x0 = !c0 & c1; 10 | nullifyTrue__lut = { x0 & v0, x1 & v1 }; 11 | end 12 | endfunction 13 | -------------------------------------------------------------------------------- /src/main/resources/Verilog/b3/constMin_.vl: -------------------------------------------------------------------------------- 1 | function [1:0] constMin__lut( 2 | input [0:0] a0 3 | , input [0:0] a1 4 | , input [0:0] a2 5 | ); 6 | begin 7 | constMin__lut = { a0 | a1 | a2, 1'b0, 1'b0 }; 8 | end 9 | endfunction 10 | -------------------------------------------------------------------------------- /src/main/resources/Verilog/b3/constOne_.vl: -------------------------------------------------------------------------------- 1 | function [1:0] constOne__lut( 2 | input [0:0] a0 3 | , input [0:0] a1 4 | , input [0:0] a2 5 | ); 6 | begin 7 | constOne__lut = { 1'b0, 1'b0, a0 | a1 | a2 }; 8 | end 9 | endfunction 10 | -------------------------------------------------------------------------------- /src/main/resources/Verilog/b3/constZero_.vl: -------------------------------------------------------------------------------- 1 | function [1:0] constZero__lut( 2 | input [0:0] a0 3 | , input [0:0] a1 4 | , input [0:0] a2 5 | ); 6 | begin 7 | constZero__lut = { 1'b0, a0 | a1 | a2, 1'b0 }; 8 | end 9 | endfunction 10 | -------------------------------------------------------------------------------- /src/main/resources/Verilog/b3/isEqual_0.vl: -------------------------------------------------------------------------------- 1 | function [1:0] isEqual_0_lut( 2 | input [0:0] a0 3 | , input [0:0] a1 4 | , input [0:0] a2 5 | ); 6 | begin 7 | isEqual_0_lut = { a0 | a2, 1'b0, a1 }; 8 | end 9 | endfunction 10 | -------------------------------------------------------------------------------- /src/main/resources/Verilog/b3/isGreater_0.vl: -------------------------------------------------------------------------------- 1 | function [1:0] isGreater_0_lut( 2 | input [0:0] a0 3 | , input [0:0] a1 4 | , input [0:0] a2 5 | ); 6 | begin 7 | isGreater_0_lut = { a1 | a0, 1'b0, a2 }; 8 | end 9 | endfunction 10 | -------------------------------------------------------------------------------- /src/main/resources/Verilog/b3/isLess_0.vl: -------------------------------------------------------------------------------- 1 | function [1:0] isLess_0_lut( 2 | input [0:0] a0 3 | , input [0:0] a1 4 | , input [0:0] a2 5 | ); 6 | begin 7 | isLess_0_lut = { a1 | a2, 1'b0, a0 }; 8 | end 9 | endfunction 10 | -------------------------------------------------------------------------------- /src/main/resources/Verilog/b3/isMin_0.vl: -------------------------------------------------------------------------------- 1 | function [1:0] isMin_0_lut( 2 | input [0:0] a0 3 | , input [0:0] a1 4 | , input [0:0] a2 5 | ); 6 | begin 7 | isMin_0_lut = { a1 | a2, 1'b0, a0 }; 8 | end 9 | endfunction 10 | -------------------------------------------------------------------------------- /src/main/resources/Verilog/b3/isNegative_0.vl: -------------------------------------------------------------------------------- 1 | function [1:0] isNegative_0_lut( 2 | input [0:0] a0 3 | , input [0:0] a1 4 | , input [0:0] a2 5 | ); 6 | begin 7 | isNegative_0_lut = { a1 | a2, 1'b0, a0 }; 8 | end 9 | endfunction 10 | -------------------------------------------------------------------------------- /src/main/resources/Verilog/b3/isOne_0.vl: -------------------------------------------------------------------------------- 1 | function [1:0] isOne_0_lut( 2 | input [0:0] a0 3 | , input [0:0] a1 4 | , input [0:0] a2 5 | ); 6 | begin 7 | isOne_0_lut = { a1 | a0, 1'b0, a2 }; 8 | end 9 | endfunction 10 | -------------------------------------------------------------------------------- /src/main/resources/Verilog/b3/isPositive_0.vl: -------------------------------------------------------------------------------- 1 | function [1:0] isPositive_0_lut( 2 | input [0:0] a0 3 | , input [0:0] a1 4 | , input [0:0] a2 5 | ); 6 | begin 7 | isPositive_0_lut = { a1 | a0, 1'b0, a2 }; 8 | end 9 | endfunction 10 | -------------------------------------------------------------------------------- /src/main/resources/Verilog/b3/isZero_0.vl: -------------------------------------------------------------------------------- 1 | function [1:0] isZero_0_lut( 2 | input [0:0] a0 3 | , input [0:0] a1 4 | , input [0:0] a2 5 | ); 6 | begin 7 | isZero_0_lut = { a0 | a2, 1'b0, a1 }; 8 | end 9 | endfunction 10 | -------------------------------------------------------------------------------- /src/main/resources/Verilog/b3/merge.vl: -------------------------------------------------------------------------------- 1 | reg [0:0] x; 2 | 3 | function [1:0] merge__1( 4 | input [0:0] a0 5 | , input [0:0] a1 6 | , input [0:0] a2 7 | , input [0:0] b0 8 | , input [0:0] b1 9 | , input [0:0] b2 10 | ); 11 | begin 12 | x = (a0 | a1 | a2) & (b0 | b1 | b2); 13 | merge__1 = { a0 | b0, a1 | b1, a2 | b2 }; 14 | end 15 | endfunction 16 | -------------------------------------------------------------------------------- /src/main/resources/Verilog/b3/neg_0.vl: -------------------------------------------------------------------------------- 1 | function [1:0] neg_0_lut( 2 | input [0:0] a0 3 | , input [0:0] a1 4 | , input [0:0] a2 5 | ); 6 | begin 7 | neg_0_lut = { a2, a1, a0 }; 8 | end 9 | endfunction 10 | -------------------------------------------------------------------------------- /src/main/resources/Verilog/b3/notEqual_0.vl: -------------------------------------------------------------------------------- 1 | function [1:0] notEqual_0_lut( 2 | input [0:0] a0 3 | , input [0:0] a1 4 | , input [0:0] a2 5 | ); 6 | begin 7 | notEqual_0_lut = { a1, 1'b0, a0 | a2 }; 8 | end 9 | endfunction 10 | -------------------------------------------------------------------------------- /src/main/resources/Verilog/b3/notGreater_0.vl: -------------------------------------------------------------------------------- 1 | function [1:0] notGreater_0_lut( 2 | input [0:0] a0 3 | , input [0:0] a1 4 | , input [0:0] a2 5 | ); 6 | begin 7 | notGreater_0_lut = { a2, 1'b0, a1 | a0 }; 8 | end 9 | endfunction 10 | -------------------------------------------------------------------------------- /src/main/resources/Verilog/b3/notLess_0.vl: -------------------------------------------------------------------------------- 1 | function [1:0] notLess_0_lut( 2 | input [0:0] a0 3 | , input [0:0] a1 4 | , input [0:0] a2 5 | ); 6 | begin 7 | notLess_0_lut = { a0, 1'b0, a1 | a2 }; 8 | end 9 | endfunction 10 | -------------------------------------------------------------------------------- /src/main/resources/Verilog/b3/notNegative_0.vl: -------------------------------------------------------------------------------- 1 | function [1:0] notNegative_0_lut( 2 | input [0:0] a0 3 | , input [0:0] a1 4 | , input [0:0] a2 5 | ); 6 | begin 7 | notNegative_0_lut = { a0, 1'b0, a1 | a2 }; 8 | end 9 | endfunction 10 | -------------------------------------------------------------------------------- /src/main/resources/Verilog/b3/notPositive_0.vl: -------------------------------------------------------------------------------- 1 | function [1:0] notPositive_0_lut( 2 | input [0:0] a0 3 | , input [0:0] a1 4 | , input [0:0] a2 5 | ); 6 | begin 7 | notPositive_0_lut = { a2, 1'b0, a1 | a0 }; 8 | end 9 | endfunction 10 | -------------------------------------------------------------------------------- /src/main/resources/Verilog/b3/notZero_0.vl: -------------------------------------------------------------------------------- 1 | function [1:0] notZero_0_lut( 2 | input [0:0] a0 3 | , input [0:0] a1 4 | , input [0:0] a2 5 | ); 6 | begin 7 | notZero_0_lut = { a1, 1'b0, a0 | a2 }; 8 | end 9 | endfunction 10 | -------------------------------------------------------------------------------- /src/main/resources/Verilog/b3/not_0.vl: -------------------------------------------------------------------------------- 1 | function [1:0] not_0_lut( 2 | input [0:0] a0 3 | , input [0:0] a1 4 | , input [0:0] a2 5 | ); 6 | begin 7 | not_0_lut = { a2, 1'b0, a0 }; 8 | end 9 | endfunction 10 | -------------------------------------------------------------------------------- /src/main/resources/Verilog/b3/nullifyFalse_.vl: -------------------------------------------------------------------------------- 1 | function [1:0] nullifyFalse__lut( 2 | input [0:0] c0 3 | , input [0:0] c1 4 | , input [0:0] c2 5 | , input [0:0] v0 6 | , input [0:0] v1 7 | , input [0:0] v2 8 | ); 9 | begin 10 | nullifyFalse__lut = { c0 & v0, c0 & v1, c0 & v2 }; 11 | end 12 | endfunction 13 | -------------------------------------------------------------------------------- /src/main/resources/Verilog/b3/nullifyTrue_.vl: -------------------------------------------------------------------------------- 1 | function [1:0] nullifyTrue__lut( 2 | input [0:0] c0 3 | , input [0:0] c1 4 | , input [0:0] c2 5 | , input [0:0] v0 6 | , input [0:0] v1 7 | , input [0:0] v2 8 | ); 9 | begin 10 | nullifyTrue__lut = { c2 & v0, c2 & v1, c2 & v2 }; 11 | end 12 | endfunction 13 | -------------------------------------------------------------------------------- /src/main/resources/syntax/diagram/ConstFuncExpr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iotaledger-archive/qupla/13af581737d3f3f36944f268817295d5e0f78c94/src/main/resources/syntax/diagram/ConstFuncExpr.png -------------------------------------------------------------------------------- /src/main/resources/syntax/diagram/ConstNumber.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iotaledger-archive/qupla/13af581737d3f3f36944f268817295d5e0f78c94/src/main/resources/syntax/diagram/ConstNumber.png -------------------------------------------------------------------------------- /src/main/resources/syntax/diagram/ConstSubExpr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iotaledger-archive/qupla/13af581737d3f3f36944f268817295d5e0f78c94/src/main/resources/syntax/diagram/ConstSubExpr.png -------------------------------------------------------------------------------- /src/main/resources/syntax/diagram/ConstTypeName.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iotaledger-archive/qupla/13af581737d3f3f36944f268817295d5e0f78c94/src/main/resources/syntax/diagram/ConstTypeName.png -------------------------------------------------------------------------------- /src/main/resources/syntax/diagram/ExecStmt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iotaledger-archive/qupla/13af581737d3f3f36944f268817295d5e0f78c94/src/main/resources/syntax/diagram/ExecStmt.png -------------------------------------------------------------------------------- /src/main/resources/syntax/diagram/FieldExpr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iotaledger-archive/qupla/13af581737d3f3f36944f268817295d5e0f78c94/src/main/resources/syntax/diagram/FieldExpr.png -------------------------------------------------------------------------------- /src/main/resources/syntax/diagram/LutEntry.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iotaledger-archive/qupla/13af581737d3f3f36944f268817295d5e0f78c94/src/main/resources/syntax/diagram/LutEntry.png -------------------------------------------------------------------------------- /src/main/resources/syntax/diagram/NameExpr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iotaledger-archive/qupla/13af581737d3f3f36944f268817295d5e0f78c94/src/main/resources/syntax/diagram/NameExpr.png -------------------------------------------------------------------------------- /src/main/resources/syntax/diagram/QuplaSource.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iotaledger-archive/qupla/13af581737d3f3f36944f268817295d5e0f78c94/src/main/resources/syntax/diagram/QuplaSource.png -------------------------------------------------------------------------------- /src/main/resources/syntax/diagram/SizeofExpr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iotaledger-archive/qupla/13af581737d3f3f36944f268817295d5e0f78c94/src/main/resources/syntax/diagram/SizeofExpr.png -------------------------------------------------------------------------------- /src/main/resources/syntax/diagram/SubExpr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iotaledger-archive/qupla/13af581737d3f3f36944f268817295d5e0f78c94/src/main/resources/syntax/diagram/SubExpr.png -------------------------------------------------------------------------------- /src/main/resources/syntax/diagram/TritStructDef.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iotaledger-archive/qupla/13af581737d3f3f36944f268817295d5e0f78c94/src/main/resources/syntax/diagram/TritStructDef.png -------------------------------------------------------------------------------- /src/main/resources/syntax/diagram/TritVectorDef.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iotaledger-archive/qupla/13af581737d3f3f36944f268817295d5e0f78c94/src/main/resources/syntax/diagram/TritVectorDef.png -------------------------------------------------------------------------------- /src/main/resources/syntax/diagram/VectorExpr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iotaledger-archive/qupla/13af581737d3f3f36944f268817295d5e0f78c94/src/main/resources/syntax/diagram/VectorExpr.png -------------------------------------------------------------------------------- /src/main/resources/syntax/diagram/affectExpr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iotaledger-archive/qupla/13af581737d3f3f36944f268817295d5e0f78c94/src/main/resources/syntax/diagram/affectExpr.png -------------------------------------------------------------------------------- /src/main/resources/syntax/diagram/assignExpr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iotaledger-archive/qupla/13af581737d3f3f36944f268817295d5e0f78c94/src/main/resources/syntax/diagram/assignExpr.png -------------------------------------------------------------------------------- /src/main/resources/syntax/diagram/bitLiteral.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iotaledger-archive/qupla/13af581737d3f3f36944f268817295d5e0f78c94/src/main/resources/syntax/diagram/bitLiteral.png -------------------------------------------------------------------------------- /src/main/resources/syntax/diagram/bool.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iotaledger-archive/qupla/13af581737d3f3f36944f268817295d5e0f78c94/src/main/resources/syntax/diagram/bool.png -------------------------------------------------------------------------------- /src/main/resources/syntax/diagram/concatExpr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iotaledger-archive/qupla/13af581737d3f3f36944f268817295d5e0f78c94/src/main/resources/syntax/diagram/concatExpr.png -------------------------------------------------------------------------------- /src/main/resources/syntax/diagram/condExpr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iotaledger-archive/qupla/13af581737d3f3f36944f268817295d5e0f78c94/src/main/resources/syntax/diagram/condExpr.png -------------------------------------------------------------------------------- /src/main/resources/syntax/diagram/constExpr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iotaledger-archive/qupla/13af581737d3f3f36944f268817295d5e0f78c94/src/main/resources/syntax/diagram/constExpr.png -------------------------------------------------------------------------------- /src/main/resources/syntax/diagram/constFactor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iotaledger-archive/qupla/13af581737d3f3f36944f268817295d5e0f78c94/src/main/resources/syntax/diagram/constFactor.png -------------------------------------------------------------------------------- /src/main/resources/syntax/diagram/constTerm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iotaledger-archive/qupla/13af581737d3f3f36944f268817295d5e0f78c94/src/main/resources/syntax/diagram/constTerm.png -------------------------------------------------------------------------------- /src/main/resources/syntax/diagram/entityAlias.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iotaledger-archive/qupla/13af581737d3f3f36944f268817295d5e0f78c94/src/main/resources/syntax/diagram/entityAlias.png -------------------------------------------------------------------------------- /src/main/resources/syntax/diagram/envExpr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iotaledger-archive/qupla/13af581737d3f3f36944f268817295d5e0f78c94/src/main/resources/syntax/diagram/envExpr.png -------------------------------------------------------------------------------- /src/main/resources/syntax/diagram/float.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iotaledger-archive/qupla/13af581737d3f3f36944f268817295d5e0f78c94/src/main/resources/syntax/diagram/float.png -------------------------------------------------------------------------------- /src/main/resources/syntax/diagram/funcBody.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iotaledger-archive/qupla/13af581737d3f3f36944f268817295d5e0f78c94/src/main/resources/syntax/diagram/funcBody.png -------------------------------------------------------------------------------- /src/main/resources/syntax/diagram/funcExpr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iotaledger-archive/qupla/13af581737d3f3f36944f268817295d5e0f78c94/src/main/resources/syntax/diagram/funcExpr.png -------------------------------------------------------------------------------- /src/main/resources/syntax/diagram/funcParam.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iotaledger-archive/qupla/13af581737d3f3f36944f268817295d5e0f78c94/src/main/resources/syntax/diagram/funcParam.png -------------------------------------------------------------------------------- /src/main/resources/syntax/diagram/funcSignature.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iotaledger-archive/qupla/13af581737d3f3f36944f268817295d5e0f78c94/src/main/resources/syntax/diagram/funcSignature.png -------------------------------------------------------------------------------- /src/main/resources/syntax/diagram/funcStmt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iotaledger-archive/qupla/13af581737d3f3f36944f268817295d5e0f78c94/src/main/resources/syntax/diagram/funcStmt.png -------------------------------------------------------------------------------- /src/main/resources/syntax/diagram/hexLiteral.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iotaledger-archive/qupla/13af581737d3f3f36944f268817295d5e0f78c94/src/main/resources/syntax/diagram/hexLiteral.png -------------------------------------------------------------------------------- /src/main/resources/syntax/diagram/importStmt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iotaledger-archive/qupla/13af581737d3f3f36944f268817295d5e0f78c94/src/main/resources/syntax/diagram/importStmt.png -------------------------------------------------------------------------------- /src/main/resources/syntax/diagram/integer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iotaledger-archive/qupla/13af581737d3f3f36944f268817295d5e0f78c94/src/main/resources/syntax/diagram/integer.png -------------------------------------------------------------------------------- /src/main/resources/syntax/diagram/joinExpr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iotaledger-archive/qupla/13af581737d3f3f36944f268817295d5e0f78c94/src/main/resources/syntax/diagram/joinExpr.png -------------------------------------------------------------------------------- /src/main/resources/syntax/diagram/lutExpr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iotaledger-archive/qupla/13af581737d3f3f36944f268817295d5e0f78c94/src/main/resources/syntax/diagram/lutExpr.png -------------------------------------------------------------------------------- /src/main/resources/syntax/diagram/lutStmt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iotaledger-archive/qupla/13af581737d3f3f36944f268817295d5e0f78c94/src/main/resources/syntax/diagram/lutStmt.png -------------------------------------------------------------------------------- /src/main/resources/syntax/diagram/mergeExpr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iotaledger-archive/qupla/13af581737d3f3f36944f268817295d5e0f78c94/src/main/resources/syntax/diagram/mergeExpr.png -------------------------------------------------------------------------------- /src/main/resources/syntax/diagram/name.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iotaledger-archive/qupla/13af581737d3f3f36944f268817295d5e0f78c94/src/main/resources/syntax/diagram/name.png -------------------------------------------------------------------------------- /src/main/resources/syntax/diagram/number.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iotaledger-archive/qupla/13af581737d3f3f36944f268817295d5e0f78c94/src/main/resources/syntax/diagram/number.png -------------------------------------------------------------------------------- /src/main/resources/syntax/diagram/postfixExpr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iotaledger-archive/qupla/13af581737d3f3f36944f268817295d5e0f78c94/src/main/resources/syntax/diagram/postfixExpr.png -------------------------------------------------------------------------------- /src/main/resources/syntax/diagram/quplaStmt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iotaledger-archive/qupla/13af581737d3f3f36944f268817295d5e0f78c94/src/main/resources/syntax/diagram/quplaStmt.png -------------------------------------------------------------------------------- /src/main/resources/syntax/diagram/rr-1.58.1777.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iotaledger-archive/qupla/13af581737d3f3f36944f268817295d5e0f78c94/src/main/resources/syntax/diagram/rr-1.58.1777.png -------------------------------------------------------------------------------- /src/main/resources/syntax/diagram/sliceExpr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iotaledger-archive/qupla/13af581737d3f3f36944f268817295d5e0f78c94/src/main/resources/syntax/diagram/sliceExpr.png -------------------------------------------------------------------------------- /src/main/resources/syntax/diagram/stateExpr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iotaledger-archive/qupla/13af581737d3f3f36944f268817295d5e0f78c94/src/main/resources/syntax/diagram/stateExpr.png -------------------------------------------------------------------------------- /src/main/resources/syntax/diagram/templateBody.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iotaledger-archive/qupla/13af581737d3f3f36944f268817295d5e0f78c94/src/main/resources/syntax/diagram/templateBody.png -------------------------------------------------------------------------------- /src/main/resources/syntax/diagram/templateStmt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iotaledger-archive/qupla/13af581737d3f3f36944f268817295d5e0f78c94/src/main/resources/syntax/diagram/templateStmt.png -------------------------------------------------------------------------------- /src/main/resources/syntax/diagram/templateTypeRelation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iotaledger-archive/qupla/13af581737d3f3f36944f268817295d5e0f78c94/src/main/resources/syntax/diagram/templateTypeRelation.png -------------------------------------------------------------------------------- /src/main/resources/syntax/diagram/trit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iotaledger-archive/qupla/13af581737d3f3f36944f268817295d5e0f78c94/src/main/resources/syntax/diagram/trit.png -------------------------------------------------------------------------------- /src/main/resources/syntax/diagram/tritList.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iotaledger-archive/qupla/13af581737d3f3f36944f268817295d5e0f78c94/src/main/resources/syntax/diagram/tritList.png -------------------------------------------------------------------------------- /src/main/resources/syntax/diagram/tritLiteral.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iotaledger-archive/qupla/13af581737d3f3f36944f268817295d5e0f78c94/src/main/resources/syntax/diagram/tritLiteral.png -------------------------------------------------------------------------------- /src/main/resources/syntax/diagram/tritOrBool.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iotaledger-archive/qupla/13af581737d3f3f36944f268817295d5e0f78c94/src/main/resources/syntax/diagram/tritOrBool.png -------------------------------------------------------------------------------- /src/main/resources/syntax/diagram/tryteLiteral.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iotaledger-archive/qupla/13af581737d3f3f36944f268817295d5e0f78c94/src/main/resources/syntax/diagram/tryteLiteral.png -------------------------------------------------------------------------------- /src/main/resources/syntax/diagram/typeExpr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iotaledger-archive/qupla/13af581737d3f3f36944f268817295d5e0f78c94/src/main/resources/syntax/diagram/typeExpr.png -------------------------------------------------------------------------------- /src/main/resources/syntax/diagram/typeInstantiation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iotaledger-archive/qupla/13af581737d3f3f36944f268817295d5e0f78c94/src/main/resources/syntax/diagram/typeInstantiation.png -------------------------------------------------------------------------------- /src/main/resources/syntax/diagram/typeStmt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iotaledger-archive/qupla/13af581737d3f3f36944f268817295d5e0f78c94/src/main/resources/syntax/diagram/typeStmt.png -------------------------------------------------------------------------------- /src/main/resources/syntax/diagram/useStmt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iotaledger-archive/qupla/13af581737d3f3f36944f268817295d5e0f78c94/src/main/resources/syntax/diagram/useStmt.png -------------------------------------------------------------------------------- /src/test/java/org/iota/qupla/qupla/parser/TokenTest.java: -------------------------------------------------------------------------------- 1 | package org.iota.qupla.qupla.parser; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Test; 5 | import org.mockito.Mockito; 6 | 7 | import java.util.concurrent.ThreadLocalRandom; 8 | 9 | /** 10 | * Unit test of {@link Token} class 11 | */ 12 | public class TokenTest { 13 | private static final int TEST_TOKEN_ID = ThreadLocalRandom.current().nextInt(1); 14 | private static final int TEST_SYMBOL = ThreadLocalRandom.current().nextInt(1); 15 | private static final int TEST_COL_NR = ThreadLocalRandom.current().nextInt(1); 16 | private static final String TEST_TEXT = "token text"; 17 | 18 | private final Token underTest = new Token(0, 0, Mockito.mock(QuplaSource.class), -1, -1, ""); 19 | 20 | @Test 21 | public void when_resetId_then_newInstanceExpected() { 22 | // given 23 | Assert.assertNotEquals(TEST_TOKEN_ID, underTest.id); 24 | 25 | // when 26 | Token token = underTest.resetId(TEST_TOKEN_ID); 27 | 28 | // then 29 | Assert.assertNotSame(underTest, token); 30 | Assert.assertEquals(TEST_TOKEN_ID, token.id); 31 | } 32 | 33 | @Test 34 | public void when_resetSymbol_then_newInstanceExpected() { 35 | // given 36 | Assert.assertNotEquals(TEST_SYMBOL, underTest.symbol); 37 | 38 | // when 39 | Token token = underTest.resetSymbol(TEST_SYMBOL); 40 | 41 | // then 42 | Assert.assertNotSame(underTest, token); 43 | Assert.assertEquals(TEST_SYMBOL, token.symbol); 44 | } 45 | 46 | @Test 47 | public void when_resetText_then_newInstanceExpected() { 48 | // given 49 | Assert.assertNotEquals(TEST_TEXT, underTest.text); 50 | 51 | // when 52 | Token token = underTest.resetText(TEST_TEXT); 53 | 54 | // then 55 | Assert.assertNotSame(underTest, token); 56 | Assert.assertEquals(TEST_TEXT, token.text); 57 | } 58 | 59 | @Test 60 | public void when_resetText2_then_newInstanceExpected() { 61 | // given 62 | Assert.assertNotEquals(TEST_TEXT, underTest.text); 63 | 64 | // when 65 | Token token = underTest.resetText(TEST_TEXT, TEST_TOKEN_ID, TEST_COL_NR); 66 | 67 | // then 68 | Assert.assertNotSame(underTest, token); 69 | Assert.assertEquals(TEST_TEXT, token.text); 70 | } 71 | } 72 | --------------------------------------------------------------------------------