├── .gitattributes ├── .github └── workflows │ └── maven.yml ├── .gitignore ├── .gitmodules ├── .idea ├── .gitignore ├── LanguageServersSettings.xml ├── artifacts │ └── mindcode_compiler_jar.xml ├── codeStyles │ └── codeStyleConfig.xml ├── compiler.xml ├── encodings.xml ├── inspectionProfiles │ ├── Markdown.xml │ ├── Nullness.xml │ ├── Pre_commit.xml │ ├── Project_Default.xml │ └── profiles_settings.xml ├── jarRepositories.xml ├── misc.xml ├── modules.xml └── uiDesigner.xml ├── .mvn └── wrapper │ ├── MavenWrapperDownloader.java │ ├── maven-wrapper.jar │ └── maven-wrapper.properties ├── CHANGELOG.markdown ├── CONTRIBUTING.markdown ├── Dockerfile ├── IDEAS.markdown ├── LICENSE ├── Procfile ├── README.markdown ├── SYNTAX.markdown ├── annotations ├── pom.xml └── src │ └── main │ └── java │ └── info │ └── teksol │ └── annotations │ ├── AstNode.java │ ├── BaseClass.java │ └── processor │ └── AstNodeAnnotationProcessor.java ├── bin ├── build ├── dbconsole ├── deploy ├── mindcode ├── mindcode.bat ├── run-local ├── run-local.ps1 └── webapp.bat ├── compiler ├── pom.xml └── src │ ├── main │ ├── java │ │ └── info │ │ │ └── teksol │ │ │ └── mc │ │ │ ├── Version.java │ │ │ ├── common │ │ │ ├── CompilerOutput.java │ │ │ ├── InputFile.java │ │ │ ├── InputFiles.java │ │ │ ├── PositionFormatter.java │ │ │ ├── SourceElement.java │ │ │ ├── SourcePosition.java │ │ │ └── TextFilePosition.java │ │ │ ├── emulator │ │ │ ├── AbstractMindustryObject.java │ │ │ ├── MindustryObject.java │ │ │ ├── MindustryString.java │ │ │ ├── MindustryVariable.java │ │ │ ├── blocks │ │ │ │ ├── Memory.java │ │ │ │ ├── MessageBlock.java │ │ │ │ ├── MindustryBlock.java │ │ │ │ └── graphics │ │ │ │ │ ├── GraphicsBuffer.java │ │ │ │ │ ├── LogicDisplay.java │ │ │ │ │ └── TransformationMatrix.java │ │ │ └── processor │ │ │ │ ├── Assertion.java │ │ │ │ ├── ExecutionException.java │ │ │ │ ├── ExecutionFlag.java │ │ │ │ ├── MindustryVariables.java │ │ │ │ ├── Processor.java │ │ │ │ └── TextBuffer.java │ │ │ ├── evaluator │ │ │ ├── Color.java │ │ │ ├── ConditionEvaluator.java │ │ │ ├── ExpressionEvaluator.java │ │ │ ├── ExpressionValue.java │ │ │ ├── LogicCondition.java │ │ │ ├── LogicOperation.java │ │ │ ├── LogicReadable.java │ │ │ └── LogicWritable.java │ │ │ ├── messages │ │ │ ├── AbstractMessageEmitter.java │ │ │ ├── AbstractMessageLogger.java │ │ │ ├── CompilerMessage.java │ │ │ ├── ERR.java │ │ │ ├── ExpectedMessages.java │ │ │ ├── ListMessageLogger.java │ │ │ ├── MessageConsumer.java │ │ │ ├── MessageEmitter.java │ │ │ ├── MessageLevel.java │ │ │ ├── MessageLogger.java │ │ │ ├── MindcodeMessage.java │ │ │ ├── SourcePositionTranslator.java │ │ │ ├── TimingMessage.java │ │ │ ├── ToolMessage.java │ │ │ ├── TranslatingMessageConsumer.java │ │ │ └── WARN.java │ │ │ ├── mindcode │ │ │ ├── compiler │ │ │ │ ├── CallType.java │ │ │ │ ├── CompilationPhase.java │ │ │ │ ├── CompilerContext.java │ │ │ │ ├── DataType.java │ │ │ │ ├── InstructionCounter.java │ │ │ │ ├── MindcodeCompiler.java │ │ │ │ ├── MindcodeErrorListener.java │ │ │ │ ├── MindcodeErrorStrategy.java │ │ │ │ ├── MindcodeInternalError.java │ │ │ │ ├── Modifier.java │ │ │ │ ├── RequirementsProcessor.java │ │ │ │ ├── antlr │ │ │ │ │ ├── LexerParser.java │ │ │ │ │ ├── MindcodeLexer.g4 │ │ │ │ │ ├── MindcodeLexer.interp │ │ │ │ │ ├── MindcodeLexer.java │ │ │ │ │ ├── MindcodeLexer.tokens │ │ │ │ │ ├── MindcodeParser.g4 │ │ │ │ │ ├── MindcodeParser.interp │ │ │ │ │ ├── MindcodeParser.java │ │ │ │ │ ├── MindcodeParser.tokens │ │ │ │ │ ├── MindcodeParserBaseListener.java │ │ │ │ │ ├── MindcodeParserBaseVisitor.java │ │ │ │ │ ├── MindcodeParserListener.java │ │ │ │ │ ├── MindcodeParserVisitor.java │ │ │ │ │ └── MissingSemicolonException.java │ │ │ │ ├── ast │ │ │ │ │ ├── AbstractAstIndentedPrinter.java │ │ │ │ │ ├── AstBuilder.java │ │ │ │ │ ├── AstBuilderContext.java │ │ │ │ │ ├── ParserAbort.java │ │ │ │ │ └── nodes │ │ │ │ │ │ ├── AstAllocation.java │ │ │ │ │ │ ├── AstAllocations.java │ │ │ │ │ │ ├── AstArray.java │ │ │ │ │ │ ├── AstArrayAccess.java │ │ │ │ │ │ ├── AstAssignment.java │ │ │ │ │ │ ├── AstBaseMindcodeNode.java │ │ │ │ │ │ ├── AstBreakStatement.java │ │ │ │ │ │ ├── AstBuiltInIdentifier.java │ │ │ │ │ │ ├── AstCaseAlternative.java │ │ │ │ │ │ ├── AstCaseExpression.java │ │ │ │ │ │ ├── AstCodeBlock.java │ │ │ │ │ │ ├── AstContinueStatement.java │ │ │ │ │ │ ├── AstDeclaration.java │ │ │ │ │ │ ├── AstDirectiveDeclare.java │ │ │ │ │ │ ├── AstDirectiveSet.java │ │ │ │ │ │ ├── AstDirectiveValue.java │ │ │ │ │ │ ├── AstDocComment.java │ │ │ │ │ │ ├── AstEnhancedComment.java │ │ │ │ │ │ ├── AstExpression.java │ │ │ │ │ │ ├── AstExpressionList.java │ │ │ │ │ │ ├── AstExternalParameters.java │ │ │ │ │ │ ├── AstForEachLoopStatement.java │ │ │ │ │ │ ├── AstFormattableLiteral.java │ │ │ │ │ │ ├── AstFormattablePlaceholder.java │ │ │ │ │ │ ├── AstFragment.java │ │ │ │ │ │ ├── AstFunctionArgument.java │ │ │ │ │ │ ├── AstFunctionCall.java │ │ │ │ │ │ ├── AstFunctionDeclaration.java │ │ │ │ │ │ ├── AstFunctionParameter.java │ │ │ │ │ │ ├── AstIdentifier.java │ │ │ │ │ │ ├── AstIfBranch.java │ │ │ │ │ │ ├── AstIfExpression.java │ │ │ │ │ │ ├── AstIteratedForLoopStatement.java │ │ │ │ │ │ ├── AstIterator.java │ │ │ │ │ │ ├── AstIteratorsValuesGroup.java │ │ │ │ │ │ ├── AstKeyword.java │ │ │ │ │ │ ├── AstLabeledStatement.java │ │ │ │ │ │ ├── AstLiteral.java │ │ │ │ │ │ ├── AstLiteralBinary.java │ │ │ │ │ │ ├── AstLiteralBoolean.java │ │ │ │ │ │ ├── AstLiteralChar.java │ │ │ │ │ │ ├── AstLiteralColor.java │ │ │ │ │ │ ├── AstLiteralDecimal.java │ │ │ │ │ │ ├── AstLiteralEscape.java │ │ │ │ │ │ ├── AstLiteralFloat.java │ │ │ │ │ │ ├── AstLiteralHexadecimal.java │ │ │ │ │ │ ├── AstLiteralNamedColor.java │ │ │ │ │ │ ├── AstLiteralNull.java │ │ │ │ │ │ ├── AstLiteralNumeric.java │ │ │ │ │ │ ├── AstLiteralString.java │ │ │ │ │ │ ├── AstMemberAccess.java │ │ │ │ │ │ ├── AstMindcodeNode.java │ │ │ │ │ │ ├── AstMlogBlock.java │ │ │ │ │ │ ├── AstMlogComment.java │ │ │ │ │ │ ├── AstMlogInstruction.java │ │ │ │ │ │ ├── AstMlogParameters.java │ │ │ │ │ │ ├── AstMlogStatement.java │ │ │ │ │ │ ├── AstMlogToken.java │ │ │ │ │ │ ├── AstMlogVariable.java │ │ │ │ │ │ ├── AstModule.java │ │ │ │ │ │ ├── AstModuleDeclaration.java │ │ │ │ │ │ ├── AstNodeScope.java │ │ │ │ │ │ ├── AstOperatorBinary.java │ │ │ │ │ │ ├── AstOperatorIncDec.java │ │ │ │ │ │ ├── AstOperatorTernary.java │ │ │ │ │ │ ├── AstOperatorUnary.java │ │ │ │ │ │ ├── AstParameter.java │ │ │ │ │ │ ├── AstParentheses.java │ │ │ │ │ │ ├── AstProgram.java │ │ │ │ │ │ ├── AstPropertyAccess.java │ │ │ │ │ │ ├── AstQualifiedIdentifier.java │ │ │ │ │ │ ├── AstRange.java │ │ │ │ │ │ ├── AstRangedForLoopStatement.java │ │ │ │ │ │ ├── AstRemoteParameters.java │ │ │ │ │ │ ├── AstRequire.java │ │ │ │ │ │ ├── AstRequireFile.java │ │ │ │ │ │ ├── AstRequireLibrary.java │ │ │ │ │ │ ├── AstReturnStatement.java │ │ │ │ │ │ ├── AstStatement.java │ │ │ │ │ │ ├── AstStatementList.java │ │ │ │ │ │ ├── AstSubarray.java │ │ │ │ │ │ ├── AstVariableModifier.java │ │ │ │ │ │ ├── AstVariableSpecification.java │ │ │ │ │ │ ├── AstVariablesDeclaration.java │ │ │ │ │ │ ├── AstWhileLoopStatement.java │ │ │ │ │ │ └── ExternalStorage.java │ │ │ │ ├── astcontext │ │ │ │ │ ├── AstContext.java │ │ │ │ │ ├── AstContextType.java │ │ │ │ │ └── AstSubcontextType.java │ │ │ │ ├── callgraph │ │ │ │ │ ├── CallGraph.java │ │ │ │ │ ├── CallGraphCreator.java │ │ │ │ │ ├── CallGraphCreatorContext.java │ │ │ │ │ ├── FunctionDefinitions.java │ │ │ │ │ └── MindcodeFunction.java │ │ │ │ ├── evaluator │ │ │ │ │ ├── CompileTimeEvaluator.java │ │ │ │ │ ├── CompileTimeEvaluatorContext.java │ │ │ │ │ ├── ExpressionValue.java │ │ │ │ │ ├── IntermediateValue.java │ │ │ │ │ ├── Result.java │ │ │ │ │ └── ValueType.java │ │ │ │ ├── functions │ │ │ │ │ ├── AbstractHandler.java │ │ │ │ │ ├── BaseFunctionMapper.java │ │ │ │ │ ├── DeprecatedPropertyHandler.java │ │ │ │ │ ├── FunctionHandler.java │ │ │ │ │ ├── FunctionMapper.java │ │ │ │ │ ├── FunctionMapperContext.java │ │ │ │ │ ├── InvalidMetadataException.java │ │ │ │ │ ├── MessageFunctionHandler.java │ │ │ │ │ ├── MultiplexedFunctionHandler.java │ │ │ │ │ ├── PropertyHandler.java │ │ │ │ │ ├── SampleGenerator.java │ │ │ │ │ ├── SelectorFunction.java │ │ │ │ │ ├── StandardFunctionHandler.java │ │ │ │ │ ├── StandardPropertyHandler.java │ │ │ │ │ ├── UbindFunctionHandler.java │ │ │ │ │ └── VariableArityFunctionHandler.java │ │ │ │ ├── generation │ │ │ │ │ ├── AbstractBuilder.java │ │ │ │ │ ├── AbstractStandaloneBuilder.java │ │ │ │ │ ├── CodeAssembler.java │ │ │ │ │ ├── CodeAssemblerContext.java │ │ │ │ │ ├── CodeGenerator.java │ │ │ │ │ ├── CodeGeneratorContext.java │ │ │ │ │ ├── LoopStack.java │ │ │ │ │ ├── ReturnStack.java │ │ │ │ │ ├── StackTracker.java │ │ │ │ │ ├── builders │ │ │ │ │ │ ├── AbstractFunctionBuilder.java │ │ │ │ │ │ ├── AbstractLoopBuilder.java │ │ │ │ │ │ ├── AssignmentsBuilder.java │ │ │ │ │ │ ├── BreakContinueStatementsBuilder.java │ │ │ │ │ │ ├── BuiltinFunctionAssertsBuilder.java │ │ │ │ │ │ ├── BuiltinFunctionMlogBuilder.java │ │ │ │ │ │ ├── BuiltinFunctionTextOutputBuilder.java │ │ │ │ │ │ ├── BuiltinFunctionVarargsBuilder.java │ │ │ │ │ │ ├── CaseExpressionsBuilder.java │ │ │ │ │ │ ├── DeclarationsBuilder.java │ │ │ │ │ │ ├── ForEachLoopStatementsBuilder.java │ │ │ │ │ │ ├── FunctionCallsBuilder.java │ │ │ │ │ │ ├── FunctionDeclarationsBuilder.java │ │ │ │ │ │ ├── IdentifiersBuilder.java │ │ │ │ │ │ ├── IfExpressionsBuilder.java │ │ │ │ │ │ ├── IteratedForLoopStatementsBuilder.java │ │ │ │ │ │ ├── LiteralsBuilder.java │ │ │ │ │ │ ├── MemberAccessBuilder.java │ │ │ │ │ │ ├── MlogBlocksBuilder.java │ │ │ │ │ │ ├── OperatorsBuilder.java │ │ │ │ │ │ ├── RangedForLoopStatementsBuilder.java │ │ │ │ │ │ ├── StandardFunctionCallsBuilder.java │ │ │ │ │ │ ├── StatementListsBuilder.java │ │ │ │ │ │ └── WhileLoopStatementsBuilder.java │ │ │ │ │ └── variables │ │ │ │ │ │ ├── AbstractArrayStore.java │ │ │ │ │ │ ├── ArrayStore.java │ │ │ │ │ │ ├── CompoundValueStore.java │ │ │ │ │ │ ├── ExternalArray.java │ │ │ │ │ │ ├── ExternalCachedVariable.java │ │ │ │ │ │ ├── ExternalVariable.java │ │ │ │ │ │ ├── FormattableContent.java │ │ │ │ │ │ ├── FunctionArgument.java │ │ │ │ │ │ ├── FunctionContext.java │ │ │ │ │ │ ├── FunctionParameter.java │ │ │ │ │ │ ├── GlobalContext.java │ │ │ │ │ │ ├── HeapTracker.java │ │ │ │ │ │ ├── IdentifierFunctionArgument.java │ │ │ │ │ │ ├── InputFunctionArgument.java │ │ │ │ │ │ ├── InternalArray.java │ │ │ │ │ │ ├── LocalContext.java │ │ │ │ │ │ ├── MissingFunctionArgument.java │ │ │ │ │ │ ├── MissingValue.java │ │ │ │ │ │ ├── NameCreator.java │ │ │ │ │ │ ├── OptimizerContext.java │ │ │ │ │ │ ├── OutputFunctionArgument.java │ │ │ │ │ │ ├── ProcessorStorage.java │ │ │ │ │ │ ├── Property.java │ │ │ │ │ │ ├── RecursiveContext.java │ │ │ │ │ │ ├── RemoteVariable.java │ │ │ │ │ │ ├── StandardNameCreator.java │ │ │ │ │ │ ├── StructuredValueStore.java │ │ │ │ │ │ ├── ValueStore.java │ │ │ │ │ │ ├── VariableScope.java │ │ │ │ │ │ ├── Variables.java │ │ │ │ │ │ └── VariablesContext.java │ │ │ │ ├── optimization │ │ │ │ │ ├── AbstractOptimizer.java │ │ │ │ │ ├── ArrayOptimizer.java │ │ │ │ │ ├── BaseOptimizer.java │ │ │ │ │ ├── CaseExpressionOptimizer.java │ │ │ │ │ ├── CaseSwitcher.java │ │ │ │ │ ├── DataFlowOptimizer.java │ │ │ │ │ ├── DataFlowVariableStates.java │ │ │ │ │ ├── DeadCodeEliminator.java │ │ │ │ │ ├── DebugPrinter.java │ │ │ │ │ ├── DiffDebugPrinter.java │ │ │ │ │ ├── ExpressionOptimizer.java │ │ │ │ │ ├── FunctionInliner.java │ │ │ │ │ ├── IfExpressionOptimizer.java │ │ │ │ │ ├── JumpNormalizer.java │ │ │ │ │ ├── JumpOptimizer.java │ │ │ │ │ ├── JumpStraightening.java │ │ │ │ │ ├── JumpThreading.java │ │ │ │ │ ├── LoopHoisting.java │ │ │ │ │ ├── LoopOptimizer.java │ │ │ │ │ ├── LoopUnroller.java │ │ │ │ │ ├── NullDebugPrinter.java │ │ │ │ │ ├── Optimization.java │ │ │ │ │ ├── OptimizationAction.java │ │ │ │ │ ├── OptimizationContext.java │ │ │ │ │ ├── OptimizationCoordinator.java │ │ │ │ │ ├── OptimizationLevel.java │ │ │ │ │ ├── OptimizationPhase.java │ │ │ │ │ ├── OptimizationResult.java │ │ │ │ │ ├── Optimizer.java │ │ │ │ │ ├── OptimizerExpressionEvaluator.java │ │ │ │ │ ├── OptimizerMessage.java │ │ │ │ │ ├── PrintMerger.java │ │ │ │ │ ├── ReturnOptimizer.java │ │ │ │ │ ├── SingleStepEliminator.java │ │ │ │ │ ├── StackOptimizer.java │ │ │ │ │ ├── TempVariableEliminator.java │ │ │ │ │ ├── UnreachableCodeEliminator.java │ │ │ │ │ └── cases │ │ │ │ │ │ ├── AbstractSegmentConfigurationGenerator.java │ │ │ │ │ │ ├── CaseSwitcherConfigurations.java │ │ │ │ │ │ ├── CombinatorialSegmentConfigurationGenerator.java │ │ │ │ │ │ ├── Partition.java │ │ │ │ │ │ ├── Segment.java │ │ │ │ │ │ ├── SegmentConfiguration.java │ │ │ │ │ │ ├── SegmentConfigurationGenerator.java │ │ │ │ │ │ ├── SegmentType.java │ │ │ │ │ │ └── Targets.java │ │ │ │ ├── postprocess │ │ │ │ │ ├── LogicInstructionArrayExpander.java │ │ │ │ │ ├── LogicInstructionLabelResolver.java │ │ │ │ │ └── LogicInstructionPrinter.java │ │ │ │ └── preprocess │ │ │ │ │ ├── DirectivePreprocessor.java │ │ │ │ │ └── PreprocessorContext.java │ │ │ ├── decompiler │ │ │ │ ├── InstructionExpression.java │ │ │ │ ├── MlogDecompiler.java │ │ │ │ ├── MlogExpression.java │ │ │ │ ├── MlogParser.java │ │ │ │ ├── MlogVariable.java │ │ │ │ ├── OperationExpression.java │ │ │ │ └── ParsedMlog.java │ │ │ └── logic │ │ │ │ ├── arguments │ │ │ │ ├── AbstractArgument.java │ │ │ │ ├── ArgumentType.java │ │ │ │ ├── AssertOp.java │ │ │ │ ├── AssertionType.java │ │ │ │ ├── Condition.java │ │ │ │ ├── GenericArgument.java │ │ │ │ ├── LogicAddress.java │ │ │ │ ├── LogicArgument.java │ │ │ │ ├── LogicArray.java │ │ │ │ ├── LogicBoolean.java │ │ │ │ ├── LogicBuiltIn.java │ │ │ │ ├── LogicBuiltinConst.java │ │ │ │ ├── LogicColor.java │ │ │ │ ├── LogicKeyword.java │ │ │ │ ├── LogicLabel.java │ │ │ │ ├── LogicLiteral.java │ │ │ │ ├── LogicNamedColor.java │ │ │ │ ├── LogicNull.java │ │ │ │ ├── LogicNumber.java │ │ │ │ ├── LogicParameter.java │ │ │ │ ├── LogicString.java │ │ │ │ ├── LogicToken.java │ │ │ │ ├── LogicValue.java │ │ │ │ ├── LogicVariable.java │ │ │ │ ├── LogicVoid.java │ │ │ │ ├── Operation.java │ │ │ │ ├── ValueMutability.java │ │ │ │ └── arrays │ │ │ │ │ ├── AbstractArrayConstructor.java │ │ │ │ │ ├── ArrayConstructor.java │ │ │ │ │ ├── ArraySize1Constructor.java │ │ │ │ │ ├── ArraySize2Or3Constructor.java │ │ │ │ │ ├── ExternalArrayConstructor.java │ │ │ │ │ ├── InlinedArrayConstructor.java │ │ │ │ │ └── RegularArrayConstructor.java │ │ │ │ ├── instructions │ │ │ │ ├── AbstractInstruction.java │ │ │ │ ├── ArrayAccessInstruction.java │ │ │ │ ├── ArrayOrganization.java │ │ │ │ ├── BaseInstruction.java │ │ │ │ ├── BaseInstructionProcessor.java │ │ │ │ ├── BaseResultInstruction.java │ │ │ │ ├── CallInstruction.java │ │ │ │ ├── CallRecInstruction.java │ │ │ │ ├── CallingInstruction.java │ │ │ │ ├── CommentInstruction.java │ │ │ │ ├── ConditionalInstruction.java │ │ │ │ ├── ContextfulInstructionCreator.java │ │ │ │ ├── ContextlessInstructionCreator.java │ │ │ │ ├── ControlInstruction.java │ │ │ │ ├── CustomInstruction.java │ │ │ │ ├── DrawInstruction.java │ │ │ │ ├── DrawflushInstruction.java │ │ │ │ ├── EmptyInstruction.java │ │ │ │ ├── EndInstruction.java │ │ │ │ ├── FormatInstruction.java │ │ │ │ ├── GetlinkInstruction.java │ │ │ │ ├── InstructionComment.java │ │ │ │ ├── InstructionInfo.java │ │ │ │ ├── InstructionProcessor.java │ │ │ │ ├── InstructionProcessorFactory.java │ │ │ │ ├── JumpInstruction.java │ │ │ │ ├── LabelInstruction.java │ │ │ │ ├── LabeledInstruction.java │ │ │ │ ├── LocalContextfulInstructionsCreator.java │ │ │ │ ├── LogicInstruction.java │ │ │ │ ├── LogicResultInstruction.java │ │ │ │ ├── LookupInstruction.java │ │ │ │ ├── MindustryInstructionProcessor7.java │ │ │ │ ├── MindustryInstructionProcessor8.java │ │ │ │ ├── MlogInstruction.java │ │ │ │ ├── MultiCallInstruction.java │ │ │ │ ├── MultiJumpInstruction.java │ │ │ │ ├── MultiLabelInstruction.java │ │ │ │ ├── MultiTargetInstruction.java │ │ │ │ ├── OpInstruction.java │ │ │ │ ├── PackColorInstruction.java │ │ │ │ ├── PopInstruction.java │ │ │ │ ├── PrintCharInstruction.java │ │ │ │ ├── PrintInstruction.java │ │ │ │ ├── PrintflushInstruction.java │ │ │ │ ├── PrintingInstruction.java │ │ │ │ ├── PushInstruction.java │ │ │ │ ├── PushOrPopInstruction.java │ │ │ │ ├── ReadArrInstruction.java │ │ │ │ ├── ReadInstruction.java │ │ │ │ ├── RemarkInstruction.java │ │ │ │ ├── ReturnInstruction.java │ │ │ │ ├── ReturnRecInstruction.java │ │ │ │ ├── SelectInstruction.java │ │ │ │ ├── SensorInstruction.java │ │ │ │ ├── SetAddressInstruction.java │ │ │ │ ├── SetInstruction.java │ │ │ │ ├── SideEffects.java │ │ │ │ ├── StopInstruction.java │ │ │ │ ├── UnpackColorInstruction.java │ │ │ │ ├── WriteArrInstruction.java │ │ │ │ └── WriteInstruction.java │ │ │ │ ├── mimex │ │ │ │ ├── BlockType.java │ │ │ │ ├── ContentType.java │ │ │ │ ├── Icons.java │ │ │ │ ├── Item.java │ │ │ │ ├── LAccess.java │ │ │ │ ├── LVar.java │ │ │ │ ├── Liquid.java │ │ │ │ ├── MindustryContent.java │ │ │ │ ├── MindustryMetadata.java │ │ │ │ ├── NamedColor.java │ │ │ │ ├── NamedContent.java │ │ │ │ ├── Unit.java │ │ │ │ ├── UnitCommand.java │ │ │ │ ├── UnknownContent.java │ │ │ │ └── Weather.java │ │ │ │ └── opcodes │ │ │ │ ├── FunctionMapping.java │ │ │ │ ├── InstructionParameterType.java │ │ │ │ ├── KeywordCategory.java │ │ │ │ ├── MindustryOpcodeVariants.java │ │ │ │ ├── NamedParameter.java │ │ │ │ ├── Opcode.java │ │ │ │ ├── OpcodeVariant.java │ │ │ │ ├── ProcessorEdition.java │ │ │ │ ├── ProcessorVersion.java │ │ │ │ └── TypedArgument.java │ │ │ ├── profile │ │ │ ├── BuiltinEvaluation.java │ │ │ ├── CompilerProfile.java │ │ │ ├── DirectiveProcessor.java │ │ │ ├── FileReferences.java │ │ │ ├── FinalCodeOutput.java │ │ │ ├── GenerationGoal.java │ │ │ ├── GlobalCompilerProfile.java │ │ │ ├── LocalCompilerProfile.java │ │ │ ├── Remarks.java │ │ │ ├── RuntimeChecks.java │ │ │ ├── SortCategory.java │ │ │ ├── SyntacticMode.java │ │ │ └── options │ │ │ │ ├── BooleanCompilerOptionValue.java │ │ │ │ ├── CompilerOption.java │ │ │ │ ├── CompilerOptionFactory.java │ │ │ │ ├── CompilerOptionValue.java │ │ │ │ ├── CompilerOptions.java │ │ │ │ ├── DebuggingOptions.java │ │ │ │ ├── DoubleCompilerOptionValue.java │ │ │ │ ├── EnumCompilerOptionValue.java │ │ │ │ ├── EnvironmentOptions.java │ │ │ │ ├── InputOutputOptions.java │ │ │ │ ├── IntOptimizationLevelCompilerValue.java │ │ │ │ ├── IntegerCompilerOptionValue.java │ │ │ │ ├── MlogFormatOptions.java │ │ │ │ ├── OptimizationLevelCompilerValue.java │ │ │ │ ├── OptimizationOptionValue.java │ │ │ │ ├── OptimizationOptions.java │ │ │ │ ├── OptionAvailability.java │ │ │ │ ├── OptionCategory.java │ │ │ │ ├── OptionMultiplicity.java │ │ │ │ ├── OptionScope.java │ │ │ │ ├── RunOptions.java │ │ │ │ ├── SchematicOptions.java │ │ │ │ ├── SemanticStability.java │ │ │ │ ├── StringCompilerOptionValue.java │ │ │ │ ├── Target.java │ │ │ │ └── TargetCompilerOptionValue.java │ │ │ └── util │ │ │ ├── CRC64.java │ │ │ ├── CollectionUtils.java │ │ │ ├── EnumUtils.java │ │ │ ├── Indenter.java │ │ │ ├── IntRange.java │ │ │ ├── Lazy.java │ │ │ ├── ObjectUtils.java │ │ │ ├── StringSimilarity.java │ │ │ ├── StringUtils.java │ │ │ ├── TraceFile.java │ │ │ ├── Tuple2.java │ │ │ └── Tuple2Nullable.java │ ├── resources-filtered │ │ └── info │ │ │ └── teksol │ │ │ └── mc │ │ │ └── mindcode.properties │ └── resources │ │ ├── META-INF │ │ └── services │ │ │ └── javax.annotation.processing.Processor │ │ └── library │ │ ├── arrays.mnd │ │ ├── blocks.mnd │ │ ├── compatibility.mnd │ │ ├── graphics.mnd │ │ ├── math.mnd │ │ ├── printing.mnd │ │ └── units.mnd │ └── test │ ├── java │ └── info │ │ └── teksol │ │ └── mc │ │ ├── VersionTest.java │ │ ├── mindcode │ │ ├── CompatibilityLibraryGeneratorTest.java │ │ ├── DocGeneratorTest.java │ │ ├── DocValidatorTest.java │ │ ├── SystemLibraryTest.java │ │ ├── compiler │ │ │ ├── AbstractTestBase.java │ │ │ ├── MindcodeCompilerTest.java │ │ │ ├── antlr │ │ │ │ ├── AbstractParserTest.java │ │ │ │ └── MindcodeParserTest.java │ │ │ ├── ast │ │ │ │ ├── AbstractAstBuilderTest.java │ │ │ │ ├── AstBuilderTest.java │ │ │ │ └── AstIndentedPrinterTest.java │ │ │ ├── astcontext │ │ │ │ └── AstContextTest.java │ │ │ ├── callgraph │ │ │ │ └── CallGraphCreatorTest.java │ │ │ ├── evaluator │ │ │ │ └── CompileTimeEvaluatorTest.java │ │ │ ├── functions │ │ │ │ ├── AbstractFunctionMapperTest.java │ │ │ │ ├── BaseFunctionMapperTest.java │ │ │ │ ├── FunctionReferenceGeneratorTest.java │ │ │ │ ├── InstructionSamplesTest.java │ │ │ │ └── StandardFunctionHandlerTest.java │ │ │ ├── generation │ │ │ │ ├── AbstractCodeGeneratorTest.java │ │ │ │ ├── CodeGeneratorTest.java │ │ │ │ ├── LoopStackTest.java │ │ │ │ ├── RemoteModulesTest.java │ │ │ │ ├── ReturnStackTest.java │ │ │ │ └── builders │ │ │ │ │ ├── AssignmentsBuilderTest.java │ │ │ │ │ ├── BreakContinueStatementsBuilderTest.java │ │ │ │ │ ├── BuiltinFunctionAssertsBuilderTest.java │ │ │ │ │ ├── BuiltinFunctionMlogBuilderTest.java │ │ │ │ │ ├── BuiltinFunctionTextOutputBuilderTest.java │ │ │ │ │ ├── BuiltinFunctionVarargsBuilderTest.java │ │ │ │ │ ├── CaseExpressionsBuilderTest.java │ │ │ │ │ ├── DeclarationsBuilderTest.java │ │ │ │ │ ├── ForEachLoopStatementsBuilderTest.java │ │ │ │ │ ├── FunctionDeclarationsBuilderTest.java │ │ │ │ │ ├── IdentifiersBuilderTest.java │ │ │ │ │ ├── IfExpressionsBuilderTest.java │ │ │ │ │ ├── IteratedForLoopStatementsBuilderTest.java │ │ │ │ │ ├── LiteralsBuilderTest.java │ │ │ │ │ ├── MemberAccessBuilderTest.java │ │ │ │ │ ├── MlogBlocksBuilderTest.java │ │ │ │ │ ├── OperatorsBuilderTest.java │ │ │ │ │ ├── RangedForLoopStatementsBuilderTest.java │ │ │ │ │ ├── StandardFunctionCallsBuilderTest.java │ │ │ │ │ └── WhileLoopStatementsBuilderTest.java │ │ │ ├── optimization │ │ │ │ ├── AbstractOptimizerTest.java │ │ │ │ ├── ArrayOptimizerTest.java │ │ │ │ ├── BaseOptimizerTest.java │ │ │ │ ├── CaseExpressionOptimizerTest.java │ │ │ │ ├── CaseSwitcherConfigurationGeneratorTest.java │ │ │ │ ├── CaseSwitcherTest.java │ │ │ │ ├── DataFlowOptimizerTest.java │ │ │ │ ├── DeadCodeEliminatorTest.java │ │ │ │ ├── DiffDebugPrinterTest.java │ │ │ │ ├── ExpressionOptimizerTest.java │ │ │ │ ├── FunctionInlinerTest.java │ │ │ │ ├── GeneralOptimizationTest.java │ │ │ │ ├── IfExpressionOptimizerTest.java │ │ │ │ ├── JumpNormalizerTest.java │ │ │ │ ├── JumpOptimizerTest.java │ │ │ │ ├── JumpStraighteningTest.java │ │ │ │ ├── JumpThreadingTest.java │ │ │ │ ├── LoopHoistingTest.java │ │ │ │ ├── LoopOptimizerTest.java │ │ │ │ ├── LoopUnrollerBasicTest.java │ │ │ │ ├── LoopUnrollerFullTest.java │ │ │ │ ├── LoopUnrollerTestBase.java │ │ │ │ ├── OptimizationCoordinatorTest.java │ │ │ │ ├── PrintMergerLogic7Test.java │ │ │ │ ├── PrintMergerTest.java │ │ │ │ ├── ReturnOptimizerTest.java │ │ │ │ ├── SingleStepEliminatorTest.java │ │ │ │ ├── StackOptimizerTest.java │ │ │ │ ├── TempVariableEliminatorTest.java │ │ │ │ └── UnreachableCodeEliminatorTest.java │ │ │ ├── postprocess │ │ │ │ ├── AbstractCodeOutputTest.java │ │ │ │ ├── LogicInstructionArrayExpanderTest.java │ │ │ │ ├── LogicInstructionLabelResolverTest.java │ │ │ │ └── LogicInstructionPrinterTest.java │ │ │ └── preprocess │ │ │ │ ├── DirectivePreprocessorTest.java │ │ │ │ └── PreprocessorContextImpl.java │ │ ├── decompiler │ │ │ └── MlogDecompilerTest.java │ │ ├── logic │ │ │ ├── instructions │ │ │ │ ├── BaseInstructionProcessorTest.java │ │ │ │ └── BaseInstructionTest.java │ │ │ ├── mimex │ │ │ │ └── MindustryMetadataTest.java │ │ │ └── opcodes │ │ │ │ └── MindustryOpcodeVariantsTest.java │ │ └── tests │ │ │ ├── AbstractProcessorTest.java │ │ │ ├── AlgorithmsSymbolicLabelsTest.java │ │ │ ├── AlgorithmsTest.java │ │ │ ├── AlgorithmsTestBase.java │ │ │ ├── CaseSwitcherProcessorTest.java │ │ │ ├── CaseSwitcherProcessorTestBase.java │ │ │ ├── CaseSwitcherSymbolicLabelsProcessorTest.java │ │ │ ├── EulerSymbolicLabelsTest.java │ │ │ ├── EulerTest.java │ │ │ ├── OptimizerSymbolicLabelsTest.java │ │ │ ├── OptimizerTest.java │ │ │ ├── ProcessorSymbolicLabelsTest.java │ │ │ ├── ProcessorTest.java │ │ │ ├── ProcessorTestBase.java │ │ │ └── interceptor │ │ │ ├── AbstractInterceptorTest.java │ │ │ └── InterceptorTest.java │ │ ├── profile │ │ └── CompilerProfileTest.java │ │ └── util │ │ ├── CollectionUtilsTest.java │ │ ├── IntRangeTest.java │ │ └── StringSimilarityTest.java │ └── resources │ ├── info │ └── teksol │ │ └── mc │ │ └── mindcode │ │ └── tests │ │ ├── algorithms │ │ ├── AlgorithmsSymbolicLabelsTest.txt │ │ ├── AlgorithmsTest.txt │ │ ├── array-reversion-symbolic.log │ │ ├── array-reversion.log │ │ ├── array-reversion.mnd │ │ ├── base64-decode-symbolic.log │ │ ├── base64-decode.log │ │ ├── base64-decode.mnd │ │ ├── bubble-sort-symbolic.log │ │ ├── bubble-sort.log │ │ ├── bubble-sort.mnd │ │ ├── compute-recursive-fibonacci-symbolic.log │ │ ├── compute-recursive-fibonacci.log │ │ ├── compute-recursive-fibonacci.mnd │ │ ├── compute-sum-of-primes-symbolic.log │ │ ├── compute-sum-of-primes.log │ │ ├── compute-sum-of-primes.mnd │ │ ├── digit-counts-symbolic.log │ │ ├── digit-counts.log │ │ ├── digit-counts.mnd │ │ ├── heap-sort-symbolic.log │ │ ├── heap-sort.log │ │ ├── heap-sort.mnd │ │ ├── insert-sort-symbolic.log │ │ ├── insert-sort.log │ │ ├── insert-sort.mnd │ │ ├── memory-read-write-symbolic.log │ │ ├── memory-read-write.log │ │ ├── memory-read-write.mnd │ │ ├── pascal-triangle-symbolic.log │ │ ├── pascal-triangle.log │ │ ├── pascal-triangle.mnd │ │ ├── quick-sort-symbolic.log │ │ ├── quick-sort.log │ │ ├── quick-sort.mnd │ │ ├── select-sort-symbolic.log │ │ ├── select-sort.log │ │ ├── select-sort.mnd │ │ ├── storage-display-symbolic.log │ │ ├── storage-display.log │ │ └── storage-display.mnd │ │ ├── caseswitcher │ │ ├── CaseSwitcherConfigurationGeneratorTest.txt │ │ ├── CaseSwitcherProcessorTest.txt │ │ ├── CaseSwitcherSymbolicLabelsProcessorTest.txt │ │ ├── distinct-0-none-limit-0-symbolic.log │ │ ├── distinct-0-none-limit-0.log │ │ ├── distinct-0-none-limit-110-symbolic.log │ │ ├── distinct-0-none-limit-110.log │ │ ├── distinct-0-none-limit-200-symbolic.log │ │ ├── distinct-0-none-limit-200.log │ │ ├── distinct-0-none-limit-500-symbolic.log │ │ ├── distinct-0-none-limit-500.log │ │ ├── distinct-0-none.mnd │ │ ├── distinct-0-none.txt │ │ ├── distinct-1-zero-limit-0-symbolic.log │ │ ├── distinct-1-zero-limit-0.log │ │ ├── distinct-1-zero-limit-110-symbolic.log │ │ ├── distinct-1-zero-limit-110.log │ │ ├── distinct-1-zero-limit-200-symbolic.log │ │ ├── distinct-1-zero-limit-200.log │ │ ├── distinct-1-zero-limit-500-symbolic.log │ │ ├── distinct-1-zero-limit-500.log │ │ ├── distinct-1-zero.mnd │ │ ├── distinct-1-zero.txt │ │ ├── distinct-2-null-limit-0-symbolic.log │ │ ├── distinct-2-null-limit-0.log │ │ ├── distinct-2-null-limit-110-symbolic.log │ │ ├── distinct-2-null-limit-110.log │ │ ├── distinct-2-null-limit-200-symbolic.log │ │ ├── distinct-2-null-limit-200.log │ │ ├── distinct-2-null-limit-500-symbolic.log │ │ ├── distinct-2-null-limit-500.log │ │ ├── distinct-2-null.mnd │ │ ├── distinct-2-null.txt │ │ ├── distinct-3-both-limit-0-symbolic.log │ │ ├── distinct-3-both-limit-0.log │ │ ├── distinct-3-both-limit-110-symbolic.log │ │ ├── distinct-3-both-limit-110.log │ │ ├── distinct-3-both-limit-200-symbolic.log │ │ ├── distinct-3-both-limit-200.log │ │ ├── distinct-3-both-limit-500-symbolic.log │ │ ├── distinct-3-both-limit-500.log │ │ ├── distinct-3-both.mnd │ │ ├── distinct-3-both.txt │ │ ├── distinct-4-max-limit-0-symbolic.log │ │ ├── distinct-4-max-limit-0.log │ │ ├── distinct-4-max-limit-110-symbolic.log │ │ ├── distinct-4-max-limit-110.log │ │ ├── distinct-4-max-limit-200-symbolic.log │ │ ├── distinct-4-max-limit-200.log │ │ ├── distinct-4-max-limit-500-symbolic.log │ │ ├── distinct-4-max-limit-500.log │ │ ├── distinct-4-max.mnd │ │ ├── distinct-4-max.txt │ │ ├── homogenous-0-none-limit-0-symbolic.log │ │ ├── homogenous-0-none-limit-0.log │ │ ├── homogenous-0-none-limit-100-symbolic.log │ │ ├── homogenous-0-none-limit-100.log │ │ ├── homogenous-0-none-limit-500-symbolic.log │ │ ├── homogenous-0-none-limit-500.log │ │ ├── homogenous-0-none-limit-60-symbolic.log │ │ ├── homogenous-0-none-limit-60.log │ │ ├── homogenous-0-none.mnd │ │ ├── homogenous-0-none.txt │ │ ├── homogenous-1-zero-limit-0-symbolic.log │ │ ├── homogenous-1-zero-limit-0.log │ │ ├── homogenous-1-zero-limit-100-symbolic.log │ │ ├── homogenous-1-zero-limit-100.log │ │ ├── homogenous-1-zero-limit-500-symbolic.log │ │ ├── homogenous-1-zero-limit-500.log │ │ ├── homogenous-1-zero-limit-60-symbolic.log │ │ ├── homogenous-1-zero-limit-60.log │ │ ├── homogenous-1-zero.mnd │ │ ├── homogenous-1-zero.txt │ │ ├── homogenous-2-null-limit-0-symbolic.log │ │ ├── homogenous-2-null-limit-0.log │ │ ├── homogenous-2-null-limit-100-symbolic.log │ │ ├── homogenous-2-null-limit-100.log │ │ ├── homogenous-2-null-limit-500-symbolic.log │ │ ├── homogenous-2-null-limit-500.log │ │ ├── homogenous-2-null-limit-60-symbolic.log │ │ ├── homogenous-2-null-limit-60.log │ │ ├── homogenous-2-null.mnd │ │ ├── homogenous-2-null.txt │ │ ├── homogenous-3-both-limit-0-symbolic.log │ │ ├── homogenous-3-both-limit-0.log │ │ ├── homogenous-3-both-limit-100-symbolic.log │ │ ├── homogenous-3-both-limit-100.log │ │ ├── homogenous-3-both-limit-500-symbolic.log │ │ ├── homogenous-3-both-limit-500.log │ │ ├── homogenous-3-both-limit-60-symbolic.log │ │ ├── homogenous-3-both-limit-60.log │ │ ├── homogenous-3-both.mnd │ │ ├── homogenous-3-both.txt │ │ ├── homogenous-4-max-limit-0-symbolic.log │ │ ├── homogenous-4-max-limit-0.log │ │ ├── homogenous-4-max-limit-100-symbolic.log │ │ ├── homogenous-4-max-limit-100.log │ │ ├── homogenous-4-max-limit-500-symbolic.log │ │ ├── homogenous-4-max-limit-500.log │ │ ├── homogenous-4-max-limit-60-symbolic.log │ │ ├── homogenous-4-max-limit-60.log │ │ ├── homogenous-4-max.mnd │ │ ├── homogenous-4-max.txt │ │ ├── mixed-2-null-limit-0-symbolic.log │ │ ├── mixed-2-null-limit-0.log │ │ ├── mixed-2-null-limit-140-symbolic.log │ │ ├── mixed-2-null-limit-140.log │ │ ├── mixed-2-null-limit-230-symbolic.log │ │ ├── mixed-2-null-limit-230.log │ │ ├── mixed-2-null-limit-500-symbolic.log │ │ ├── mixed-2-null-limit-500.log │ │ ├── mixed-2-null.mnd │ │ └── mixed-2-null.txt │ │ ├── euler │ │ ├── EulerSymbolicLabelsTest.txt │ │ ├── EulerTest.txt │ │ ├── ProjectEulerTest.txt │ │ ├── project-euler-04-symbolic.log │ │ ├── project-euler-04.log │ │ ├── project-euler-04.mnd │ │ ├── project-euler-18-symbolic.log │ │ ├── project-euler-18.log │ │ ├── project-euler-18.mnd │ │ ├── project-euler-26-symbolic.log │ │ ├── project-euler-26.log │ │ ├── project-euler-26.mnd │ │ ├── project-euler-28-symbolic.log │ │ ├── project-euler-28.log │ │ ├── project-euler-28.mnd │ │ ├── project-euler-31-symbolic.log │ │ ├── project-euler-31.log │ │ ├── project-euler-31.mnd │ │ ├── project-euler-31b-symbolic.log │ │ ├── project-euler-31b.log │ │ ├── project-euler-31b.mnd │ │ ├── project-euler-45-symbolic.log │ │ ├── project-euler-45.log │ │ ├── project-euler-45.mnd │ │ ├── project-euler-97-symbolic.log │ │ ├── project-euler-97.log │ │ └── project-euler-97.mnd │ │ ├── optimizer │ │ ├── OptimizerSymbolicLabelsTest.txt │ │ ├── OptimizerTest.txt │ │ ├── breakout-00-symbolic.log │ │ ├── breakout-00.log │ │ ├── breakout-00.mnd │ │ ├── detector-00-symbolic.log │ │ ├── detector-00.log │ │ ├── detector-00.mnd │ │ ├── factory-monitor-00-symbolic.log │ │ ├── factory-monitor-00.log │ │ ├── factory-monitor-00.mnd │ │ ├── factory-monitor-silicon-00-symbolic.log │ │ ├── factory-monitor-silicon-00.log │ │ ├── factory-monitor-silicon-00.mnd │ │ ├── factory-monitor-surge-alloy-00-symbolic.log │ │ ├── factory-monitor-surge-alloy-00.log │ │ ├── factory-monitor-surge-alloy-00.mnd │ │ ├── impact-reactor-logic-00-symbolic.log │ │ ├── impact-reactor-logic-00.log │ │ ├── impact-reactor-logic-00.mnd │ │ ├── instant-overdrive-dome-01-symbolic.log │ │ ├── instant-overdrive-dome-01.log │ │ ├── instant-overdrive-dome-01.mnd │ │ ├── item-counter-00-symbolic.log │ │ ├── item-counter-00.log │ │ ├── item-counter-00.mnd │ │ ├── item-counter-micro-00-symbolic.log │ │ ├── item-counter-micro-00.log │ │ ├── item-counter-micro-00.mnd │ │ ├── item-rate-display-00-symbolic.log │ │ ├── item-rate-display-00.log │ │ ├── item-rate-display-00.mnd │ │ ├── item-rate-meter-00-symbolic.log │ │ ├── item-rate-meter-00.log │ │ ├── item-rate-meter-00.mnd │ │ ├── level-display-00-symbolic.log │ │ ├── level-display-00.log │ │ ├── level-display-00.mnd │ │ ├── level-display-water-cryo-00-symbolic.log │ │ ├── level-display-water-cryo-00.log │ │ ├── level-display-water-cryo-00.mnd │ │ ├── level-meter-00-symbolic.log │ │ ├── level-meter-00.log │ │ ├── level-meter-00.mnd │ │ ├── map-setup-00-symbolic.log │ │ ├── map-setup-00.log │ │ ├── map-setup-00.mnd │ │ ├── mass-driver-monitor-00-symbolic.log │ │ ├── mass-driver-monitor-00.log │ │ ├── mass-driver-monitor-00.mnd │ │ ├── mass-driver-monitor-surge-alloy-00-symbolic.log │ │ ├── mass-driver-monitor-surge-alloy-00.log │ │ ├── mass-driver-monitor-surge-alloy-00.mnd │ │ ├── reactor-control-00-symbolic.log │ │ ├── reactor-control-00.log │ │ ├── reactor-control-00.mnd │ │ ├── reactor-control-battery-level-00-symbolic.log │ │ ├── reactor-control-battery-level-00.log │ │ ├── reactor-control-battery-level-00.mnd │ │ ├── regulator-00-symbolic.log │ │ ├── regulator-00.log │ │ ├── regulator-00.mnd │ │ ├── remote-vault-00-symbolic.log │ │ ├── remote-vault-00.log │ │ ├── remote-vault-00.mnd │ │ ├── storage-display-00-symbolic.log │ │ ├── storage-display-00.log │ │ ├── storage-display-00.mnd │ │ ├── unit-housekeeping-00-symbolic.log │ │ ├── unit-housekeeping-00.log │ │ ├── unit-housekeeping-00.mnd │ │ ├── unit-speed-00-symbolic.log │ │ ├── unit-speed-00.log │ │ ├── unit-speed-00.mnd │ │ ├── unit-transport-00-symbolic.log │ │ ├── unit-transport-00.log │ │ ├── unit-transport-00.mnd │ │ ├── unit-transport-flow-rate-00-symbolic.log │ │ ├── unit-transport-flow-rate-00.log │ │ ├── unit-transport-flow-rate-00.mnd │ │ ├── unit-transport-single-00-symbolic.log │ │ ├── unit-transport-single-00.log │ │ └── unit-transport-single-00.mnd │ │ └── processor │ │ ├── ProcessorSymbolicLabelsTest.txt │ │ ├── ProcessorTest.txt │ │ ├── assignments-in-expressions-symbolic.log │ │ ├── assignments-in-expressions.log │ │ ├── assignments-in-expressions.mnd │ │ ├── complex-case-expression-symbolic.log │ │ ├── complex-case-expression.log │ │ ├── complex-case-expression.mnd │ │ ├── equality-comparisons-symbolic.log │ │ ├── equality-comparisons.log │ │ ├── equality-comparisons.mnd │ │ ├── executes-sort-variables-symbolic.log │ │ ├── executes-sort-variables.log │ │ ├── executes-sort-variables.mnd │ │ ├── expression-evaluation-compile-time-symbolic.log │ │ ├── expression-evaluation-compile-time.log │ │ ├── expression-evaluation-compile-time.mnd │ │ ├── expression-evaluation-runtime-symbolic.log │ │ ├── expression-evaluation-runtime.log │ │ ├── expression-evaluation-runtime.mnd │ │ ├── fixed-bounds-ranged-for-symbolic.log │ │ ├── fixed-bounds-ranged-for.log │ │ ├── fixed-bounds-ranged-for.mnd │ │ ├── for-each-loop-break-continue-symbolic.log │ │ ├── for-each-loop-break-continue.log │ │ ├── for-each-loop-break-continue.mnd │ │ ├── function-inlining-symbolic.log │ │ ├── function-inlining.log │ │ ├── function-inlining.mnd │ │ ├── iterated-for-loop-break-continue-symbolic.log │ │ ├── iterated-for-loop-break-continue.log │ │ ├── iterated-for-loop-break-continue.mnd │ │ ├── loops-in-conditions-symbolic.log │ │ ├── loops-in-conditions.log │ │ ├── loops-in-conditions.mnd │ │ ├── prints-values-symbolic.log │ │ ├── prints-values.log │ │ ├── prints-values.mnd │ │ ├── ranged-for-loop-break-continue-symbolic.log │ │ ├── ranged-for-loop-break-continue.log │ │ ├── ranged-for-loop-break-continue.mnd │ │ ├── recursive-calls-symbolic.log │ │ ├── recursive-calls.log │ │ ├── recursive-calls.mnd │ │ ├── recursive-function-condition-symbolic.log │ │ ├── recursive-function-condition.log │ │ ├── recursive-function-condition.mnd │ │ ├── switched-case-expression-symbolic.log │ │ ├── switched-case-expression.log │ │ ├── switched-case-expression.mnd │ │ ├── while-loop-symbolic.log │ │ ├── while-loop.log │ │ └── while-loop.mnd │ ├── junit-platform.properties │ └── library │ ├── outputs │ ├── arrays-advanced.log │ ├── arrays-advanced.mlog │ ├── arrays-basic.log │ ├── arrays-basic.mlog │ ├── arrays-experimental.log │ ├── arrays-experimental.mlog │ ├── arrays-none.log │ ├── arrays-none.mlog │ ├── arrays.mnd │ ├── blocks-advanced.log │ ├── blocks-advanced.mlog │ ├── blocks-basic.log │ ├── blocks-basic.mlog │ ├── blocks-experimental.log │ ├── blocks-experimental.mlog │ ├── blocks-none.log │ ├── blocks-none.mlog │ ├── blocks.mnd │ ├── graphics-advanced.log │ ├── graphics-advanced.mlog │ ├── graphics-basic.log │ ├── graphics-basic.mlog │ ├── graphics-experimental.log │ ├── graphics-experimental.mlog │ ├── graphics-none.log │ ├── graphics-none.mlog │ ├── graphics.mnd │ ├── math-advanced.log │ ├── math-advanced.mlog │ ├── math-basic.log │ ├── math-basic.mlog │ ├── math-experimental.log │ ├── math-experimental.mlog │ ├── math-none.log │ ├── math-none.mlog │ ├── math.mnd │ ├── printing-advanced.log │ ├── printing-advanced.mlog │ ├── printing-basic.log │ ├── printing-basic.mlog │ ├── printing-experimental.log │ ├── printing-experimental.mlog │ ├── printing-none.log │ ├── printing-none.mlog │ ├── printing.mnd │ ├── units-advanced.log │ ├── units-advanced.mlog │ ├── units-basic.log │ ├── units-basic.mlog │ ├── units-experimental.log │ ├── units-experimental.mlog │ ├── units-none.log │ ├── units-none.mlog │ ├── units.mnd │ └── utils.log │ └── tests │ ├── arrays.mnd │ ├── blocks.mnd │ ├── graphics.mnd │ ├── math.txt │ └── printing.txt ├── doc ├── announcements │ ├── 2021-03-16.markdown │ ├── 2021-03-18.markdown │ ├── 2021-03-27.markdown │ └── 2023-03-29.markdown └── syntax │ ├── FUNCTIONS-60.markdown │ ├── FUNCTIONS-70.markdown │ ├── FUNCTIONS-71.markdown │ ├── FUNCTIONS-80.markdown │ ├── FUNCTIONS-81.markdown │ ├── MINDUSTRY-8.markdown │ ├── MINDUSTRY-TIPS-N-TRICKS.markdown │ ├── PERFORMANCE-TIPS.markdown │ ├── REMOTE-CALLS.markdown │ ├── SCHEMACODE.markdown │ ├── SYNTAX-1-VARIABLES.markdown │ ├── SYNTAX-2-EXPRESSIONS.markdown │ ├── SYNTAX-3-STATEMENTS.markdown │ ├── SYNTAX-4-FUNCTIONS.markdown │ ├── SYNTAX-5-OTHER.markdown │ ├── SYNTAX-6-OPTIMIZATIONS.markdown │ ├── SYNTAX-EXTENSIONS.markdown │ ├── SYNTAX.markdown │ ├── SYSTEM-LIBRARY-ARRAYS.markdown │ ├── SYSTEM-LIBRARY-BLOCKS.markdown │ ├── SYSTEM-LIBRARY-COMPATIBILITY.markdown │ ├── SYSTEM-LIBRARY-GRAPHICS.markdown │ ├── SYSTEM-LIBRARY-MATH.markdown │ ├── SYSTEM-LIBRARY-PRINTING.markdown │ ├── SYSTEM-LIBRARY-UNITS.markdown │ ├── SYSTEM-LIBRARY.markdown │ ├── TOOLS-CMDLINE.markdown │ ├── TOOLS-IDE-INTEGRATION.markdown │ ├── TOOLS-MLOG-DECOMPILER.markdown │ ├── TOOLS-MLOG-WATCHER.markdown │ ├── TOOLS-PROCESSOR-EMULATOR.markdown │ ├── TOOLS-REFRESHER.markdown │ ├── TOOLS-TESTING-TOOL.markdown │ ├── TROUBLESHOOTING.markdown │ └── TUTORIAL-MINDCODE.markdown ├── docker-compose.yaml ├── errors ├── 001-loop-unroller.log ├── 001-loop-unroller.mlog ├── 001-loop-unroller.mnd ├── 002-dfo.log ├── 002-dfo.mlog └── 002-dfo.mnd ├── exttest ├── .gitignore ├── data │ ├── bubble-sort.mnd │ ├── case-distinct-both.mnd │ ├── case-distinct-max.mnd │ ├── case-distinct-none.mnd │ ├── case-distinct-null.mnd │ ├── case-distinct-zero.mnd │ ├── case-homogenous-both.mnd │ ├── case-homogenous-max.mnd │ ├── case-homogenous-none.mnd │ ├── case-homogenous-null.mnd │ ├── case-homogenous-zero.mnd │ ├── case-no-else.mnd │ ├── case-range.mnd │ ├── case-small.mnd │ ├── case-variable.mnd │ ├── heap-sort.mnd │ ├── impact-reactor-logic.mnd │ ├── math.mnd │ ├── printing.mnd │ ├── quick-sort.mnd │ ├── recursion.mnd │ ├── settings.yaml │ └── sum-of-primes.mnd ├── pom.xml └── src │ ├── main │ └── java │ │ └── info │ │ └── teksol │ │ └── mindcode │ │ └── exttest │ │ ├── AbstractTestProgress.java │ │ ├── BasicTestProgress.java │ │ ├── Configuration.java │ │ ├── ConfigurationReader.java │ │ ├── ErrorResult.java │ │ ├── ExecutionFramework.java │ │ ├── ExtendedTests.java │ │ ├── ScreeningTestProgress.java │ │ ├── TestConfiguration.java │ │ ├── TestProgress.java │ │ ├── cases │ │ ├── BaseTestCaseCreator.java │ │ ├── BasicTestCaseExecutor.java │ │ ├── CaseSwitchingTestCaseExecutor.java │ │ ├── TestCaseCreator.java │ │ ├── TestCaseCreatorFull.java │ │ ├── TestCaseCreatorSampled.java │ │ ├── TestCaseCreatorScreening.java │ │ └── TestCaseExecutor.java │ │ ├── forkjoin │ │ ├── ForkJoinFramework.java │ │ └── ForkJoinTestRunner.java │ │ └── threadpool │ │ ├── ThreadPoolFramework.java │ │ └── ThreadPoolRunner.java │ └── test │ ├── java │ └── info │ │ └── teksol │ │ └── mindcode │ │ └── exttest │ │ ├── ExtendedTestsTest.java │ │ └── cases │ │ └── TestCaseCreatorSampledTest.java │ └── resources │ └── junit-platform.properties ├── java └── util │ └── annotations.xml ├── logo.png ├── mvnw ├── mvnw.cmd ├── pom.xml ├── samples ├── .gitignore ├── pom.xml └── src │ ├── main │ ├── java │ │ └── info │ │ │ └── teksol │ │ │ └── mindcode │ │ │ └── samples │ │ │ ├── Sample.java │ │ │ └── Samples.java │ └── resources │ │ └── samples │ │ ├── mindcode │ │ ├── control-multiple-units.mnd │ │ ├── heal-damaged-building.mnd │ │ ├── item-transport.mnd │ │ ├── many-thorium.mnd │ │ ├── mining-drone.mnd │ │ ├── one-thorium.mnd │ │ ├── sum-of-primes.mnd │ │ └── upgrade-conveyors.mnd │ │ └── schematics │ │ ├── detector.sdf │ │ ├── healing-center.sdf │ │ ├── item-transport.sdf │ │ ├── mandelbrot-generator.sdf │ │ ├── on-off-switch.sdf │ │ ├── overdrive-dome-supply.sdf │ │ ├── payload-hub.sdf │ │ ├── regulator.sdf │ │ ├── scrap-to-metaglass-2.sdf │ │ └── worker-recall-station.sdf │ └── test │ ├── java │ └── info │ │ └── teksol │ │ └── mindcode │ │ └── samples │ │ └── SamplesTest.java │ └── resources │ └── junit-platform.properties ├── schemacode ├── pom.xml └── src │ ├── main │ └── java │ │ └── info │ │ └── teksol │ │ └── schemacode │ │ ├── IOConsumer.java │ │ ├── IOSupplier.java │ │ ├── SchemacodeCompiler.java │ │ ├── SchemacodeErrorListener.java │ │ ├── SchematicsDecompiler.java │ │ ├── SchematicsInternalError.java │ │ ├── SchematicsMetadata.java │ │ ├── ast │ │ ├── AstBlock.java │ │ ├── AstBlockReference.java │ │ ├── AstBoolean.java │ │ ├── AstColor.java │ │ ├── AstConfiguration.java │ │ ├── AstConnection.java │ │ ├── AstConnections.java │ │ ├── AstContentsReference.java │ │ ├── AstCoordinates.java │ │ ├── AstDefinition.java │ │ ├── AstDefinitions.java │ │ ├── AstDirection.java │ │ ├── AstItemReference.java │ │ ├── AstLink.java │ │ ├── AstLinkPattern.java │ │ ├── AstLinkPos.java │ │ ├── AstLiquidReference.java │ │ ├── AstProcessor.java │ │ ├── AstProgram.java │ │ ├── AstProgramSnippet.java │ │ ├── AstProgramSnippetFile.java │ │ ├── AstProgramSnippetText.java │ │ ├── AstRgbaValue.java │ │ ├── AstSchemaAttribute.java │ │ ├── AstSchemaItem.java │ │ ├── AstSchematic.java │ │ ├── AstSchematicsBuilder.java │ │ ├── AstStringBlock.java │ │ ├── AstStringConstant.java │ │ ├── AstStringLiteral.java │ │ ├── AstStringRef.java │ │ ├── AstText.java │ │ ├── AstUnitCommandReference.java │ │ ├── AstUnitReference.java │ │ ├── AstVirtual.java │ │ └── MultipartPositionTranslator.java │ │ ├── config │ │ ├── Array.java │ │ ├── BooleanConfiguration.java │ │ ├── ByteArray.java │ │ ├── Configuration.java │ │ ├── DoubleConfiguration.java │ │ ├── EmptyConfiguration.java │ │ ├── FloatConfiguration.java │ │ ├── IntConfiguration.java │ │ ├── LongConfiguration.java │ │ ├── PositionArray.java │ │ ├── TextConfiguration.java │ │ └── UnhandledItem.java │ │ ├── grammar │ │ ├── Schemacode.g4 │ │ ├── Schemacode.interp │ │ ├── Schemacode.tokens │ │ ├── SchemacodeBaseListener.java │ │ ├── SchemacodeBaseVisitor.java │ │ ├── SchemacodeLexer.interp │ │ ├── SchemacodeLexer.java │ │ ├── SchemacodeLexer.tokens │ │ ├── SchemacodeListener.java │ │ ├── SchemacodeParser.java │ │ └── SchemacodeVisitor.java │ │ ├── mindustry │ │ ├── BlockConfiguration.java │ │ ├── Color.java │ │ ├── ConfigurationType.java │ │ ├── ContentConfiguration.java │ │ ├── Direction.java │ │ ├── Implementation.java │ │ ├── ItemConfiguration.java │ │ ├── LiquidConfiguration.java │ │ ├── Position.java │ │ ├── ProcessorConfiguration.java │ │ ├── SchematicsIO.java │ │ ├── UnitCommandConfiguration.java │ │ ├── UnitConfiguration.java │ │ ├── UnitOrBlockConfiguration.java │ │ ├── UnitPlan.java │ │ └── Vector.java │ │ └── schematics │ │ ├── Block.java │ │ ├── BlockOrder.java │ │ ├── BlockPosition.java │ │ ├── BlockPositionMap.java │ │ ├── BlockPositionResolver.java │ │ ├── BridgeSolver.java │ │ ├── Decompiler.java │ │ ├── DirectionLevel.java │ │ ├── Language.java │ │ ├── PowerGridSolver.java │ │ ├── Schematic.java │ │ └── SchematicsBuilder.java │ └── test │ ├── java │ └── info │ │ └── teksol │ │ └── schemacode │ │ ├── AbstractSchematicsTest.java │ │ ├── ast │ │ ├── AstSchematicBuilderTest.java │ │ └── MultipartPositionTranslatorTest.java │ │ ├── mindustry │ │ ├── ImplementationTest.java │ │ └── SchematicsIOTest.java │ │ └── schematics │ │ ├── BlockPositionMapTest.java │ │ ├── BridgeSolverTest.java │ │ ├── DecompilerTest.java │ │ ├── PowerGridSolverTest.java │ │ └── SchematicsBuilderTest.java │ └── resources │ ├── junit-platform.properties │ └── schematics │ ├── detector.msch │ ├── driver-monitor-for-surge-alloy-factory.msch │ ├── factory-monitor-silicon.msch │ ├── factory-monitor-surge-alloy.msch │ ├── factory-monitor.msch │ ├── impact-power-plant.msch │ ├── instant-overdrive-dome.msch │ ├── instant-overdrive-projector.msch │ ├── item-counter.msch │ ├── item-rate-display.msch │ ├── item-rate-meter.msch │ ├── level-display.msch │ ├── level-meter-water+cryo.msch │ ├── level-meter.msch │ ├── mass-driver-monitor.msch │ ├── regulator.msch │ ├── sample.msch │ └── unit-transport-single.msch ├── support └── idea │ ├── settings-filetypes.zip │ ├── settings-tools-linux.zip │ └── settings-tools-windows.zip ├── system.properties ├── toolapp ├── .gitignore ├── pom.xml └── src │ ├── main │ ├── java │ │ └── info │ │ │ └── teksol │ │ │ └── mindcode │ │ │ └── cmdline │ │ │ ├── ActionHandler.java │ │ │ ├── CaseInsensitiveChoices.java │ │ │ ├── CompileMindcodeAction.java │ │ │ ├── CompileSchemacodeAction.java │ │ │ ├── ConsoleMessageLogger.java │ │ │ ├── DecompileMlogAction.java │ │ │ ├── DecompileSchemacodeAction.java │ │ │ ├── ExcerptSpecification.java │ │ │ ├── LowerCaseEnumArgumentType.java │ │ │ ├── Main.java │ │ │ ├── MlogWatcherClient.java │ │ │ └── ProcessingException.java │ └── resources │ │ └── META-INF │ │ └── MANIFEST.MF │ └── test │ ├── java │ └── info │ │ └── teksol │ │ └── mindcode │ │ ├── cmdline │ │ ├── AbstractCommandLineTest.java │ │ ├── CommandLineHelpGeneratorTest.java │ │ ├── CompileMindcodeActionTest.java │ │ ├── CompileSchemacodeActionTest.java │ │ └── DecompileSchemacodeActionTest.java │ │ └── ide │ │ └── idea │ │ └── CreateIdeaSettingsTest.java │ └── resources │ ├── ide │ └── idea │ │ ├── IntelliJ IDEA Global Settings │ │ ├── filetypes │ │ ├── Mindcode.xml │ │ ├── Schema Definition File.xml │ │ └── mlog.xml │ │ ├── installed.txt │ │ ├── tools-linux │ │ └── External Tools.xml │ │ └── tools-windows │ │ └── External Tools.xml │ └── templates │ └── TOOLS-CMDLINE_template.markdown ├── webapp ├── .gitignore ├── pom.xml └── src │ ├── main │ ├── java │ │ └── info │ │ │ └── teksol │ │ │ └── mindcode │ │ │ └── webapp │ │ │ ├── DbMigrator.java │ │ │ ├── DecompilerController.java │ │ │ ├── HomeController.java │ │ │ ├── HomePageData.java │ │ │ ├── MlogDecompilerController.java │ │ │ ├── SchematicsController.java │ │ │ ├── Source.java │ │ │ ├── SourceRepository.java │ │ │ ├── WebappApplication.java │ │ │ └── WebappMessage.java │ └── resources │ │ ├── application.properties │ │ ├── logback.xml │ │ └── templates │ │ ├── common.ftlh │ │ ├── decompiler.ftlh │ │ ├── home.ftlh │ │ ├── mlog-decompiler.ftlh │ │ └── schematic.ftlh │ └── test │ ├── java │ └── info │ │ └── teksol │ │ └── mindcode │ │ └── webapp │ │ ├── WebAppSchematicsBuilderTest.java │ │ └── WebappApplicationTests.java │ └── resources │ ├── application.properties │ └── logback-test.xml └── wide-logo.png /.gitattributes: -------------------------------------------------------------------------------- 1 | mvnw text eol=lf 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Files which don't need to be shared between developers 2 | .idea/dataSources* 3 | .idea/dictionaries 4 | .idea/libraries 5 | .idea/vcs.xml 6 | .idea/workspace.xml 7 | .idea/dbnavigator.xml 8 | .idea/codeStyles/Project.xml 9 | .idea/templateLanguages.xml 10 | 11 | # PostgreSQL cluster data directory 12 | db/cluster 13 | 14 | # Compiled artifacts 15 | Instruction_Samples_*.txt 16 | trace*.txt 17 | scratches/ 18 | out/ 19 | target 20 | tmp 21 | mindcode/src/test/resources/scripts/*.mlog 22 | mindcode/src/test/resources/euler/*.mlog 23 | 24 | # System library log files 25 | mindcode/src/main/resources/library/*.log 26 | mindcode/src/main/resources/library/*.mlog 27 | 28 | 29 | # Other 30 | *.orig 31 | .flattened-pom.xml 32 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "compiler/src/main/resources/mimex"] 2 | path = compiler/src/main/resources/mimex 3 | url = https://github.com/cardillan/mimex-data.git 4 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | -------------------------------------------------------------------------------- /.idea/LanguageServersSettings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /.idea/artifacts/mindcode_compiler_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | $PROJECT_DIR$/out/artifacts/mindcode_compiler_jar 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/codeStyles/codeStyleConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cardillan/mindcode/ed0453b0cd24b5cff4d623923c79bbcc3e3191ba/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.1/apache-maven-3.8.1-bin.zip 2 | wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar 3 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM eclipse-temurin:22 2 | 3 | WORKDIR /srv 4 | 5 | RUN apt update && apt -y install maven 6 | 7 | COPY pom.xml pom.xml 8 | COPY annotations/pom.xml annotations/pom.xml 9 | COPY compiler/pom.xml compiler/pom.xml 10 | COPY exttest/pom.xml exttest/pom.xml 11 | COPY samples/pom.xml samples/pom.xml 12 | COPY schemacode/pom.xml schemacode/pom.xml 13 | COPY toolapp/pom.xml toolapp/pom.xml 14 | COPY webapp/pom.xml webapp/pom.xml 15 | 16 | RUN mvn dependency:go-offline 17 | 18 | COPY . . 19 | 20 | ENV SPRING_DATASOURCE_URL jdbc:postgresql://mindcode-db/mindcode_development 21 | ENV SPRING_DATASOURCE_USERNAME postgres 22 | ENV SPRING_DATASOURCE_PASSWORD pg_password 23 | 24 | # Skip tests because postgres is only available at runtime 25 | RUN mvn install -Dmaven.test.skip 26 | 27 | EXPOSE 8080 28 | 29 | CMD java -classpath `find webapp -type f -name '*.jar' | tr '\n' ':'` info.teksol.mindcode.webapp.WebappApplication 30 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | web: java -Dserver.port=${PORT} -classpath $( find webapp -type f -name '*.jar' | tr '\n' ':' ) info.teksol.mindcode.webapp.WebappApplication 2 | -------------------------------------------------------------------------------- /SYNTAX.markdown: -------------------------------------------------------------------------------- 1 | > [!NOTE] 2 | > Mindcode syntax documentation has been expanded and moved [here](doc/syntax/SYNTAX.markdown). 3 | -------------------------------------------------------------------------------- /annotations/src/main/java/info/teksol/annotations/AstNode.java: -------------------------------------------------------------------------------- 1 | package info.teksol.annotations; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | @Retention(RetentionPolicy.SOURCE) 9 | @Target(ElementType.TYPE) 10 | public @interface AstNode { 11 | boolean printFlat() default false; 12 | } 13 | -------------------------------------------------------------------------------- /annotations/src/main/java/info/teksol/annotations/BaseClass.java: -------------------------------------------------------------------------------- 1 | package info.teksol.annotations; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** Marks a base class used as a supertype for generated subclasses of given category */ 9 | @Retention(RetentionPolicy.SOURCE) 10 | @Target(ElementType.TYPE) 11 | public @interface BaseClass { 12 | String value(); 13 | } 14 | -------------------------------------------------------------------------------- /bin/build: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | $MINDCODE_PATH/mvnw install 4 | -------------------------------------------------------------------------------- /bin/dbconsole: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | exec psql -h localhost -d mindcode_development 3 | -------------------------------------------------------------------------------- /bin/deploy: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | exec git push heroku main:master 3 | -------------------------------------------------------------------------------- /bin/mindcode: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | BASEDIR=$(dirname "$0") 3 | exec java -jar $BASEDIR/../toolapp/target/mindcode.jar "$@" 4 | -------------------------------------------------------------------------------- /bin/mindcode.bat: -------------------------------------------------------------------------------- 1 | @"%JAVA_HOME%\bin\java.exe" -jar %~dp0..\toolapp\target\mindcode.jar %* 2 | -------------------------------------------------------------------------------- /bin/webapp.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal enableDelayedExpansion 3 | pushd %~dp0..\webapp\target 4 | for %%i in (*.jar) do set __CLPATH=..\%%i 5 | cd dependency 6 | for %%i in (*.jar) do set __CLPATH=!__CLPATH!;%%i 7 | "%JAVA_HOME%\bin\java.exe" -classpath !__CLPATH! info.teksol.mindcode.webapp.WebappApplication %* 8 | popd 9 | endlocal 10 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/Version.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | 5 | import java.io.IOException; 6 | import java.io.InputStream; 7 | import java.util.Properties; 8 | 9 | @NullMarked 10 | public class Version { 11 | 12 | public static String getVersion() { 13 | try (InputStream in = Version.class.getResourceAsStream("mindcode.properties")) { 14 | if (in == null) { 15 | return "unknown"; 16 | } 17 | Properties properties = new Properties(); 18 | properties.load(in); 19 | return properties.getProperty("mindcode.version"); 20 | } catch (IOException e) { 21 | throw new RuntimeException("Error obtaining version information", e); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/common/InputFile.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.common; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | 5 | import java.nio.file.Path; 6 | 7 | @NullMarked 8 | public interface InputFile { 9 | int getId(); 10 | 11 | /// @return true if this file is a standalone source (i.e. not loaded from existing file or library 12 | boolean isStandaloneSource(); 13 | 14 | /// @return true if this file is a system library 15 | boolean isLibrary(); 16 | 17 | /// @return source code of this file 18 | String getCode(); 19 | 20 | /// @return path to the file as given when loaded 21 | Path getPath(); 22 | 23 | /// @return relative path to the root of all input files (if applicable) 24 | Path getRelativePath(); 25 | 26 | /// @return absolute, normalized path of the file 27 | String getAbsolutePath(); 28 | 29 | /// @return distinct path for displaying in log files 30 | String getDistinctPath(); 31 | 32 | /// @return distinct title for displaying in log files 33 | String getDistinctTitle(); 34 | } 35 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/common/PositionFormatter.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.common; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | 5 | import java.util.function.Function; 6 | 7 | @FunctionalInterface 8 | @NullMarked 9 | public interface PositionFormatter extends Function { 10 | @Override 11 | default String apply(SourcePosition position) { 12 | return formatPosition(position); 13 | } 14 | 15 | String formatPosition(SourcePosition position); 16 | } 17 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/common/SourceElement.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.common; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | 5 | /// An instance which can be tied to a particular position in the source file. Typically, AST tree 6 | /// nodes are instances of source element, but some other classes can also implement this interface 7 | /// to provide the source position. 8 | @NullMarked 9 | public interface SourceElement { 10 | 11 | /// Provides the input position of the source element corresponding to this object. 12 | /// When the object doesn't have a corresponding source element, it should return 13 | /// `SourcePosition.EMPTY`. 14 | /// 15 | /// @return position of the source element corresponding to this object in the source code 16 | SourcePosition sourcePosition(); 17 | 18 | } 19 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/emulator/AbstractMindustryObject.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.emulator; 2 | 3 | import info.teksol.mc.mindcode.logic.mimex.MindustryContent; 4 | import org.jspecify.annotations.NullMarked; 5 | import org.jspecify.annotations.Nullable; 6 | 7 | import java.util.Objects; 8 | 9 | @NullMarked 10 | public class AbstractMindustryObject implements MindustryObject { 11 | private final String name; 12 | private final int id; 13 | private @Nullable final MindustryContent type; 14 | 15 | public AbstractMindustryObject(String name, int id, @Nullable MindustryContent type) { 16 | this.name = Objects.requireNonNull(name); 17 | this.id = id; 18 | this.type = type; 19 | } 20 | 21 | @Override 22 | public String name() { 23 | return name; 24 | } 25 | 26 | @Override 27 | public String format() { 28 | return name(); 29 | } 30 | 31 | @Override 32 | public int id() { 33 | return id; 34 | } 35 | 36 | @Override 37 | public @Nullable MindustryContent type() { 38 | return type; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/emulator/MindustryString.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.emulator; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | 5 | @NullMarked 6 | public class MindustryString extends AbstractMindustryObject { 7 | 8 | public MindustryString(String name) { 9 | super(name, -1, null); 10 | } 11 | 12 | public String value() { 13 | return name(); 14 | } 15 | 16 | @Override 17 | public boolean equals(Object obj) { 18 | return obj != null && obj.getClass() == this.getClass() && ((MindustryString) obj).name().equals(name()); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/emulator/blocks/MessageBlock.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.emulator.blocks; 2 | 3 | import info.teksol.mc.emulator.processor.TextBuffer; 4 | import info.teksol.mc.mindcode.logic.mimex.MindustryContent; 5 | import info.teksol.mc.mindcode.logic.mimex.MindustryMetadata; 6 | import org.jspecify.annotations.NullMarked; 7 | 8 | @NullMarked 9 | public class MessageBlock extends MindustryBlock { 10 | private final StringBuilder contents = new StringBuilder(); 11 | 12 | public MessageBlock(String name, MindustryContent type) { 13 | super(name, type); 14 | } 15 | 16 | public void printflush(TextBuffer textBuffer) { 17 | textBuffer.printflush(contents); 18 | } 19 | 20 | public static MessageBlock createMessage(MindustryMetadata metadata) { 21 | return new MessageBlock("message", metadata.getExistingBlock("@message")); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/emulator/blocks/MindustryBlock.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.emulator.blocks; 2 | 3 | import info.teksol.mc.emulator.AbstractMindustryObject; 4 | import info.teksol.mc.mindcode.logic.mimex.MindustryContent; 5 | import org.jspecify.annotations.NullMarked; 6 | 7 | import java.util.Objects; 8 | 9 | @NullMarked 10 | public class MindustryBlock extends AbstractMindustryObject { 11 | 12 | public MindustryBlock(String name, MindustryContent type) { 13 | super(name, -1, Objects.requireNonNull(type)); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/emulator/blocks/graphics/TransformationMatrix.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.emulator.blocks.graphics; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | 5 | /// Represents the transformation matrix. Is shared among displays. 6 | /// 7 | /// In Mindustry Logic, the matrix is owned by the processor and applied to whichever display 8 | /// the drawflush is being called. The same needs to be done here. 9 | @NullMarked 10 | public class TransformationMatrix { 11 | } 12 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/evaluator/LogicCondition.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.evaluator; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | 5 | /// Interface representing a Mindustry Logic condition. 6 | @NullMarked 7 | public interface LogicCondition { 8 | boolean evaluate(LogicReadable a, LogicReadable b); 9 | } 10 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/evaluator/LogicOperation.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.evaluator; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | 5 | /// Interface representing a Mindustry Logic operation. 6 | @NullMarked 7 | public interface LogicOperation { 8 | void execute(LogicWritable result, LogicReadable left, LogicReadable right); 9 | } 10 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/evaluator/LogicWritable.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.evaluator; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | 5 | @NullMarked 6 | public interface LogicWritable { 7 | void setDoubleValue(double value); 8 | 9 | void setLongValue(long value); 10 | 11 | void setBooleanValue(boolean value); 12 | } 13 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/messages/MessageConsumer.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.messages; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | 5 | import java.util.function.Consumer; 6 | 7 | /// Represents a class capable of accepting and processing messages generated during the compilation. 8 | /// Default convenience methods are provided for generating various kinds of messages. 9 | /// 10 | /// In the test code, the ExpectedMessages implementation provides mechanisms to validate only the expected messages 11 | /// are generated by the compiler. 12 | /// 13 | /// Variables holding instances of this interface should be named "messageConsumer", 14 | /// or "expectedMessages" in the test code. 15 | @FunctionalInterface 16 | @NullMarked 17 | public interface MessageConsumer extends Consumer { 18 | 19 | void addMessage(MindcodeMessage message); 20 | 21 | default void accept(MindcodeMessage message) { 22 | addMessage(message); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/messages/MessageLevel.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.messages; 2 | 3 | import info.teksol.mc.util.StringUtils; 4 | import org.jspecify.annotations.NullMarked; 5 | 6 | @NullMarked 7 | public enum MessageLevel { 8 | ERROR, 9 | WARNING, 10 | INFO, 11 | DEBUG; 12 | 13 | private final String title; 14 | 15 | public boolean strongerOrEqual(MessageLevel other) { 16 | return ordinal() >= other.ordinal(); 17 | } 18 | 19 | public boolean weakerOrEqual(MessageLevel other) { 20 | return ordinal() >= other.ordinal(); 21 | } 22 | 23 | MessageLevel() { 24 | title = StringUtils.titleCase(name()); 25 | } 26 | 27 | public String getTitle() { 28 | return title; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/messages/MessageLogger.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.messages; 2 | 3 | import info.teksol.mc.common.SourceElement; 4 | import info.teksol.mc.common.SourcePosition; 5 | import org.intellij.lang.annotations.PrintFormat; 6 | import org.jspecify.annotations.NullMarked; 7 | 8 | @NullMarked 9 | public interface MessageLogger { 10 | 11 | void error(SourceElement node, @PrintFormat String format, Object... args); 12 | 13 | void error(SourcePosition position, @PrintFormat String format, Object... args); 14 | 15 | void error(@PrintFormat String format, Object... args); 16 | 17 | void warn(SourceElement node, @PrintFormat String format, Object... args); 18 | 19 | void warn(SourcePosition position, @PrintFormat String format, Object... args); 20 | 21 | void info(@PrintFormat String format, Object... args); 22 | 23 | void timing(@PrintFormat String format, Object... args); 24 | 25 | void debug(String message); 26 | } 27 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/messages/SourcePositionTranslator.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.messages; 2 | 3 | import info.teksol.mc.common.SourcePosition; 4 | import org.jspecify.annotations.NullMarked; 5 | 6 | @NullMarked 7 | public interface SourcePositionTranslator { 8 | 9 | SourcePosition apply(SourcePosition position); 10 | } 11 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/messages/TranslatingMessageConsumer.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.messages; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | 5 | @NullMarked 6 | public class TranslatingMessageConsumer implements MessageConsumer { 7 | private final MessageConsumer consumer; 8 | private final SourcePositionTranslator translator; 9 | 10 | public TranslatingMessageConsumer(MessageConsumer consumer, SourcePositionTranslator translator) { 11 | this.consumer = consumer; 12 | this.translator = translator; 13 | } 14 | 15 | @Override 16 | public void addMessage(MindcodeMessage message) { 17 | consumer.accept(message.translatePosition(translator)); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/compiler/CompilationPhase.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.compiler; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | 5 | @NullMarked 6 | public enum CompilationPhase { 7 | LEXER, 8 | PARSER, 9 | AST_BUILDER, 10 | PREPROCESSOR, 11 | CALL_GRAPH, 12 | COMPILER, 13 | OPTIMIZER, 14 | PRINTER, 15 | EMULATOR, 16 | ALL; 17 | 18 | public boolean includes(CompilationPhase phase) { 19 | return this.ordinal() >= phase.ordinal(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/compiler/CompilerContext.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.compiler; 2 | 3 | import info.teksol.mc.messages.MessageConsumer; 4 | import info.teksol.mc.messages.MessageEmitter; 5 | import org.jspecify.annotations.NullMarked; 6 | 7 | /// Represents a context used during compilation. 8 | /// Provides utilities and services needed during the compilation process. 9 | /// Specific interfaces extending this interface are created for specific classes 10 | /// accessing the context, providing only the necessary methods for the class. 11 | /// 12 | /// Where possible, the context is passed as a parameter to the class that needs it. 13 | /// In other cases the context can be accesses via appropriate static method of the 14 | /// `MindcodeCompiler` class. 15 | /// 16 | /// Context interfaces declare getter methods without the `get` prefix, so that 17 | /// a record matching the interface can be easily created for testing. 18 | @NullMarked 19 | public interface CompilerContext extends MessageEmitter { 20 | MessageConsumer messageConsumer(); 21 | } 22 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/compiler/DataType.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.compiler; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | 5 | @NullMarked 6 | public enum DataType { 7 | // No return type 8 | VOID ("void"), 9 | 10 | // General mlog variable 11 | VAR ("def"), 12 | ; 13 | 14 | public final String keyword; 15 | 16 | DataType(String keyword) { 17 | this.keyword = keyword; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/compiler/antlr/MissingSemicolonException.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.compiler.antlr; 2 | 3 | import org.antlr.v4.runtime.RecognitionException; 4 | import org.antlr.v4.runtime.Token; 5 | import org.jspecify.annotations.NullMarked; 6 | 7 | @NullMarked 8 | public class MissingSemicolonException extends RecognitionException { 9 | private final Token nextToken; 10 | 11 | public MissingSemicolonException(Token nextToken) { 12 | super(null, null, null); 13 | this.nextToken = nextToken; 14 | } 15 | 16 | public Token getNextToken() { 17 | return nextToken; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/compiler/ast/AstBuilderContext.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.compiler.ast; 2 | 3 | import info.teksol.mc.mindcode.compiler.CompilerContext; 4 | import info.teksol.mc.mindcode.compiler.ast.nodes.AstRequire; 5 | import org.jspecify.annotations.NullMarked; 6 | 7 | @NullMarked 8 | public interface AstBuilderContext extends CompilerContext { 9 | void addRequirement(AstRequire requirement); 10 | } 11 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/compiler/ast/ParserAbort.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.compiler.ast; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | 5 | @NullMarked 6 | public class ParserAbort extends RuntimeException { 7 | } 8 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/compiler/ast/nodes/AstArray.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.compiler.ast.nodes; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | import org.jspecify.annotations.Nullable; 5 | 6 | @NullMarked 7 | public interface AstArray { 8 | 9 | @Nullable AstIdentifier getProcessor(); 10 | 11 | AstIdentifier getArray(); 12 | } 13 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/compiler/ast/nodes/AstBreakStatement.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.compiler.ast.nodes; 2 | 3 | import info.teksol.annotations.AstNode; 4 | import info.teksol.mc.common.SourcePosition; 5 | import info.teksol.mc.mindcode.compiler.astcontext.AstContextType; 6 | import org.jspecify.annotations.NullMarked; 7 | import org.jspecify.annotations.Nullable; 8 | 9 | @NullMarked 10 | @AstNode(printFlat = true) 11 | public class AstBreakStatement extends AstLabeledStatement { 12 | 13 | public AstBreakStatement(SourcePosition sourcePosition, @Nullable AstIdentifier loopLabel) { 14 | super(sourcePosition, loopLabel); 15 | } 16 | 17 | @Override 18 | public AstContextType getContextType() { 19 | return AstContextType.BREAK; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/compiler/ast/nodes/AstContinueStatement.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.compiler.ast.nodes; 2 | 3 | import info.teksol.annotations.AstNode; 4 | import info.teksol.mc.common.SourcePosition; 5 | import info.teksol.mc.mindcode.compiler.astcontext.AstContextType; 6 | import org.jspecify.annotations.NullMarked; 7 | import org.jspecify.annotations.Nullable; 8 | 9 | @NullMarked 10 | @AstNode(printFlat = true) 11 | public class AstContinueStatement extends AstLabeledStatement { 12 | 13 | public AstContinueStatement(SourcePosition sourcePosition, @Nullable AstIdentifier loopLabel) { 14 | super(sourcePosition, loopLabel); 15 | } 16 | 17 | @Override 18 | public AstContextType getContextType() { 19 | return AstContextType.CONTINUE; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/compiler/ast/nodes/AstDeclaration.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.compiler.ast.nodes; 2 | 3 | import info.teksol.mc.common.SourcePosition; 4 | import org.jspecify.annotations.NullMarked; 5 | import org.jspecify.annotations.Nullable; 6 | 7 | import java.util.List; 8 | 9 | @NullMarked 10 | public abstract class AstDeclaration extends AstBaseMindcodeNode { 11 | 12 | @Override 13 | public AstNodeScope getScopeRestriction() { 14 | return AstNodeScope.GLOBAL; 15 | } 16 | 17 | @Override 18 | public boolean reportAllScopeErrors() { 19 | return true; 20 | } 21 | 22 | protected AstDeclaration(SourcePosition sourcePosition) { 23 | super(sourcePosition); 24 | } 25 | 26 | protected AstDeclaration(SourcePosition sourcePosition, List children) { 27 | super(sourcePosition, children); 28 | } 29 | 30 | protected AstDeclaration(SourcePosition sourcePosition, List children, 31 | @Nullable AstDocComment docComment) { 32 | super(sourcePosition, children, docComment); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/compiler/ast/nodes/AstDocComment.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.compiler.ast.nodes; 2 | 3 | import info.teksol.annotations.AstNode; 4 | import info.teksol.mc.common.SourcePosition; 5 | import org.jspecify.annotations.NullMarked; 6 | import org.jspecify.annotations.Nullable; 7 | 8 | @NullMarked 9 | @AstNode 10 | public class AstDocComment extends AstDeclaration { 11 | private final String comment; 12 | 13 | public AstDocComment(SourcePosition sourcePosition, String comment) { 14 | super(sourcePosition); 15 | this.comment = comment; 16 | } 17 | 18 | public String getComment() { 19 | return comment; 20 | } 21 | 22 | @Override 23 | public boolean equals(@Nullable Object o) { 24 | if (o == null || getClass() != o.getClass()) return false; 25 | 26 | AstDocComment that = (AstDocComment) o; 27 | return comment.equals(that.comment); 28 | } 29 | 30 | @Override 31 | public int hashCode() { 32 | return comment.hashCode(); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/compiler/ast/nodes/AstExpression.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.compiler.ast.nodes; 2 | 3 | import info.teksol.mc.common.SourcePosition; 4 | import org.jspecify.annotations.NullMarked; 5 | import org.jspecify.annotations.Nullable; 6 | 7 | import java.util.List; 8 | 9 | @NullMarked 10 | public abstract class AstExpression extends AstBaseMindcodeNode { 11 | 12 | @Override 13 | public AstNodeScope getScopeRestriction() { 14 | return AstNodeScope.LOCAL; 15 | } 16 | 17 | protected AstExpression(SourcePosition sourcePosition) { 18 | super(sourcePosition); 19 | } 20 | 21 | protected AstExpression(SourcePosition sourcePosition, List children) { 22 | super(sourcePosition, children); 23 | } 24 | 25 | protected AstExpression(SourcePosition sourcePosition, List children, 26 | @Nullable AstDocComment docComment) { 27 | super(sourcePosition, children, docComment); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/compiler/ast/nodes/AstFormattablePlaceholder.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.compiler.ast.nodes; 2 | 3 | import info.teksol.annotations.AstNode; 4 | import info.teksol.mc.common.SourcePosition; 5 | import org.jspecify.annotations.NullMarked; 6 | import org.jspecify.annotations.Nullable; 7 | 8 | @NullMarked 9 | @AstNode(printFlat = true) 10 | public class AstFormattablePlaceholder extends AstExpression { 11 | 12 | public AstFormattablePlaceholder(SourcePosition sourcePosition) { 13 | super(sourcePosition); 14 | } 15 | 16 | @Override 17 | public boolean equals(@Nullable Object o) { 18 | if (this == o) return true; 19 | return o != null && getClass() == o.getClass(); 20 | } 21 | 22 | @Override 23 | public int hashCode() { 24 | return 17; 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/compiler/ast/nodes/AstFragment.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.compiler.ast.nodes; 2 | 3 | import info.teksol.mc.common.SourcePosition; 4 | import org.jspecify.annotations.NullMarked; 5 | import org.jspecify.annotations.Nullable; 6 | 7 | import java.util.List; 8 | 9 | @NullMarked 10 | public abstract class AstFragment extends AstBaseMindcodeNode { 11 | 12 | @Override 13 | public AstNodeScope getScopeRestriction() { 14 | return AstNodeScope.NONE; 15 | } 16 | 17 | protected AstFragment(SourcePosition sourcePosition) { 18 | super(sourcePosition); 19 | } 20 | 21 | protected AstFragment(SourcePosition sourcePosition, List children) { 22 | super(sourcePosition, children); 23 | } 24 | 25 | protected AstFragment(SourcePosition sourcePosition, List children, 26 | @Nullable AstDocComment docComment) { 27 | super(sourcePosition, children, docComment); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/compiler/ast/nodes/AstLiteralColor.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.compiler.ast.nodes; 2 | 3 | import info.teksol.annotations.AstNode; 4 | import info.teksol.mc.common.SourcePosition; 5 | import info.teksol.mc.evaluator.Color; 6 | import org.jspecify.annotations.NullMarked; 7 | 8 | @NullMarked 9 | @AstNode(printFlat = true) 10 | public class AstLiteralColor extends AstLiteralNumeric { 11 | 12 | public AstLiteralColor(SourcePosition sourcePosition, String literal) { 13 | super(sourcePosition, literal, false); 14 | } 15 | 16 | @Override 17 | public double getDoubleValue() { 18 | return Color.parseColor(literal); 19 | } 20 | 21 | @Override 22 | public long getLongValue() { 23 | return (long) getDoubleValue(); 24 | } 25 | 26 | @Override 27 | public AstLiteralColor withSourcePosition(SourcePosition sourcePosition) { 28 | return new AstLiteralColor(sourcePosition, literal); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/compiler/ast/nodes/AstLiteralEscape.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.compiler.ast.nodes; 2 | 3 | import info.teksol.annotations.AstNode; 4 | import info.teksol.mc.common.SourcePosition; 5 | import org.jspecify.annotations.NullMarked; 6 | 7 | @NullMarked 8 | @AstNode(printFlat = true) 9 | public class AstLiteralEscape extends AstLiteralString { 10 | 11 | public AstLiteralEscape(SourcePosition sourcePosition, String literal) { 12 | super(sourcePosition, literal); 13 | } 14 | 15 | @Override 16 | public AstLiteralEscape withSourcePosition(SourcePosition sourcePosition) { 17 | return new AstLiteralEscape(sourcePosition, literal); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/compiler/ast/nodes/AstLiteralNumeric.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.compiler.ast.nodes; 2 | 3 | import info.teksol.mc.common.SourcePosition; 4 | import org.jspecify.annotations.NullMarked; 5 | 6 | @NullMarked 7 | public abstract class AstLiteralNumeric extends AstLiteral { 8 | 9 | protected AstLiteralNumeric(SourcePosition sourcePosition, String literal, boolean suppressWarning) { 10 | super(sourcePosition, literal, suppressWarning); 11 | if (literal.isEmpty()) { 12 | throw new IllegalArgumentException("Value cannot be empty"); 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/compiler/ast/nodes/AstLiteralString.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.compiler.ast.nodes; 2 | 3 | import info.teksol.annotations.AstNode; 4 | import info.teksol.mc.common.SourcePosition; 5 | import org.jspecify.annotations.NullMarked; 6 | 7 | @NullMarked 8 | @AstNode(printFlat = true) 9 | public class AstLiteralString extends AstLiteral { 10 | 11 | public AstLiteralString(SourcePosition sourcePosition, String literal) { 12 | super(sourcePosition, literal, false); 13 | } 14 | 15 | public String getValue() { 16 | return literal; 17 | } 18 | 19 | @Override 20 | public AstLiteralString withSourcePosition(SourcePosition sourcePosition) { 21 | return new AstLiteralString(sourcePosition, literal); 22 | } 23 | 24 | @Override 25 | public double getDoubleValue() { 26 | return 1.0; 27 | } 28 | 29 | @Override 30 | public long getLongValue() { 31 | return 1; 32 | } 33 | } -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/compiler/ast/nodes/AstMlogParameters.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.compiler.ast.nodes; 2 | 3 | import info.teksol.annotations.AstNode; 4 | import info.teksol.mc.common.SourcePosition; 5 | import org.jspecify.annotations.NullMarked; 6 | 7 | @NullMarked 8 | @AstNode(printFlat = true) 9 | public class AstMlogParameters extends AstFragment { 10 | private final AstExpression mlog; 11 | 12 | public AstMlogParameters(SourcePosition sourcePosition, AstExpression mlog) { 13 | super(sourcePosition, children(mlog)); 14 | this.mlog = mlog; 15 | } 16 | 17 | public AstExpression getMlog() { 18 | return mlog; 19 | } 20 | 21 | @Override 22 | public boolean equals(Object o) { 23 | if (o == null || getClass() != o.getClass()) return false; 24 | 25 | AstMlogParameters that = (AstMlogParameters) o; 26 | return mlog.equals(that.mlog); 27 | } 28 | 29 | @Override 30 | public int hashCode() { 31 | return mlog.hashCode(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/compiler/ast/nodes/AstNodeScope.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.compiler.ast.nodes; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | 5 | @NullMarked 6 | public enum AstNodeScope { 7 | GLOBAL, 8 | LOCAL, 9 | NONE, 10 | ; 11 | 12 | public boolean disallowed(AstNodeScope currentScope) { 13 | return this != NONE && this != currentScope; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/compiler/ast/nodes/AstStatement.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.compiler.ast.nodes; 2 | 3 | import info.teksol.mc.common.SourcePosition; 4 | import org.jspecify.annotations.NullMarked; 5 | import org.jspecify.annotations.Nullable; 6 | 7 | import java.util.List; 8 | 9 | @NullMarked 10 | public abstract class AstStatement extends AstBaseMindcodeNode { 11 | 12 | @Override 13 | public AstNodeScope getScopeRestriction() { 14 | return AstNodeScope.LOCAL; 15 | } 16 | 17 | protected AstStatement(SourcePosition sourcePosition) { 18 | super(sourcePosition); 19 | } 20 | 21 | protected AstStatement(SourcePosition sourcePosition, List children) { 22 | super(sourcePosition, children); 23 | } 24 | 25 | protected AstStatement(SourcePosition sourcePosition, List children, 26 | @Nullable AstDocComment docComment) { 27 | super(sourcePosition, children, docComment); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/compiler/ast/nodes/ExternalStorage.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.compiler.ast.nodes; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | import org.jspecify.annotations.Nullable; 5 | 6 | @NullMarked 7 | public interface ExternalStorage extends AstMindcodeNode { 8 | 9 | AstIdentifier getMemory(); 10 | 11 | @Nullable AstRange getRange(); 12 | 13 | default @Nullable AstExpression getStartIndex() { 14 | return null; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/compiler/callgraph/CallGraphCreatorContext.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.compiler.callgraph; 2 | 3 | import info.teksol.mc.mindcode.compiler.CompilerContext; 4 | import info.teksol.mc.mindcode.compiler.generation.variables.NameCreator; 5 | import info.teksol.mc.mindcode.logic.instructions.InstructionProcessor; 6 | import info.teksol.mc.profile.GlobalCompilerProfile; 7 | import org.jspecify.annotations.NullMarked; 8 | 9 | @NullMarked 10 | public interface CallGraphCreatorContext extends CompilerContext { 11 | GlobalCompilerProfile globalCompilerProfile(); 12 | InstructionProcessor instructionProcessor(); 13 | NameCreator nameCreator(); 14 | } 15 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/compiler/evaluator/CompileTimeEvaluatorContext.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.compiler.evaluator; 2 | 3 | import info.teksol.mc.mindcode.compiler.CompilerContext; 4 | import info.teksol.mc.mindcode.compiler.callgraph.CallGraph; 5 | import info.teksol.mc.mindcode.compiler.generation.variables.Variables; 6 | import info.teksol.mc.mindcode.logic.instructions.InstructionProcessor; 7 | import info.teksol.mc.profile.GlobalCompilerProfile; 8 | import org.jspecify.annotations.NullMarked; 9 | 10 | @NullMarked 11 | public interface CompileTimeEvaluatorContext extends CompilerContext { 12 | GlobalCompilerProfile globalCompilerProfile(); 13 | InstructionProcessor instructionProcessor(); 14 | CallGraph callGraph(); 15 | Variables variables(); 16 | } 17 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/compiler/evaluator/ValueType.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.compiler.evaluator; 2 | 3 | enum ValueType {NULL, BOOLEAN, BIN, HEX, LONG, DOUBLE} 4 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/compiler/functions/FunctionHandler.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.compiler.functions; 2 | 3 | import info.teksol.mc.mindcode.compiler.ast.nodes.AstFunctionCall; 4 | import info.teksol.mc.mindcode.compiler.generation.variables.FunctionArgument; 5 | import info.teksol.mc.mindcode.compiler.generation.variables.ValueStore; 6 | import org.jspecify.annotations.NullMarked; 7 | 8 | import java.util.List; 9 | 10 | @NullMarked 11 | interface FunctionHandler extends SampleGenerator { 12 | ValueStore handleFunction(AstFunctionCall call, List arguments); 13 | } 14 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/compiler/functions/FunctionMapperContext.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.compiler.functions; 2 | 3 | import info.teksol.mc.mindcode.compiler.CompilerContext; 4 | import info.teksol.mc.mindcode.compiler.generation.CodeAssembler; 5 | import info.teksol.mc.mindcode.logic.instructions.InstructionProcessor; 6 | import org.jspecify.annotations.NullMarked; 7 | 8 | @NullMarked 9 | public interface FunctionMapperContext extends CompilerContext { 10 | InstructionProcessor instructionProcessor(); 11 | CodeAssembler assembler(); 12 | } 13 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/compiler/functions/InvalidMetadataException.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.compiler.functions; 2 | 3 | import info.teksol.mc.mindcode.compiler.MindcodeInternalError; 4 | import org.jspecify.annotations.NullMarked; 5 | 6 | @NullMarked 7 | public class InvalidMetadataException extends MindcodeInternalError { 8 | InvalidMetadataException(String message) { 9 | super(message); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/compiler/functions/PropertyHandler.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.compiler.functions; 2 | 3 | import info.teksol.mc.mindcode.compiler.ast.nodes.AstFunctionCall; 4 | import info.teksol.mc.mindcode.compiler.generation.variables.FunctionArgument; 5 | import info.teksol.mc.mindcode.compiler.generation.variables.ValueStore; 6 | import info.teksol.mc.mindcode.logic.arguments.LogicValue; 7 | import org.jspecify.annotations.NullMarked; 8 | 9 | import java.util.List; 10 | 11 | @NullMarked 12 | interface PropertyHandler extends SampleGenerator { 13 | LogicValue handleProperty(AstFunctionCall node, ValueStore target, List arguments); 14 | } 15 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/compiler/functions/SelectorFunction.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.compiler.functions; 2 | 3 | import info.teksol.mc.mindcode.logic.opcodes.NamedParameter; 4 | import org.jspecify.annotations.NullMarked; 5 | 6 | @NullMarked 7 | interface SelectorFunction extends FunctionHandler { 8 | NamedParameter getSelector(); 9 | } 10 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/compiler/generation/AbstractStandaloneBuilder.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.compiler.generation; 2 | 3 | import info.teksol.mc.mindcode.compiler.ast.nodes.AstMindcodeNode; 4 | import org.jspecify.annotations.NullMarked; 5 | 6 | /// A base for a standalone builder class. A new instance is created for each processed node. The class 7 | /// provides all the methods the AbstractBuilder class does, but allows to store state inside the instance. 8 | @NullMarked 9 | public abstract class AbstractStandaloneBuilder extends AbstractBuilder { 10 | protected final T node; 11 | 12 | public AbstractStandaloneBuilder(AbstractBuilder builder, T node) { 13 | super(builder); 14 | this.node = node; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/compiler/generation/CodeAssemblerContext.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.compiler.generation; 2 | 3 | import info.teksol.mc.mindcode.compiler.CompilerContext; 4 | import info.teksol.mc.mindcode.compiler.astcontext.AstContext; 5 | import info.teksol.mc.mindcode.compiler.generation.variables.Variables; 6 | import info.teksol.mc.mindcode.logic.instructions.InstructionProcessor; 7 | import info.teksol.mc.profile.GlobalCompilerProfile; 8 | import org.jspecify.annotations.NullMarked; 9 | 10 | @NullMarked 11 | public interface CodeAssemblerContext extends CompilerContext { 12 | GlobalCompilerProfile globalCompilerProfile(); 13 | InstructionProcessor instructionProcessor(); 14 | Variables variables(); 15 | AstContext rootAstContext(); 16 | } 17 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/compiler/generation/StackTracker.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.compiler.generation; 2 | 3 | import info.teksol.mc.messages.AbstractMessageEmitter; 4 | import info.teksol.mc.messages.MessageConsumer; 5 | import info.teksol.mc.mindcode.logic.arguments.LogicVariable; 6 | import org.jspecify.annotations.NullMarked; 7 | 8 | import java.util.Objects; 9 | 10 | @NullMarked 11 | public class StackTracker extends AbstractMessageEmitter { 12 | private LogicVariable stackMemory = LogicVariable.INVALID; 13 | 14 | public StackTracker(MessageConsumer messageConsumer) { 15 | super(messageConsumer); 16 | } 17 | 18 | public boolean isValid() { 19 | return stackMemory != LogicVariable.INVALID; 20 | } 21 | 22 | public void setStackMemory(LogicVariable stackMemory) { 23 | this.stackMemory = Objects.requireNonNull(stackMemory); 24 | } 25 | 26 | public LogicVariable getStackMemory() { 27 | return stackMemory; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/compiler/generation/variables/FormattableContent.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.compiler.generation.variables; 2 | 3 | import info.teksol.mc.common.SourcePosition; 4 | import info.teksol.mc.messages.ERR; 5 | import info.teksol.mc.mindcode.compiler.ast.nodes.AstExpression; 6 | import org.jspecify.annotations.NullMarked; 7 | 8 | import java.util.List; 9 | 10 | @NullMarked 11 | public class FormattableContent extends CompoundValueStore { 12 | private final List parts; 13 | 14 | public FormattableContent(SourcePosition sourcePosition, List parts) { 15 | super(sourcePosition, ERR.FORMATTABLE_FORBIDDEN); 16 | this.parts = parts; 17 | } 18 | 19 | public List getParts() { 20 | return parts; 21 | } 22 | 23 | @Override 24 | public FormattableContent withSourcePosition(SourcePosition sourcePosition) { 25 | return new FormattableContent(sourcePosition, parts); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/compiler/generation/variables/FunctionParameter.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.compiler.generation.variables; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | 5 | @NullMarked 6 | public interface FunctionParameter extends ValueStore { 7 | // Variable name 8 | String getName(); 9 | 10 | boolean isInput(); 11 | 12 | boolean isOutput(); 13 | } 14 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/compiler/generation/variables/OptimizerContext.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.compiler.generation.variables; 2 | 3 | import info.teksol.mc.mindcode.compiler.CompilerContext; 4 | import org.jspecify.annotations.NullMarked; 5 | 6 | import java.util.List; 7 | 8 | @NullMarked 9 | public interface OptimizerContext extends CompilerContext { 10 | void addDiagnosticData(Object data); 11 | void addDiagnosticData(Class dataClass, List data); 12 | List getDiagnosticData(Class type); 13 | } -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/compiler/generation/variables/ProcessorStorage.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.compiler.generation.variables; 2 | 3 | import info.teksol.mc.mindcode.logic.arguments.LogicVariable; 4 | import org.jspecify.annotations.NullMarked; 5 | import org.jspecify.annotations.Nullable; 6 | 7 | import java.util.Objects; 8 | 9 | @NullMarked 10 | public record ProcessorStorage(@Nullable LogicVariable processor, @Nullable String name) { 11 | 12 | public String getName() { 13 | return Objects.requireNonNull(name); 14 | } 15 | 16 | public boolean hasNameSpecification() { 17 | return name != null; 18 | } 19 | 20 | public LogicVariable getProcessor() { 21 | return Objects.requireNonNull(processor); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/compiler/generation/variables/VariableScope.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.compiler.generation.variables; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | 5 | /// Defines possible scopes of variable registration. 6 | @NullMarked 7 | public enum VariableScope { 8 | /// The registration is valid within the entire function. 9 | FUNCTION, 10 | 11 | /// The registration is valid within the parent node. 12 | PARENT_NODE, 13 | 14 | /// The registration is valid within the current node only. 15 | NODE, 16 | } 17 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/compiler/generation/variables/VariablesContext.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.compiler.generation.variables; 2 | 3 | import info.teksol.mc.mindcode.compiler.CompilerContext; 4 | import info.teksol.mc.mindcode.logic.instructions.InstructionProcessor; 5 | import info.teksol.mc.mindcode.logic.mimex.MindustryMetadata; 6 | import info.teksol.mc.profile.GlobalCompilerProfile; 7 | import org.jspecify.annotations.NullMarked; 8 | 9 | @NullMarked 10 | public interface VariablesContext extends CompilerContext { 11 | GlobalCompilerProfile globalCompilerProfile(); 12 | InstructionProcessor instructionProcessor(); 13 | NameCreator nameCreator(); 14 | MindustryMetadata metadata(); 15 | } 16 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/compiler/optimization/NullDebugPrinter.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.compiler.optimization; 2 | 3 | import info.teksol.mc.mindcode.logic.instructions.LogicInstruction; 4 | import org.jspecify.annotations.NullMarked; 5 | import org.jspecify.annotations.Nullable; 6 | 7 | import java.util.List; 8 | import java.util.function.Consumer; 9 | 10 | @NullMarked 11 | public class NullDebugPrinter implements DebugPrinter { 12 | @Override 13 | public void registerIteration(@Nullable Optimizer optimizer, String title, List program) { 14 | // Do nothing 15 | } 16 | 17 | @Override 18 | public void print(Consumer messageConsumer) { 19 | // Do nothing 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/compiler/optimization/OptimizationResult.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.compiler.optimization; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | 5 | @NullMarked 6 | public enum OptimizationResult { 7 | /// The optimization was done as planned. 8 | REALIZED, 9 | 10 | /// The optimization proposal is no longer valid. 11 | INVALID, 12 | 13 | /// The optimization is possible, but would be costlier than initially assessed. This can only happen 14 | /// if the code was changed by some other optimizer in the meantime. 15 | OVER_LIMIT 16 | } 17 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/compiler/optimization/cases/CaseSwitcherConfigurations.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.compiler.optimization.cases; 2 | 3 | import info.teksol.mc.common.SourcePosition; 4 | import org.jspecify.annotations.NullMarked; 5 | 6 | @NullMarked 7 | public record CaseSwitcherConfigurations(SourcePosition sourcePosition, int configurationsCount) { 8 | } 9 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/compiler/optimization/cases/Partition.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.compiler.optimization.cases; 2 | 3 | import info.teksol.mc.mindcode.logic.arguments.LogicLabel; 4 | import org.jspecify.annotations.NullMarked; 5 | 6 | // Note: to is exclusive 7 | @NullMarked 8 | public record Partition(int from, int to, LogicLabel label) { 9 | public int size() { 10 | return to - from; 11 | } 12 | 13 | public boolean follows(Partition other) { 14 | return from == other.to; 15 | } 16 | 17 | public Segment toSegment() { 18 | return new Segment(SegmentType.SINGLE, from, to, label, size(), label, size()); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/compiler/optimization/cases/SegmentConfigurationGenerator.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.compiler.optimization.cases; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | 5 | import java.util.List; 6 | import java.util.Set; 7 | 8 | @NullMarked 9 | public interface SegmentConfigurationGenerator { 10 | List getPartitions(); 11 | 12 | Set createSegmentConfigurations(); 13 | 14 | int getConfigurationCount(); 15 | } 16 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/compiler/optimization/cases/SegmentType.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.compiler.optimization.cases; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | 5 | @NullMarked 6 | public enum SegmentType { 7 | /// A segment containing one distinct value 8 | /// When the distinct value is an `else` value, represents an empty segment 9 | SINGLE, 10 | 11 | // A merged segment containing one predominant value and a few possible exceptions 12 | MIXED, 13 | 14 | /// A segment containing multiple distinct values, produces a jump table 15 | JUMP_TABLE 16 | } 17 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/compiler/preprocess/PreprocessorContext.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.compiler.preprocess; 2 | 3 | import info.teksol.mc.mindcode.compiler.CompilerContext; 4 | import info.teksol.mc.profile.DirectiveProcessor; 5 | import org.jspecify.annotations.NullMarked; 6 | 7 | @NullMarked 8 | public interface PreprocessorContext extends CompilerContext { 9 | DirectiveProcessor directiveProcessor(); 10 | } 11 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/decompiler/ParsedMlog.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.decompiler; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | @NullMarked 9 | public record ParsedMlog(Map labels, List content) { 10 | } 11 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/logic/arguments/GenericArgument.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.logic.arguments; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | 5 | /// Represents a generic argument created outside usual compiler context (e.g. in a test code, or when generating 6 | /// sample instructions). Compiler/optimizer is unable to handle generic arguments. 7 | @NullMarked 8 | public class GenericArgument extends AbstractArgument { 9 | private final String mlog; 10 | 11 | public GenericArgument(String mlog) { 12 | super(ArgumentType.UNSPECIFIED, ValueMutability.MUTABLE); 13 | this.mlog = mlog; 14 | } 15 | 16 | @Override 17 | public String toMlog() { 18 | return mlog; 19 | } 20 | 21 | @Override 22 | public String toString() { 23 | return "BaseArgument{" + 24 | "mlog='" + mlog + '\'' + 25 | '}'; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/logic/arguments/LogicAddress.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.logic.arguments; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | 5 | @NullMarked 6 | public interface LogicAddress extends LogicArgument { 7 | } 8 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/logic/arguments/LogicLiteral.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.logic.arguments; 2 | 3 | import info.teksol.mc.common.SourcePosition; 4 | import info.teksol.mc.mindcode.compiler.ast.nodes.AstMindcodeNode; 5 | import org.jspecify.annotations.NullMarked; 6 | 7 | @NullMarked 8 | public interface LogicLiteral extends LogicValue { 9 | 10 | @Override 11 | default boolean isLvalue() { 12 | return false; 13 | } 14 | 15 | default boolean isNull() { 16 | return this == LogicNull.NULL; 17 | } 18 | 19 | @Override 20 | default LogicLiteral withSourcePosition(SourcePosition sourcePosition) { 21 | return this; 22 | } 23 | 24 | AstMindcodeNode asAstNode(SourcePosition position); 25 | } 26 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/logic/arguments/arrays/ArrayConstructor.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.logic.arguments.arrays; 2 | 3 | import info.teksol.mc.mindcode.logic.instructions.LogicInstruction; 4 | import info.teksol.mc.mindcode.logic.instructions.SideEffects; 5 | import org.jspecify.annotations.NullMarked; 6 | import org.jspecify.annotations.Nullable; 7 | 8 | import java.util.List; 9 | import java.util.Map; 10 | import java.util.function.Consumer; 11 | 12 | @NullMarked 13 | public interface ArrayConstructor { 14 | 15 | SideEffects createSideEffects(AccessType accessType); 16 | 17 | int getInstructionSize(AccessType accessType, @Nullable Map sharedStructures); 18 | 19 | String getJumpTableId(AccessType accessType); 20 | 21 | void generateJumpTable(AccessType accessType, Map> jumpTables); 22 | 23 | void expandInstruction(Consumer consumer, Map> jumpTables); 24 | 25 | enum AccessType { 26 | READ, WRITE 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/logic/instructions/ArrayAccessInstruction.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.logic.instructions; 2 | 3 | import info.teksol.mc.mindcode.logic.arguments.LogicArray; 4 | import info.teksol.mc.mindcode.logic.arguments.LogicValue; 5 | import info.teksol.mc.mindcode.logic.arguments.arrays.ArrayConstructor; 6 | import info.teksol.mc.mindcode.logic.arguments.arrays.ArrayConstructor.AccessType; 7 | import org.jspecify.annotations.NullMarked; 8 | 9 | @NullMarked 10 | public interface ArrayAccessInstruction extends LogicInstruction { 11 | 12 | default LogicArray getArray() { 13 | return (LogicArray) getArg(1); 14 | } 15 | 16 | default LogicValue getIndex() { 17 | return (LogicValue) getArg(2); 18 | } 19 | 20 | ArrayConstructor getArrayConstructor(); 21 | 22 | AccessType getAccessType(); 23 | 24 | default String getJumpTableId() { 25 | return getArrayConstructor().getJumpTableId(getAccessType()); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/logic/instructions/CallingInstruction.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.logic.instructions; 2 | 3 | import info.teksol.mc.mindcode.logic.arguments.LogicLabel; 4 | import org.jspecify.annotations.NullMarked; 5 | 6 | @NullMarked 7 | public interface CallingInstruction extends LogicInstruction { 8 | 9 | LogicLabel getCallAddr(); 10 | 11 | default boolean affectsControlFlow() { 12 | return true; 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/logic/instructions/ConditionalInstruction.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.logic.instructions; 2 | 3 | import info.teksol.mc.mindcode.logic.arguments.Condition; 4 | import info.teksol.mc.mindcode.logic.arguments.LogicValue; 5 | 6 | public interface ConditionalInstruction extends LogicInstruction { 7 | Condition getCondition(); 8 | LogicValue getX(); 9 | LogicValue getY(); 10 | 11 | default boolean isConditional() { 12 | return getCondition() != Condition.ALWAYS; 13 | } 14 | 15 | default boolean isUnconditional() { 16 | return getCondition() == Condition.ALWAYS; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/logic/instructions/EmptyInstruction.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.logic.instructions; 2 | 3 | import info.teksol.mc.mindcode.compiler.astcontext.AstContext; 4 | import info.teksol.mc.mindcode.logic.opcodes.Opcode; 5 | import org.jspecify.annotations.NullMarked; 6 | 7 | import java.util.List; 8 | 9 | @NullMarked 10 | public class EmptyInstruction extends BaseInstruction { 11 | 12 | EmptyInstruction(AstContext astContext) { 13 | super(astContext, Opcode.EMPTY, List.of(), List.of()); 14 | } 15 | 16 | protected EmptyInstruction(BaseInstruction other, AstContext astContext) { 17 | super(other, astContext); 18 | } 19 | 20 | @Override 21 | public EmptyInstruction withContext(AstContext astContext) { 22 | return this.astContext == astContext ? this : new EmptyInstruction(this, astContext); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/logic/instructions/EndInstruction.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.logic.instructions; 2 | 3 | import info.teksol.mc.mindcode.compiler.astcontext.AstContext; 4 | import info.teksol.mc.mindcode.logic.opcodes.Opcode; 5 | import org.jspecify.annotations.NullMarked; 6 | 7 | import java.util.List; 8 | 9 | @NullMarked 10 | public class EndInstruction extends BaseInstruction { 11 | 12 | EndInstruction(AstContext astContext) { 13 | super(astContext, Opcode.END, List.of(), List.of()); 14 | } 15 | 16 | protected EndInstruction(BaseInstruction other, AstContext astContext) { 17 | super(other, astContext); 18 | } 19 | 20 | @Override 21 | public EndInstruction withContext(AstContext astContext) { 22 | return this.astContext == astContext ? this : new EndInstruction(this, astContext); 23 | } 24 | 25 | @Override 26 | public boolean endsCodePath() { 27 | return true; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/logic/instructions/InstructionComment.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.logic.instructions; 2 | 3 | public record InstructionComment(String whiteSpace, String comment) { 4 | public static final InstructionComment EMPTY = new InstructionComment("", ""); 5 | 6 | public String fullComment() { 7 | return whiteSpace + comment; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/logic/instructions/LabeledInstruction.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.logic.instructions; 2 | 3 | import info.teksol.mc.mindcode.logic.arguments.LogicLabel; 4 | import org.jspecify.annotations.NullMarked; 5 | 6 | @NullMarked 7 | public interface LabeledInstruction extends LogicInstruction { 8 | 9 | LogicLabel getLabel(); 10 | 11 | default boolean affectsControlFlow() { 12 | return true; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/logic/instructions/LogicResultInstruction.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.logic.instructions; 2 | 3 | import info.teksol.mc.mindcode.logic.arguments.LogicVariable; 4 | import org.jspecify.annotations.NullMarked; 5 | 6 | @NullMarked 7 | public interface LogicResultInstruction extends LogicInstruction { 8 | 9 | LogicVariable getResult(); 10 | 11 | LogicResultInstruction withResult(LogicVariable result); 12 | 13 | /// @return true if the instruction depends on the prior value of the result variable (e.g. `op add x x 1`). 14 | default boolean isUpdating() { 15 | LogicVariable result = getResult(); 16 | return getArgs().stream().filter(result::equals).count() > 1; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/logic/instructions/MultiTargetInstruction.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.logic.instructions; 2 | 3 | import info.teksol.mc.mindcode.logic.arguments.LogicAddress; 4 | import org.jspecify.annotations.NullMarked; 5 | 6 | @NullMarked 7 | public interface MultiTargetInstruction extends LogicInstruction { 8 | 9 | LogicAddress getTarget(); 10 | 11 | } 12 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/logic/instructions/PrintingInstruction.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.logic.instructions; 2 | 3 | import info.teksol.mc.mindcode.logic.arguments.LogicValue; 4 | import org.jspecify.annotations.NullMarked; 5 | 6 | @NullMarked 7 | public interface PrintingInstruction extends LogicInstruction { 8 | 9 | LogicValue getValue(); 10 | 11 | } 12 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/logic/instructions/PushOrPopInstruction.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.logic.instructions; 2 | 3 | import info.teksol.mc.mindcode.logic.arguments.LogicVariable; 4 | import org.jspecify.annotations.NullMarked; 5 | 6 | // Push and pop are always processed at the same time 7 | @NullMarked 8 | public interface PushOrPopInstruction extends LogicInstruction { 9 | 10 | default LogicVariable getMemory() { 11 | return (LogicVariable) getArg(0); 12 | } 13 | 14 | default LogicVariable getVariable() { 15 | return (LogicVariable) getArg(1); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/logic/instructions/StopInstruction.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.logic.instructions; 2 | 3 | import info.teksol.mc.mindcode.compiler.astcontext.AstContext; 4 | import info.teksol.mc.mindcode.logic.opcodes.Opcode; 5 | import org.jspecify.annotations.NullMarked; 6 | 7 | import java.util.List; 8 | 9 | @NullMarked 10 | public class StopInstruction extends BaseInstruction { 11 | 12 | StopInstruction(AstContext astContext) { 13 | super(astContext, Opcode.STOP, List.of(), List.of()); 14 | } 15 | 16 | protected StopInstruction(BaseInstruction other, AstContext astContext) { 17 | super(other, astContext); 18 | } 19 | 20 | @Override 21 | public StopInstruction withContext(AstContext astContext) { 22 | return this.astContext == astContext ? this : new StopInstruction(this, astContext); 23 | } 24 | 25 | @Override 26 | public boolean endsCodePath() { 27 | return true; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/logic/mimex/Item.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.logic.mimex; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | 5 | @NullMarked 6 | public record Item( 7 | String contentName, 8 | String name, 9 | int id, 10 | int logicId 11 | ) implements MindustryContent { 12 | 13 | @Override 14 | public ContentType contentType() { 15 | return ContentType.ITEM; 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/logic/mimex/LAccess.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.logic.mimex; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | 5 | @NullMarked 6 | public record LAccess( 7 | String contentName, 8 | String name, 9 | boolean senseable, 10 | boolean controllable, 11 | boolean settable, 12 | String parameters 13 | ) implements MindustryContent { 14 | 15 | @Override 16 | public ContentType contentType() { 17 | return ContentType.LACCESS; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/logic/mimex/LVar.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.logic.mimex; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | 5 | @NullMarked 6 | public record LVar( 7 | String contentName, 8 | String name, 9 | boolean global, 10 | boolean object, 11 | boolean constant, 12 | double numericValue 13 | ) implements MindustryContent { 14 | 15 | @Override 16 | public ContentType contentType() { 17 | return ContentType.LVAR; 18 | } 19 | 20 | public boolean isNumericConstant() { 21 | return global && !object && constant && numericValue != 0.0; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/logic/mimex/Liquid.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.logic.mimex; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | 5 | @NullMarked 6 | public record Liquid( 7 | String contentName, 8 | String name, 9 | int id, 10 | int logicId 11 | ) implements MindustryContent { 12 | 13 | @Override 14 | public ContentType contentType() { 15 | return ContentType.LIQUID; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/logic/mimex/NamedColor.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.logic.mimex; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | 5 | @NullMarked 6 | public record NamedColor(String name, double color) implements NamedContent { 7 | 8 | @Override 9 | public String contentName() { 10 | return name; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/logic/mimex/NamedContent.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.logic.mimex; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | 5 | @NullMarked 6 | public interface NamedContent { 7 | 8 | /// @return content name of the content (not including any prefix - e.g. `@` for built-ins) 9 | String contentName(); 10 | 11 | /// @return name of the content (includes the prefix) 12 | String name(); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/logic/mimex/Unit.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.logic.mimex; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | 5 | @NullMarked 6 | public record Unit( 7 | String contentName, 8 | String name, 9 | int id, 10 | int logicId 11 | ) implements MindustryContent { 12 | 13 | @Override 14 | public ContentType contentType() { 15 | return ContentType.UNIT; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/logic/mimex/UnitCommand.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.logic.mimex; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | 5 | @NullMarked 6 | public record UnitCommand( 7 | String contentName, 8 | String name, 9 | int id 10 | ) implements MindustryContent { 11 | 12 | @Override 13 | public ContentType contentType() { 14 | return ContentType.UNIT_COMMAND; 15 | } 16 | 17 | static UnitCommand create(String contentName, String name, int id, int logicId) { 18 | return new UnitCommand(contentName, name, id); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/logic/mimex/UnknownContent.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.logic.mimex; 2 | 3 | import info.teksol.mc.mindcode.compiler.MindcodeInternalError; 4 | import org.jspecify.annotations.NullMarked; 5 | 6 | @NullMarked 7 | public record UnknownContent(String name) implements MindustryContent { 8 | 9 | public UnknownContent(String name) { 10 | this.name = name; 11 | if (!name.startsWith("@")) { 12 | throw new MindcodeInternalError(String.format("No '@' at the beginning of content '%s'", name)); 13 | } 14 | } 15 | 16 | @Override 17 | public ContentType contentType() { 18 | return ContentType.UNKNOWN; 19 | } 20 | 21 | @Override 22 | public String contentName() { 23 | return name.substring(1); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/logic/mimex/Weather.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.logic.mimex; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | 5 | @NullMarked 6 | public record Weather( 7 | String contentName, 8 | String name, 9 | int id, 10 | int logicId 11 | ) implements MindustryContent { 12 | 13 | @Override 14 | public ContentType contentType() { 15 | return ContentType.WEATHER; 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/logic/opcodes/FunctionMapping.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.logic.opcodes; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | 5 | @NullMarked 6 | public enum FunctionMapping { 7 | NONE, // No mapping 8 | FUNC, // Mapping to function 9 | PROP, // Mapping to property access - block.method(arguments) 10 | BOTH, // Mapping to both a function and a property access 11 | } 12 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/logic/opcodes/KeywordCategory.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.logic.opcodes; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | import org.jspecify.annotations.Nullable; 5 | 6 | import java.util.Map; 7 | import java.util.stream.Collectors; 8 | import java.util.stream.Stream; 9 | 10 | /// Defines keyword categories. The primary purpose of keyword categories is the ability to declare additional keywords 11 | /// using the `#declare` directive. 12 | @NullMarked 13 | public enum KeywordCategory { 14 | linkedBlock, 15 | builtin, 16 | 17 | alignment, 18 | blockGroup, 19 | lookupType, 20 | markerType, 21 | radarSort, 22 | radarTarget, 23 | settableTileLayer, 24 | statusEffect, 25 | tileLayer, 26 | ; 27 | 28 | private static final Map MAP = Stream.of(values()) 29 | .collect(Collectors.toMap(Enum::name, o -> o)); 30 | 31 | public static @Nullable KeywordCategory byName(String categoryName) { 32 | return MAP.get(categoryName); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/logic/opcodes/NamedParameter.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.logic.opcodes; 2 | 3 | import info.teksol.mc.mindcode.logic.arguments.LogicArgument; 4 | import info.teksol.mc.mindcode.logic.arguments.LogicKeyword; 5 | import info.teksol.mc.mindcode.logic.arguments.Operation; 6 | import org.jspecify.annotations.NullMarked; 7 | import org.jspecify.annotations.Nullable; 8 | 9 | import java.util.Objects; 10 | 11 | @NullMarked 12 | public record NamedParameter(InstructionParameterType type, String name, @Nullable Operation operation) { 13 | public NamedParameter { 14 | Objects.requireNonNull(type); 15 | Objects.requireNonNull(name); 16 | } 17 | 18 | public NamedParameter(InstructionParameterType type, String name) { 19 | this(type, name, null); 20 | } 21 | 22 | public Operation operation() { 23 | return Objects.requireNonNull(operation); 24 | } 25 | 26 | public LogicArgument keyword() { 27 | return operation == null ? LogicKeyword.create(name) : operation; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/mindcode/logic/opcodes/TypedArgument.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.logic.opcodes; 2 | 3 | import info.teksol.mc.mindcode.logic.arguments.LogicArgument; 4 | import org.jspecify.annotations.NullMarked; 5 | 6 | import java.util.Objects; 7 | 8 | @NullMarked 9 | public record TypedArgument(InstructionParameterType type, LogicArgument argument) { 10 | public TypedArgument { 11 | Objects.requireNonNull(type); 12 | Objects.requireNonNull(argument); 13 | } 14 | 15 | public boolean isInput() { 16 | return type.isInput(); 17 | } 18 | 19 | public boolean isInputOnly() { 20 | return type.isInputOnly(); 21 | } 22 | 23 | public boolean isOutput() { 24 | return type.isOutput(); 25 | } 26 | 27 | public boolean isInputOrOutput() { 28 | return type.isInputOrOutput(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/profile/BuiltinEvaluation.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.profile; 2 | 3 | import info.teksol.mc.util.EnumUtils; 4 | import org.jspecify.annotations.Nullable; 5 | 6 | import java.util.Collection; 7 | import java.util.Map; 8 | 9 | public enum BuiltinEvaluation { 10 | NONE, 11 | COMPATIBLE, 12 | FULL, 13 | ; 14 | 15 | private static final Map VALUE_MAP = createValueMap(); 16 | 17 | private static Map createValueMap() { 18 | return EnumUtils.createValueMap(values()); 19 | } 20 | 21 | public static @Nullable BuiltinEvaluation byName(String level) { 22 | return VALUE_MAP.get(level.toLowerCase()); 23 | } 24 | 25 | public static BuiltinEvaluation byName(String level, BuiltinEvaluation defaultValue) { 26 | return VALUE_MAP.getOrDefault(level.toLowerCase(), defaultValue); 27 | } 28 | 29 | public static Collection allowedValues() { 30 | return VALUE_MAP.keySet(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/profile/FileReferences.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.profile; 2 | 3 | import info.teksol.mc.util.EnumUtils; 4 | import org.jspecify.annotations.NullMarked; 5 | import org.jspecify.annotations.Nullable; 6 | 7 | import java.util.Collection; 8 | import java.util.Map; 9 | 10 | @NullMarked 11 | public enum FileReferences { 12 | PATH, 13 | URI, 14 | WINDOWS_URI, 15 | ; 16 | 17 | private static final Map VALUE_MAP = createValueMap(); 18 | 19 | private static Map createValueMap() { 20 | return EnumUtils.createValueMap(values()); 21 | } 22 | 23 | public static @Nullable FileReferences byName(String level) { 24 | return VALUE_MAP.get(level.toLowerCase()); 25 | } 26 | 27 | public static FileReferences byName(String level, FileReferences defaultValue) { 28 | return VALUE_MAP.getOrDefault(level.toLowerCase(), defaultValue); 29 | } 30 | 31 | public static Collection allowedValues() { 32 | return VALUE_MAP.keySet(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/profile/FinalCodeOutput.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.profile; 2 | 3 | import info.teksol.mc.util.EnumUtils; 4 | import org.jspecify.annotations.NullMarked; 5 | import org.jspecify.annotations.Nullable; 6 | 7 | import java.util.Collection; 8 | import java.util.Map; 9 | 10 | @NullMarked 11 | public enum FinalCodeOutput { 12 | NONE, 13 | PLAIN, 14 | FLAT_AST, 15 | DEEP_AST, 16 | SOURCE, 17 | ; 18 | 19 | private static final Map VALUE_MAP = createValueMap(); 20 | 21 | private static Map createValueMap() { 22 | return EnumUtils.createValueMap(values()); 23 | } 24 | 25 | public static @Nullable FinalCodeOutput byName(String level) { 26 | return VALUE_MAP.get(level.toLowerCase()); 27 | } 28 | 29 | public static FinalCodeOutput byName(String level, FinalCodeOutput defaultValue) { 30 | return VALUE_MAP.getOrDefault(level.toLowerCase(), defaultValue); 31 | } 32 | 33 | public static Collection allowedValues() { 34 | return VALUE_MAP.keySet(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/profile/GenerationGoal.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.profile; 2 | 3 | import info.teksol.mc.util.EnumUtils; 4 | import org.jspecify.annotations.NullMarked; 5 | import org.jspecify.annotations.Nullable; 6 | 7 | import java.util.Collection; 8 | import java.util.Map; 9 | 10 | @NullMarked 11 | public enum GenerationGoal { 12 | SIZE, 13 | NEUTRAL, 14 | SPEED, 15 | ; 16 | 17 | private static final Map VALUE_MAP = createValueMap(); 18 | 19 | private static Map createValueMap() { 20 | return EnumUtils.createValueMap(values()); 21 | } 22 | 23 | public static @Nullable GenerationGoal byName(String level) { 24 | return VALUE_MAP.get(level.toLowerCase()); 25 | } 26 | 27 | public static GenerationGoal byName(String level, GenerationGoal defaultValue) { 28 | return VALUE_MAP.getOrDefault(level.toLowerCase(), defaultValue); 29 | } 30 | 31 | public static Collection allowedValues() { 32 | return VALUE_MAP.keySet(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/profile/Remarks.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.profile; 2 | 3 | import info.teksol.mc.util.EnumUtils; 4 | import org.jspecify.annotations.NullMarked; 5 | import org.jspecify.annotations.Nullable; 6 | 7 | import java.util.Collection; 8 | import java.util.Map; 9 | 10 | @NullMarked 11 | public enum Remarks { 12 | NONE, 13 | COMMENTS, 14 | PASSIVE, 15 | ACTIVE, 16 | ; 17 | 18 | private static final Map VALUE_MAP = createValueMap(); 19 | 20 | private static Map createValueMap() { 21 | return EnumUtils.createValueMap(values()); 22 | } 23 | 24 | public static @Nullable Remarks byName(String level) { 25 | return VALUE_MAP.get(level.toLowerCase()); 26 | } 27 | 28 | public static Remarks byName(String level, Remarks defaultValue) { 29 | return VALUE_MAP.getOrDefault(level.toLowerCase(), defaultValue); 30 | } 31 | 32 | public static Collection allowedValues() { 33 | return VALUE_MAP.keySet(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/profile/SyntacticMode.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.profile; 2 | 3 | import info.teksol.mc.util.EnumUtils; 4 | import org.jspecify.annotations.NullMarked; 5 | import org.jspecify.annotations.Nullable; 6 | 7 | import java.util.Collection; 8 | import java.util.Map; 9 | 10 | @NullMarked 11 | public enum SyntacticMode { 12 | STRICT, 13 | MIXED, 14 | RELAXED, 15 | ; 16 | 17 | private static final Map VALUE_MAP = createValueMap(); 18 | 19 | private static Map createValueMap() { 20 | return EnumUtils.createValueMap(values()); 21 | } 22 | 23 | public static @Nullable SyntacticMode byName(String level) { 24 | return VALUE_MAP.get(level.toLowerCase()); 25 | } 26 | 27 | public static SyntacticMode byName(String level, SyntacticMode defaultValue) { 28 | return VALUE_MAP.getOrDefault(level.toLowerCase(), defaultValue); 29 | } 30 | 31 | public static Collection allowedValues() { 32 | return VALUE_MAP.keySet(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/profile/options/CompilerOption.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.profile.options; 2 | 3 | public interface CompilerOption { 4 | Enum getOption(); 5 | 6 | String getOptionName(); 7 | 8 | String getFlag(); 9 | 10 | String[] getNameOrFlag(); 11 | 12 | String getDescription(); 13 | 14 | OptionAvailability getAvailability(); 15 | 16 | SemanticStability getStability(); 17 | 18 | OptionCategory getCategory(); 19 | 20 | OptionScope getScope(); 21 | 22 | OptionMultiplicity getMultiplicity(); 23 | } 24 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/profile/options/CompilerOptions.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.profile.options; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | 5 | @NullMarked 6 | public enum CompilerOptions { 7 | AUTO_PRINTFLUSH, 8 | BOUNDARY_CHECKS, 9 | REMARKS, 10 | SYNTAX, 11 | TARGET_GUARD, 12 | } 13 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/profile/options/DebuggingOptions.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.profile.options; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | 5 | @NullMarked 6 | public enum DebuggingOptions { 7 | CASE_CONFIGURATION, 8 | DEBUG_MESSAGES, 9 | DEBUG_OUTPUT, 10 | PARSE_TREE, 11 | PRINT_STACKTRACE, 12 | PRINT_UNRESOLVED, 13 | SORT_VARIABLES, 14 | } 15 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/profile/options/EnvironmentOptions.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.profile.options; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | 5 | @NullMarked 6 | public enum EnvironmentOptions { 7 | BUILTIN_EVALUATION, 8 | INSTRUCTION_LIMIT, 9 | NULL_COUNTER_IS_NOOP, 10 | TARGET, 11 | } 12 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/profile/options/InputOutputOptions.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.profile.options; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | 5 | @NullMarked 6 | public enum InputOutputOptions { 7 | FILE_REFERENCES, 8 | } 9 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/profile/options/MlogFormatOptions.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.profile.options; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | 5 | @NullMarked 6 | public enum MlogFormatOptions { 7 | FUNCTION_PREFIX, 8 | MLOG_INDENT, 9 | SIGNATURE, 10 | SYMBOLIC_LABELS, 11 | } 12 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/profile/options/OptimizationOptions.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.profile.options; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | 5 | @NullMarked 6 | public enum OptimizationOptions { 7 | OPTIMIZATION, 8 | OPTIMIZATION_LEVEL, 9 | 10 | CASE_OPTIMIZATION_STRENGTH, 11 | GOAL, 12 | MLOG_BLOCK_OPTIMIZATION, 13 | PASSES, 14 | UNSAFE_CASE_OPTIMIZATION, 15 | TEXT_TABLES, 16 | WEIGHT, 17 | } 18 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/profile/options/OptionAvailability.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.profile.options; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | 5 | @NullMarked 6 | public enum OptionAvailability { 7 | UNIVERSAL, 8 | COMMAND_LINE, 9 | DIRECTIVE, 10 | NONE, 11 | ; 12 | 13 | public boolean isCommandline() { 14 | return this == COMMAND_LINE || this == UNIVERSAL; 15 | } 16 | 17 | public boolean isDirective() { 18 | return this == DIRECTIVE || this == UNIVERSAL; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/profile/options/OptionMultiplicity.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.profile.options; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | 5 | @NullMarked 6 | public enum OptionMultiplicity { 7 | ZERO (""), 8 | ZERO_OR_ONCE ("?"), 9 | ZERO_OR_MORE ("*"), 10 | ONCE (""), 11 | ONCE_OR_MORE ("+"), 12 | ; 13 | 14 | public final String nargs; 15 | 16 | OptionMultiplicity(String nargs) { 17 | this.nargs = nargs; 18 | } 19 | 20 | public boolean matchesMultiple() { 21 | return this == ZERO_OR_MORE || this == ONCE_OR_MORE; 22 | } 23 | 24 | public boolean matchesNone() { 25 | return this == ZERO || this == ZERO_OR_ONCE || this == ZERO_OR_MORE; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/profile/options/OptionScope.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.profile.options; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | 5 | @NullMarked 6 | public enum OptionScope { 7 | GLOBAL, 8 | MODULE, 9 | LOCAL, 10 | ; 11 | 12 | public boolean isIncludedIn(OptionScope other) { 13 | return ordinal() >= other.ordinal(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/profile/options/RunOptions.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.profile.options; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | 5 | @NullMarked 6 | public enum RunOptions { 7 | RUN, 8 | RUN_STEPS, 9 | OUTPUT_PROFILING, 10 | 11 | } 12 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/profile/options/SchematicOptions.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.profile.options; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | 5 | @NullMarked 6 | public enum SchematicOptions { 7 | ADD_TAG, 8 | } 9 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/profile/options/SemanticStability.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.profile.options; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | 5 | @NullMarked 6 | public enum SemanticStability { 7 | /// The compiler option doesn't alter the behavior of the program 8 | STABLE, 9 | 10 | /// The compiler option does, at least potentially, alter the behavior of the program 11 | UNSTABLE, 12 | } 13 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/util/Indenter.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.util; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | @NullMarked 9 | public class Indenter { 10 | private final String indent; 11 | private final List indents = new ArrayList<>(List.of("")); 12 | 13 | public Indenter(String indent) { 14 | this.indent = indent; 15 | } 16 | 17 | public String getIndent(int level) { 18 | if (level < 0) throw new IllegalArgumentException("Level must be non-negative"); 19 | if (level >= indents.size()) { 20 | for (int i = indents.size(); i <= level; i++) { 21 | indents.add(indents.get(i - 1) + indent); 22 | } 23 | } 24 | return indents.get(level); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/util/Lazy.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.util; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | import org.jspecify.annotations.Nullable; 5 | 6 | import java.util.function.Supplier; 7 | 8 | @NullMarked 9 | public class Lazy { 10 | private final Supplier supplier; 11 | private @Nullable T instance; 12 | 13 | public Lazy(Supplier supplier) { 14 | this.supplier = supplier; 15 | } 16 | 17 | public T get() { 18 | if (instance == null) { 19 | instance = supplier.get(); 20 | } 21 | return instance; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/util/ObjectUtils.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.util; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | import org.jspecify.annotations.Nullable; 5 | 6 | @NullMarked 7 | public class ObjectUtils { 8 | 9 | public static E toNonNull(@Nullable E e) { 10 | assert e != null; 11 | return e; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/util/StringUtils.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.util; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | 5 | @NullMarked 6 | public class StringUtils { 7 | 8 | public static String firstLowerCase(String s) { 9 | return s.isEmpty() ? "" : Character.toLowerCase(s.charAt(0)) + s.substring(1); 10 | } 11 | 12 | public static String firstUpperCase(String s) { 13 | return s.isEmpty() ? "" : Character.toUpperCase(s.charAt(0)) + s.substring(1); 14 | } 15 | 16 | public static String titleCase(String s) { 17 | return s.isEmpty() ? "" : Character.toUpperCase(s.charAt(0)) + s.substring(1).toLowerCase(); 18 | } 19 | 20 | public static String normalizeLineEndings(String string) { 21 | return string.replaceAll("\\R", System.lineSeparator()); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/util/Tuple2.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.util; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | 5 | @NullMarked 6 | public record Tuple2(E1 e1, E2 e2) { 7 | 8 | public E1 e1() { 9 | return e1; 10 | } 11 | 12 | public E2 e2() { 13 | return e2; 14 | } 15 | 16 | public static Tuple2 of(E1 e1, E2 e2) { 17 | return new Tuple2<>(e1, e2); 18 | } 19 | 20 | public static Tuple2 ofSame(E e1, E e2) { 21 | return new Tuple2<>(e1, e2); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /compiler/src/main/java/info/teksol/mc/util/Tuple2Nullable.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.util; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | import org.jspecify.annotations.Nullable; 5 | 6 | @NullMarked 7 | public record Tuple2Nullable(E1 e1, E2 e2) { 8 | 9 | public E1 e1() { 10 | return e1; 11 | } 12 | 13 | public E2 e2() { 14 | return e2; 15 | } 16 | 17 | public static Tuple2Nullable of(E1 e1, E2 e2) { 18 | return new Tuple2Nullable<>(e1, e2); 19 | } 20 | 21 | public static Tuple2Nullable ofSame(E e1, E e2) { 22 | return new Tuple2Nullable<>(e1, e2); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /compiler/src/main/resources-filtered/info/teksol/mc/mindcode.properties: -------------------------------------------------------------------------------- 1 | # Version 2 | mindcode.version = ${revision} 3 | -------------------------------------------------------------------------------- /compiler/src/main/resources/META-INF/services/javax.annotation.processing.Processor: -------------------------------------------------------------------------------- 1 | info.teksol.annotations.processor.AstNodeAnnotationProcessor -------------------------------------------------------------------------------- /compiler/src/test/java/info/teksol/mc/VersionTest.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | import org.junit.jupiter.api.Assertions; 5 | import org.junit.jupiter.api.Test; 6 | 7 | @NullMarked 8 | class VersionTest { 9 | 10 | @Test 11 | void readsVersion() { 12 | Assertions.assertDoesNotThrow(Version::getVersion); 13 | } 14 | } -------------------------------------------------------------------------------- /compiler/src/test/java/info/teksol/mc/mindcode/compiler/antlr/AbstractParserTest.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.compiler.antlr; 2 | 3 | import info.teksol.mc.common.InputFiles; 4 | import info.teksol.mc.messages.ExpectedMessages; 5 | import info.teksol.mc.mindcode.compiler.AbstractTestBase; 6 | import info.teksol.mc.mindcode.compiler.CompilationPhase; 7 | import info.teksol.mc.mindcode.compiler.antlr.MindcodeParser.AstModuleContext; 8 | import org.jspecify.annotations.NullMarked; 9 | 10 | import java.util.Objects; 11 | 12 | @NullMarked 13 | public abstract class AbstractParserTest extends AbstractTestBase { 14 | 15 | protected CompilationPhase getTargetPhase() { 16 | return CompilationPhase.PARSER; 17 | } 18 | 19 | protected AstModuleContext parse(ExpectedMessages expectedMessages, InputFiles inputFiles) { 20 | return Objects.requireNonNull(process(expectedMessages, inputFiles, null, 21 | c -> c.getParseTree(inputFiles.getMainInputFile()))); 22 | } 23 | 24 | protected void assertParses(String source) { 25 | assertGeneratesMessages(expectedMessages(), source); 26 | } 27 | } -------------------------------------------------------------------------------- /compiler/src/test/java/info/teksol/mc/mindcode/compiler/functions/StandardFunctionHandlerTest.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.compiler.functions; 2 | 3 | import info.teksol.mc.mindcode.compiler.generation.AbstractCodeGeneratorTest; 4 | import org.junit.jupiter.api.Test; 5 | 6 | import static info.teksol.mc.mindcode.logic.opcodes.Opcode.UCONTROL; 7 | 8 | class StandardFunctionHandlerTest extends AbstractCodeGeneratorTest { 9 | 10 | @Test 11 | void compilesMissingFunctionArgument() { 12 | assertCompilesTo(""" 13 | getBlock(x, y, , out floor); 14 | """, 15 | createInstruction(UCONTROL, "getBlock", ":x", ":y", tmp(1), tmp(0), ":floor") 16 | ); 17 | } 18 | } -------------------------------------------------------------------------------- /compiler/src/test/java/info/teksol/mc/mindcode/compiler/optimization/OptimizationCoordinatorTest.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.compiler.optimization; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | import org.junit.jupiter.api.Test; 5 | 6 | import static org.junit.jupiter.api.Assertions.assertFalse; 7 | 8 | @NullMarked 9 | class OptimizationCoordinatorTest { 10 | 11 | @Test 12 | void debugFacilitiesAreInactive() { 13 | assertFalse(OptimizationCoordinator.TRACE, "TRACE is active"); 14 | assertFalse(OptimizationCoordinator.DEBUG_PRINT, "DEBUG_PRINT is active"); 15 | assertFalse(OptimizationCoordinator.IGNORE_UNINITIALIZED, "IGNORE_UNINITIALIZED is active"); 16 | } 17 | 18 | } -------------------------------------------------------------------------------- /compiler/src/test/java/info/teksol/mc/mindcode/compiler/preprocess/PreprocessorContextImpl.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.compiler.preprocess; 2 | 3 | import info.teksol.mc.messages.AbstractMessageEmitter; 4 | import info.teksol.mc.messages.MessageConsumer; 5 | import info.teksol.mc.profile.DirectiveProcessor; 6 | import org.jspecify.annotations.NullMarked; 7 | 8 | @NullMarked 9 | class PreprocessorContextImpl extends AbstractMessageEmitter implements PreprocessorContext { 10 | private final DirectiveProcessor directiveProcessor; 11 | 12 | PreprocessorContextImpl(MessageConsumer messageConsumer) { 13 | super(messageConsumer); 14 | this.directiveProcessor = new DirectiveProcessor(messageConsumer); 15 | } 16 | 17 | @Override 18 | public DirectiveProcessor directiveProcessor() { 19 | return directiveProcessor; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /compiler/src/test/java/info/teksol/mc/mindcode/tests/AlgorithmsSymbolicLabelsTest.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.tests; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | import org.junit.jupiter.api.AfterAll; 5 | import org.junit.jupiter.api.Order; 6 | 7 | import java.io.IOException; 8 | 9 | @NullMarked 10 | @Order(5) 11 | public class AlgorithmsSymbolicLabelsTest extends AlgorithmsTestBase { 12 | 13 | @AfterAll 14 | static void done() throws IOException { 15 | AbstractProcessorTest.done(SCRIPTS_DIRECTORY, AlgorithmsSymbolicLabelsTest.class.getSimpleName()); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /compiler/src/test/java/info/teksol/mc/mindcode/tests/AlgorithmsTest.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.tests; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | import org.junit.jupiter.api.AfterAll; 5 | import org.junit.jupiter.api.Order; 6 | 7 | import java.io.IOException; 8 | 9 | @NullMarked 10 | @Order(5) 11 | public class AlgorithmsTest extends AlgorithmsTestBase { 12 | 13 | @AfterAll 14 | static void done() throws IOException { 15 | AbstractProcessorTest.done(SCRIPTS_DIRECTORY, AlgorithmsTest.class.getSimpleName()); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /compiler/src/test/java/info/teksol/mc/mindcode/tests/CaseSwitcherProcessorTest.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.tests; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | import org.junit.jupiter.api.AfterAll; 5 | import org.junit.jupiter.api.Order; 6 | 7 | import java.io.IOException; 8 | 9 | @NullMarked 10 | @Order(5) 11 | public class CaseSwitcherProcessorTest extends CaseSwitcherProcessorTestBase { 12 | 13 | @AfterAll 14 | static void done() throws IOException { 15 | AbstractProcessorTest.done(SCRIPTS_DIRECTORY, CaseSwitcherProcessorTest.class.getSimpleName()); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /compiler/src/test/java/info/teksol/mc/mindcode/tests/CaseSwitcherSymbolicLabelsProcessorTest.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.tests; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | import org.junit.jupiter.api.AfterAll; 5 | import org.junit.jupiter.api.Order; 6 | 7 | import java.io.IOException; 8 | 9 | @NullMarked 10 | @Order(5) 11 | public class CaseSwitcherSymbolicLabelsProcessorTest extends CaseSwitcherProcessorTestBase { 12 | 13 | @AfterAll 14 | static void done() throws IOException { 15 | AbstractProcessorTest.done(SCRIPTS_DIRECTORY, CaseSwitcherSymbolicLabelsProcessorTest.class.getSimpleName()); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /compiler/src/test/java/info/teksol/mc/mindcode/tests/ProcessorSymbolicLabelsTest.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.tests; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | import org.junit.jupiter.api.AfterAll; 5 | import org.junit.jupiter.api.Order; 6 | 7 | import java.io.IOException; 8 | 9 | @NullMarked 10 | @Order(4) 11 | public class ProcessorSymbolicLabelsTest extends ProcessorTestBase { 12 | 13 | @AfterAll 14 | static void done() throws IOException { 15 | AbstractProcessorTest.done(SCRIPTS_DIRECTORY, ProcessorSymbolicLabelsTest.class.getSimpleName()); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /compiler/src/test/java/info/teksol/mc/mindcode/tests/ProcessorTest.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.mindcode.tests; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | import org.junit.jupiter.api.AfterAll; 5 | import org.junit.jupiter.api.Order; 6 | 7 | import java.io.IOException; 8 | 9 | @NullMarked 10 | @Order(4) 11 | public class ProcessorTest extends ProcessorTestBase { 12 | 13 | @AfterAll 14 | static void done() throws IOException { 15 | AbstractProcessorTest.done(SCRIPTS_DIRECTORY, ProcessorTest.class.getSimpleName()); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /compiler/src/test/java/info/teksol/mc/util/StringSimilarityTest.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mc.util; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | import org.junit.jupiter.api.Assertions; 5 | import org.junit.jupiter.api.Test; 6 | 7 | import java.util.Optional; 8 | 9 | @NullMarked 10 | class StringSimilarityTest { 11 | 12 | @Test 13 | public void findSimilarWordNone() { 14 | Optional bestAlternative = StringSimilarity.findBestAlternative("none", "false", "true"); 15 | Assertions.assertEquals("false", bestAlternative.orElseThrow()); 16 | } 17 | 18 | @Test 19 | public void findSimilarWordYes() { 20 | Optional bestAlternative = StringSimilarity.findBestAlternative("yes", "false", "true"); 21 | Assertions.assertEquals("true", bestAlternative.orElseThrow()); 22 | } 23 | } -------------------------------------------------------------------------------- /compiler/src/test/resources/info/teksol/mc/mindcode/tests/algorithms/array-reversion.mnd: -------------------------------------------------------------------------------- 1 | const SIZE = 10; 2 | 3 | var array[SIZE]; 4 | 5 | begin 6 | for var i in 0 ... SIZE do 7 | array[i] = i; 8 | end; 9 | 10 | reverse(out array); 11 | 12 | assertPrints("9876543210", print(array), "reverse array"); 13 | end; 14 | 15 | inline void reverse(array...) 16 | // We need to stop in the middle, otherwise the elements would get swapped twice 17 | var count = length(array) \ 2; 18 | for var out i in array; var out j in array descending do 19 | if --count < 0 then break; end; 20 | var t = i; i = j; j = t; 21 | end; 22 | end; 23 | -------------------------------------------------------------------------------- /compiler/src/test/resources/info/teksol/mc/mindcode/tests/algorithms/bubble-sort.mnd: -------------------------------------------------------------------------------- 1 | allocate stack in bank1[0...512]; 2 | param ARRAY = bank2; 3 | param FINAL = bank3; 4 | 5 | inline def testAndSwap(i, j, sorted) 6 | if (a = ARRAY[i]) > (b = ARRAY[j]) then 7 | ARRAY[i] = b; 8 | ARRAY[j] = a; 9 | false; 10 | else 11 | sorted; 12 | end; 13 | end; 14 | 15 | n = SIZE; 16 | do 17 | n -= 1; 18 | sorted = true; 19 | for i in 0 ... n do 20 | sorted = testAndSwap(i, i + 1, sorted); 21 | end; 22 | while !sorted; 23 | 24 | for i in 0 ... SIZE do 25 | assertEquals(FINAL[i], ARRAY[i], "unexpected value"); 26 | end; 27 | stopProcessor(); 28 | -------------------------------------------------------------------------------- /compiler/src/test/resources/info/teksol/mc/mindcode/tests/algorithms/compute-recursive-fibonacci.mnd: -------------------------------------------------------------------------------- 1 | allocate stack in bank1[0...512]; 2 | 3 | def fib(n) 4 | n < 2 ? n : fib(n - 1) + fib(n - 2); 5 | end; 6 | 7 | assertEquals(55, fib(10), "fib(10)"); 8 | stopProcessor(); 9 | -------------------------------------------------------------------------------- /compiler/src/test/resources/info/teksol/mc/mindcode/tests/algorithms/digit-counts.mnd: -------------------------------------------------------------------------------- 1 | const SIZE = 10; 2 | param LIMIT = 100; 3 | 4 | var array[SIZE]; 5 | 6 | begin 7 | for var out a in array do a = 0; end; 8 | 9 | for var i in 0 ... LIMIT do 10 | countDigits(i); 11 | end; 12 | 13 | assertPrints("10-20-20-20-20-20-20-20-20-20", printArray(), "digit counts"); 14 | end; 15 | 16 | void countDigits(number) 17 | do 18 | array[number % 10]++; 19 | number \= 10; 20 | while number > 0; 21 | end; 22 | 23 | void printArray() 24 | print(array[0]); 25 | for var i in 1 ... SIZE do 26 | print("-", array[i]); 27 | end; 28 | end; 29 | -------------------------------------------------------------------------------- /compiler/src/test/resources/info/teksol/mc/mindcode/tests/algorithms/insert-sort.mnd: -------------------------------------------------------------------------------- 1 | allocate stack in bank1[0...512]; 2 | param ARRAY = bank2; 3 | param FINAL = bank3; 4 | 5 | for i in 1 ... SIZE do 6 | item = ARRAY[i]; 7 | j = i - 1; 8 | while j >= 0 do 9 | if (a = ARRAY[j]) <= item then 10 | break; 11 | end; 12 | ARRAY[j + 1] = a; 13 | j -= 1; 14 | end; 15 | ARRAY[j + 1] = item; 16 | end; 17 | 18 | for i in 0 ... SIZE do 19 | assertEquals(FINAL[i], ARRAY[i], "unexpected value"); 20 | end; 21 | stopProcessor(); 22 | -------------------------------------------------------------------------------- /compiler/src/test/resources/info/teksol/mc/mindcode/tests/algorithms/memory-read-write-symbolic.log: -------------------------------------------------------------------------------- 1 | 5 instructions before optimizations. 2 | 1 instructions eliminated by Single Step Elimination (4 iterations). 3 | 4 instructions after optimizations. 4 | 5 | Modifications by Jumps phase, Single Step Elimination, pass 2, iteration 1 (-1 instructions): 6 | 7 | 1 read *tmp0 bank1 0 8 | 2 assertequals 10 *tmp0 "value from memory" 9 | 3 stop 10 | - * end 11 | 12 | Final code before resolving virtual instructions: 13 | 14 | write 10 bank1 0 15 | read *tmp0 bank1 0 16 | assertequals 10 *tmp0 "value from memory" 17 | stop 18 | -------------------------------------------------------------------------------- /compiler/src/test/resources/info/teksol/mc/mindcode/tests/algorithms/memory-read-write.log: -------------------------------------------------------------------------------- 1 | 5 instructions before optimizations. 2 | 1 instructions eliminated by Single Step Elimination (4 iterations). 3 | 4 instructions after optimizations. 4 | 5 | Modifications by Jumps phase, Single Step Elimination, pass 2, iteration 1 (-1 instructions): 6 | 7 | 1 read *tmp0 bank1 0 8 | 2 assertequals 10 *tmp0 "value from memory" 9 | 3 stop 10 | - * end 11 | 12 | Final code before resolving virtual instructions: 13 | 14 | write 10 bank1 0 15 | read *tmp0 bank1 0 16 | assertequals 10 *tmp0 "value from memory" 17 | stop 18 | -------------------------------------------------------------------------------- /compiler/src/test/resources/info/teksol/mc/mindcode/tests/algorithms/memory-read-write.mnd: -------------------------------------------------------------------------------- 1 | allocate heap in bank1[0...512]; 2 | $A = 10; 3 | assertEquals(10, $A, "value from memory"); 4 | stopProcessor(); 5 | -------------------------------------------------------------------------------- /compiler/src/test/resources/info/teksol/mc/mindcode/tests/algorithms/pascal-triangle.mnd: -------------------------------------------------------------------------------- 1 | #set syntax = strict; 2 | 3 | param TRIANGLE_SIZE = 10; 4 | 5 | var previousLine[10]; 6 | var currentLine[10]; 7 | 8 | begin 9 | var total = 3; // First two lines 10 | var lineLength = 2; 11 | 12 | previousLine[0] = 1; 13 | previousLine[1] = 1; 14 | 15 | for var i in 3 .. TRIANGLE_SIZE do 16 | currentLine[0] = 1; 17 | for var j in 1 .. lineLength do 18 | currentLine[j] = previousLine[j - 1] + previousLine[j]; 19 | end; 20 | currentLine[lineLength] = 1; 21 | lineLength++; 22 | 23 | for var c in 0 ... lineLength do 24 | total += currentLine[c]; 25 | previousLine[c] = currentLine[c]; 26 | end; 27 | end; 28 | 29 | assertEquals(1023, total, "Sum of Pascal triangle"); 30 | stopProcessor(); 31 | end; 32 | -------------------------------------------------------------------------------- /compiler/src/test/resources/info/teksol/mc/mindcode/tests/algorithms/select-sort.mnd: -------------------------------------------------------------------------------- 1 | allocate stack in bank1[0...512]; 2 | param ARRAY = bank2; 3 | param FINAL = bank3; 4 | 5 | for i in 0 ... SIZE - 1 do 6 | min = ARRAY[i]; 7 | min_index = i; 8 | for j in i + 1 ... SIZE do 9 | curr = ARRAY[j]; 10 | if curr < min then 11 | min = curr; 12 | min_index = j; 13 | end; 14 | end; 15 | ARRAY[min_index] = ARRAY[i]; 16 | ARRAY[i] = min; 17 | end; 18 | 19 | for i in 0 ... SIZE do 20 | assertEquals(FINAL[i], ARRAY[i], "unexpected value"); 21 | end; 22 | stopProcessor(); 23 | -------------------------------------------------------------------------------- /compiler/src/test/resources/info/teksol/mc/mindcode/tests/caseswitcher/CaseSwitcherConfigurationGeneratorTest.txt: -------------------------------------------------------------------------------- 1 | Strength;Improvement;distinct-0-none;distinct-1-zero;distinct-2-null;distinct-3-both;distinct-4-max;homogenous-0-none;homogenous-1-zero;homogenous-2-null;homogenous-3-both;homogenous-4-max;mixed-2-null 2 | 1;1004.59;0.00;0.00;0.00;0.00;0.00;0.00;0.00;0.00;0.00;0.00;11050.46 3 | 2;2.28;0.00;0.00;0.00;0.00;0.00;0.00;0.00;0.00;0.00;0.00;25.07 4 | 3;4.35;0.00;0.00;0.00;0.00;0.00;0.00;0.00;0.00;0.00;0.00;47.89 5 | 4;1.71;0.00;0.00;0.00;0.00;0.00;0.00;0.00;0.00;0.00;0.00;18.79 6 | 5;0.76;0.00;0.00;0.00;0.00;0.00;0.00;0.00;0.00;0.00;0.00;8.38 7 | 6;0.22;0.00;0.00;0.00;0.00;0.00;0.00;0.00;0.00;0.00;0.00;2.43 8 | -------------------------------------------------------------------------------- /compiler/src/test/resources/info/teksol/mc/mindcode/tests/caseswitcher/distinct-0-none.txt: -------------------------------------------------------------------------------- 1 | Strength;Configurations;Total steps;Avg steps;Avg improvement;Regression 2 | 1;3;24328;8109.33;0.00; 3 | 2;6;24328;8109.33;0.00; 4 | 3;22;24328;8109.33;0.00; 5 | 4;170;24328;8109.33;0.00; 6 | 5;2706;24328;8109.33;0.00; 7 | 6;78447;24328;8109.33;0.00; 8 | 9 | Strength;0;1;2;3;4;5;6 10 | Size 0;11904;11904;11904;11904;11904;11904;11904 11 | Size 2;520;520;520;520;520;520;520 12 | 13 | Strength;0;1;2;3;4;5;6 14 | Size 0;;;;;;; 15 | Size 2;;;;;;; 16 | -------------------------------------------------------------------------------- /compiler/src/test/resources/info/teksol/mc/mindcode/tests/caseswitcher/distinct-1-zero.txt: -------------------------------------------------------------------------------- 1 | Strength;Configurations;Total steps;Avg steps;Avg improvement;Regression 2 | 1;3;37793;9448.25;0.00; 3 | 2;6;37793;9448.25;0.00; 4 | 3;22;37793;9448.25;0.00; 5 | 4;170;37793;9448.25;0.00; 6 | 5;2706;37793;9448.25;0.00; 7 | 6;78447;37793;9448.25;0.00; 8 | 9 | Strength;0;1;2;3;4;5;6 10 | Size 0;12424;12424;12424;12424;12424;12424;12424 11 | Size 3;521;521;521;521;521;521;521 12 | 13 | Strength;0;1;2;3;4;5;6 14 | Size 0;;;;;;; 15 | Size 3;;;;;;; 16 | -------------------------------------------------------------------------------- /compiler/src/test/resources/info/teksol/mc/mindcode/tests/caseswitcher/distinct-2-null.txt: -------------------------------------------------------------------------------- 1 | Strength;Configurations;Total steps;Avg steps;Avg improvement;Regression 2 | 1;3;37646;9411.50;0.00; 3 | 2;6;37646;9411.50;0.00; 4 | 3;22;37646;9411.50;0.00; 5 | 4;170;37646;9411.50;0.00; 6 | 5;2706;37646;9411.50;0.00; 7 | 6;83857;37646;9411.50;0.00; 8 | 9 | Strength;0;1;2;3;4;5;6 10 | Size 0;12375;12375;12375;12375;12375;12375;12375 11 | Size 3;521;521;521;521;521;521;521 12 | 13 | Strength;0;1;2;3;4;5;6 14 | Size 0;;;;;;; 15 | Size 3;;;;;;; 16 | -------------------------------------------------------------------------------- /compiler/src/test/resources/info/teksol/mc/mindcode/tests/caseswitcher/distinct-3-both.txt: -------------------------------------------------------------------------------- 1 | Strength;Configurations;Total steps;Avg steps;Avg improvement;Regression 2 | 1;3;39206;9801.50;0.00; 3 | 2;6;39206;9801.50;0.00; 4 | 3;22;39206;9801.50;0.00; 5 | 4;170;39206;9801.50;0.00; 6 | 5;2706;39206;9801.50;0.00; 7 | 6;83857;39206;9801.50;0.00; 8 | 9 | Strength;0;1;2;3;4;5;6 10 | Size 0;12895;12895;12895;12895;12895;12895;12895 11 | Size 3;521;521;521;521;521;521;521 12 | 13 | Strength;0;1;2;3;4;5;6 14 | Size 0;;;;;;; 15 | Size 3;;;;;;; 16 | -------------------------------------------------------------------------------- /compiler/src/test/resources/info/teksol/mc/mindcode/tests/caseswitcher/distinct-4-max.txt: -------------------------------------------------------------------------------- 1 | Strength;Configurations;Total steps;Avg steps;Avg improvement;Regression 2 | 1;3;40613;10153.25;0.00; 3 | 2;6;40613;10153.25;0.00; 4 | 3;22;40613;10153.25;0.00; 5 | 4;170;40613;10153.25;0.00; 6 | 5;2706;40613;10153.25;0.00; 7 | 6;86562;40613;10153.25;0.00; 8 | 9 | Strength;0;1;2;3;4;5;6 10 | Size 0;13364;13364;13364;13364;13364;13364;13364 11 | Size 3;521;521;521;521;521;521;521 12 | 13 | Strength;0;1;2;3;4;5;6 14 | Size 0;;;;;;; 15 | Size 3;;;;;;; 16 | -------------------------------------------------------------------------------- /compiler/src/test/resources/info/teksol/mc/mindcode/tests/caseswitcher/homogenous-0-none.txt: -------------------------------------------------------------------------------- 1 | Strength;Configurations;Total steps;Avg steps;Avg improvement;Regression 2 | 1;3;12920;4306.67;0.00; 3 | 2;6;12920;4306.67;0.00; 4 | 3;22;12920;4306.67;0.00; 5 | 4;170;12920;4306.67;0.00; 6 | 5;1409;12920;4306.67;0.00; 7 | 6;6093;12920;4306.67;0.00; 8 | 9 | Strength;0;1;2;3;4;5;6 10 | Size 0;6200;6200;6200;6200;6200;6200;6200 11 | Size 2;520;520;520;520;520;520;520 12 | 13 | Strength;0;1;2;3;4;5;6 14 | Size 0;;;;;;; 15 | Size 2;;;;;;; 16 | -------------------------------------------------------------------------------- /compiler/src/test/resources/info/teksol/mc/mindcode/tests/caseswitcher/homogenous-1-zero.txt: -------------------------------------------------------------------------------- 1 | Strength;Configurations;Total steps;Avg steps;Avg improvement;Regression 2 | 1;3;19826;4956.50;0.00; 3 | 2;6;19826;4956.50;0.00; 4 | 3;22;19826;4956.50;0.00; 5 | 4;170;19826;4956.50;0.00; 6 | 5;2009;19826;4956.50;0.00; 7 | 6;18143;19826;4956.50;0.00; 8 | 9 | Strength;0;1;2;3;4;5;6 10 | Size 0;6435;6435;6435;6435;6435;6435;6435 11 | Size 3;521;521;521;521;521;521;521 12 | 13 | Strength;0;1;2;3;4;5;6 14 | Size 0;;;;;;; 15 | Size 3;;;;;;; 16 | -------------------------------------------------------------------------------- /compiler/src/test/resources/info/teksol/mc/mindcode/tests/caseswitcher/homogenous-2-null.txt: -------------------------------------------------------------------------------- 1 | Strength;Configurations;Total steps;Avg steps;Avg improvement;Regression 2 | 1;3;19901;4975.25;0.00; 3 | 2;6;19901;4975.25;0.00; 4 | 3;22;19901;4975.25;0.00; 5 | 4;170;19901;4975.25;0.00; 6 | 5;1409;19901;4975.25;0.00; 7 | 6;6093;19901;4975.25;0.00; 8 | 9 | Strength;0;1;2;3;4;5;6 10 | Size 0;6460;6460;6460;6460;6460;6460;6460 11 | Size 3;521;521;521;521;521;521;521 12 | 13 | Strength;0;1;2;3;4;5;6 14 | Size 0;;;;;;; 15 | Size 3;;;;;;; 16 | -------------------------------------------------------------------------------- /compiler/src/test/resources/info/teksol/mc/mindcode/tests/caseswitcher/homogenous-3-both.txt: -------------------------------------------------------------------------------- 1 | Strength;Configurations;Total steps;Avg steps;Avg improvement;Regression 2 | 1;3;20606;5151.50;0.00; 3 | 2;6;20606;5151.50;0.00; 4 | 3;22;20606;5151.50;0.00; 5 | 4;170;20606;5151.50;0.00; 6 | 5;2009;20606;5151.50;0.00; 7 | 6;18143;20606;5151.50;0.00; 8 | 9 | Strength;0;1;2;3;4;5;6 10 | Size 0;6695;6695;6695;6695;6695;6695;6695 11 | Size 3;521;521;521;521;521;521;521 12 | 13 | Strength;0;1;2;3;4;5;6 14 | Size 0;;;;;;; 15 | Size 3;;;;;;; 16 | -------------------------------------------------------------------------------- /compiler/src/test/resources/info/teksol/mc/mindcode/tests/caseswitcher/homogenous-4-max.txt: -------------------------------------------------------------------------------- 1 | Strength;Configurations;Total steps;Avg steps;Avg improvement;Regression 2 | 1;3;21308;5327.00;0.00; 3 | 2;6;21308;5327.00;0.00; 4 | 3;22;21308;5327.00;0.00; 5 | 4;170;21308;5327.00;0.00; 6 | 5;2368;21308;5327.00;0.00; 7 | 6;26494;21308;5327.00;0.00; 8 | 9 | Strength;0;1;2;3;4;5;6 10 | Size 0;6929;6929;6929;6929;6929;6929;6929 11 | Size 3;521;521;521;521;521;521;521 12 | 13 | Strength;0;1;2;3;4;5;6 14 | Size 0;;;;;;; 15 | Size 3;;;;;;; 16 | -------------------------------------------------------------------------------- /compiler/src/test/resources/info/teksol/mc/mindcode/tests/euler/EulerSymbolicLabelsTest.txt: -------------------------------------------------------------------------------- 1 | Name Instructions Steps Coverage Source CRC Compiled CRC 2 | project-euler-04.mnd: 21 42870 100.0% 485ABBCEBCE63451 FD841218A873FD0F 3 | project-euler-18.mnd: 837 837 100.0% 9CD1F51670FF2A5D 9CE943EDD40E9E31 4 | project-euler-26.mnd: 520 4923 68.6% 6C7318A31C223AA5 58010236F5A641F8 5 | project-euler-28.mnd: 13 11006 100.0% 5C943F9BE29F7DE5 774E5F03732D2B4B 6 | project-euler-31.mnd: 61 11310 98.3% 47A4CC119289380D CE4D7CBF76E98FE6 7 | project-euler-31b.mnd: 460 8244 100.0% 08C1247BD928B046 9DAB6A6314632321 8 | project-euler-45.mnd: 14 265002 100.0% 75B12E5E9F981D9A AFFF8287A3D19F62 9 | project-euler-97.mnd: 11 11579 100.0% 0ED039F2AEA675BF BDA161907D4918B5 10 | -------------------------------------------------------------------------------- /compiler/src/test/resources/info/teksol/mc/mindcode/tests/euler/EulerTest.txt: -------------------------------------------------------------------------------- 1 | Name Instructions Steps Coverage Source CRC Compiled CRC 2 | project-euler-04.mnd: 21 42870 100.0% 485ABBCEBCE63451 34D8A67004A4C7D3 3 | project-euler-18.mnd: 837 837 100.0% 9CD1F51670FF2A5D 0AAC86C9F63BCE49 4 | project-euler-26.mnd: 520 4923 68.6% 6C7318A31C223AA5 7CE5AAFF4354C9B8 5 | project-euler-28.mnd: 13 11006 100.0% 5C943F9BE29F7DE5 01C78654215D499C 6 | project-euler-31.mnd: 59 11017 98.3% 47A4CC119289380D F34F95C1F28C98EC 7 | project-euler-31b.mnd: 460 8244 100.0% 08C1247BD928B046 B6B969BD99B6D7CE 8 | project-euler-45.mnd: 14 265002 100.0% 75B12E5E9F981D9A 5E1A2726096B69F6 9 | project-euler-97.mnd: 11 11579 100.0% 0ED039F2AEA675BF 20E5544733C95CF7 10 | -------------------------------------------------------------------------------- /compiler/src/test/resources/info/teksol/mc/mindcode/tests/euler/project-euler-04.mnd: -------------------------------------------------------------------------------- 1 | const LIMIT = 100; 2 | max = 0; 3 | 4 | for i in 10 ... LIMIT do 5 | for j in i ... LIMIT do 6 | num = i * j; 7 | if num > max then 8 | if num == revert(num) then 9 | max = num; 10 | end; 11 | end; 12 | end; 13 | end; 14 | 15 | assertEquals(9009, max, "Project Euler 4"); 16 | stopProcessor(); 17 | 18 | def revert(num) 19 | res = 0; 20 | while num > 0 do 21 | res = 10 * res + num % 10; 22 | num \= 10; 23 | end; 24 | res; 25 | end; 26 | -------------------------------------------------------------------------------- /compiler/src/test/resources/info/teksol/mc/mindcode/tests/euler/project-euler-26.mnd: -------------------------------------------------------------------------------- 1 | const LIMIT = 100; 2 | maxlen = 0; 3 | maxnum = 0; 4 | for d in 2 .. LIMIT do 5 | len = getRepeatLength(d); 6 | if len > maxlen then 7 | maxlen = len; 8 | maxnum = d; 9 | end; 10 | end; 11 | 12 | assertEquals(97, maxnum, "Project Euler 26"); 13 | stopProcessor(); 14 | 15 | def getRepeatLength(d) 16 | n = d; 17 | while n % 5 == 0 do n /= 5; end; 18 | while n % 2 == 0 do n /= 2; end; 19 | if n < 2 then 20 | return 0; 21 | end; 22 | 23 | power = 1; 24 | for i in 1 ... LIMIT do 25 | power = power * 10 % n; 26 | if power == 1 then 27 | return i; 28 | end; 29 | end; 30 | 31 | print("Power of ten limit reached."); 32 | end(); 33 | end; 34 | -------------------------------------------------------------------------------- /compiler/src/test/resources/info/teksol/mc/mindcode/tests/euler/project-euler-28.mnd: -------------------------------------------------------------------------------- 1 | const GOAL = 1001; 2 | const LIMIT = GOAL * GOAL; 3 | sum = 1; 4 | current = 3; 5 | step = 2; 6 | count = 1; 7 | 8 | while current <= LIMIT do 9 | sum += current; 10 | current += step; 11 | count += 1; 12 | if count > 3 then 13 | step += 2; 14 | count = 0; 15 | end; 16 | end; 17 | 18 | assertEquals(669171001, sum, "Project Euler 28"); 19 | stopProcessor(); 20 | -------------------------------------------------------------------------------- /compiler/src/test/resources/info/teksol/mc/mindcode/tests/euler/project-euler-31.mnd: -------------------------------------------------------------------------------- 1 | allocate stack in bank1[16 ... 512]; 2 | const COINS = 8; 3 | index = 0; 4 | for value in 200, 100, 50, 20, 10, 5, 2, 1 do 5 | bank1[index] = value; 6 | index += 1; 7 | end; 8 | 9 | assertEquals(41, ways(20, 1), "Project Euler 31"); 10 | stopProcessor(); 11 | 12 | def ways(amount, index) 13 | if amount == 0 then 14 | return 1; 15 | end; 16 | 17 | result = 0; 18 | // TODO The optimizer should recognize it can use index instead of i in the loop, saving one variable 19 | for i in index ... COINS do 20 | p = bank1[i]; 21 | if p <= amount then 22 | result += ways(amount - p, i); 23 | end; 24 | end; 25 | result; 26 | end; 27 | -------------------------------------------------------------------------------- /compiler/src/test/resources/info/teksol/mc/mindcode/tests/euler/project-euler-31b.mnd: -------------------------------------------------------------------------------- 1 | allocate stack in bank1[16 ... 512]; 2 | const AMOUNT = 200; 3 | bank2[0] = 1; 4 | for i in 1, 2, 5, 10, 20, 50, 100, 200 do 5 | for j in i .. AMOUNT do 6 | bank2[j] += bank2[j - i]; 7 | end; 8 | end; 9 | 10 | assertEquals(73682, bank2[AMOUNT], "Project Euler 31b"); 11 | stopProcessor(); 12 | -------------------------------------------------------------------------------- /compiler/src/test/resources/info/teksol/mc/mindcode/tests/euler/project-euler-45.mnd: -------------------------------------------------------------------------------- 1 | p = 165; 2 | h = 143; 3 | p += 1; 4 | 5 | pn = p * (3 * p - 1) \ 2; 6 | hn = h * (2 * h - 1); 7 | 8 | p = 3 * p + 1; 9 | h = 4 * h + 1; 10 | 11 | while true do 12 | if pn < hn then 13 | pn += p; 14 | p += 3; 15 | elsif hn < pn then 16 | hn += h; 17 | h += 4; 18 | else 19 | break; 20 | end; 21 | end; 22 | 23 | assertEquals(1533776805, hn, "Project Euler 45"); 24 | stopProcessor(); 25 | 26 | -------------------------------------------------------------------------------- /compiler/src/test/resources/info/teksol/mc/mindcode/tests/euler/project-euler-97.mnd: -------------------------------------------------------------------------------- 1 | const START = 28433; 2 | const LIMIT = 57862; 3 | const DIGITS = 10 * 1000 * 1000 * 1000; 4 | const SHIFT = 20; 5 | 6 | // TODO Compute with better modular arithmetics 7 | result = START; 8 | count = LIMIT; 9 | while count > SHIFT do 10 | result = (result << SHIFT) % DIGITS; 11 | count -= SHIFT; 12 | end; 13 | 14 | result = ((result << count) + 1) % DIGITS; 15 | 16 | assertEquals(7075090433, result, "Project Euler 97"); 17 | stopProcessor(); 18 | -------------------------------------------------------------------------------- /compiler/src/test/resources/info/teksol/mc/mindcode/tests/optimizer/remote-vault-00.mnd: -------------------------------------------------------------------------------- 1 | param LINK_ID = 1; 2 | const QUERY_BASE = 99999900; 3 | QUERY_FLAG = QUERY_BASE + LINK_ID; 4 | position = 100 * (vault1.@x + @mapw * vault1.@y); 5 | ANSWER_FLAG = position + LINK_ID; 6 | SERVICED = 0; 7 | 8 | while true do 9 | start = @time; 10 | procesUnit(@mono); 11 | procesUnit(@poly); 12 | procesUnit(@mega); 13 | procesUnit(@quad); 14 | procesUnit(@oct); 15 | procesUnit(@flare); 16 | procesUnit(@horizon); 17 | procesUnit(@zenith); 18 | procesUnit(@antumbra); 19 | procesUnit(@eclipse); 20 | println($"Remote vault [gold]#$LINK_ID[]"); 21 | println($"Queries serviced: [green]$SERVICED[]"); 22 | println($"[lightgray]Loop time: $ ms", floor(@time - start)); 23 | printflush(message1); 24 | end; 25 | 26 | inline def procesUnit(unit) 27 | ubind(unit); 28 | if @unit.@flag == QUERY_FLAG then 29 | flag(ANSWER_FLAG); 30 | SERVICED += 1; 31 | end; 32 | end; 33 | -------------------------------------------------------------------------------- /compiler/src/test/resources/info/teksol/mc/mindcode/tests/processor/assignments-in-expressions.mnd: -------------------------------------------------------------------------------- 1 | param a = 1; 2 | param b = 2; 3 | A = a; 4 | B = A; 5 | 6 | // The preferred results might be "3", "4": see #96 7 | assertEquals(4, A + (A += 1), "A + (A += 1)"); 8 | assertEquals(4, (B += 1) + B, "(B += 1) + B"); 9 | 10 | def test() 11 | if res = a < b then 12 | print("yes"); 13 | end; 14 | print(res); 15 | end; 16 | 17 | assertPrints("yes1", test(), "assignments in conditions"); 18 | 19 | stopProcessor(); 20 | -------------------------------------------------------------------------------- /compiler/src/test/resources/info/teksol/mc/mindcode/tests/processor/complex-case-expression.mnd: -------------------------------------------------------------------------------- 1 | noinline def d(n) n; end; 2 | 3 | def test() 4 | for i in d(1) .. d(10) do 5 | str = case i 6 | when d(1) then "A"; 7 | when d(2), d(3), 4 then "B"; 8 | when 5 then continue; 9 | when d(6) .. d(8) then "C"; 10 | when 10 then break; 11 | else "D"; 12 | end; 13 | print(str); 14 | end; 15 | end; 16 | 17 | assertPrints("ABBBCCCD", test(), "complex-case-expression"); 18 | stopProcessor(); 19 | -------------------------------------------------------------------------------- /compiler/src/test/resources/info/teksol/mc/mindcode/tests/processor/executes-sort-variables.mnd: -------------------------------------------------------------------------------- 1 | #set sort-variables; 2 | param p = 1; 3 | 4 | def test() 5 | var step = p; 6 | for var out i in a, b, c, d do 7 | i = step; 8 | step *= 2; 9 | end; 10 | print(a, b, c, d); 11 | end; 12 | 13 | begin 14 | assertPrints("1248", test(), "sort variables"); 15 | stopProcessor(); 16 | end; 17 | -------------------------------------------------------------------------------- /compiler/src/test/resources/info/teksol/mc/mindcode/tests/processor/fixed-bounds-ranged-for.mnd: -------------------------------------------------------------------------------- 1 | param a = 10; 2 | b = 20; 3 | for i in a ... b do 4 | b = b - 1; 5 | end; 6 | assertEquals(10, b, "fixed-bounds-ranged-for"); 7 | stopProcessor(); 8 | -------------------------------------------------------------------------------- /compiler/src/test/resources/info/teksol/mc/mindcode/tests/processor/for-each-loop-break-continue.mnd: -------------------------------------------------------------------------------- 1 | noinline def d(n) n; end; 2 | 3 | def test() 4 | for i in 1, d(2), 3, d(5), 8, d(12), 15 do 5 | if d(i) == 3 then continue; end; 6 | print(i, "|"); 7 | if d(i) == 12 then break; end; 8 | end; 9 | end; 10 | 11 | assertPrints("1|2|5|8|12|", test(), "iterated-for-loop-break-continue"); 12 | stopProcessor(); 13 | -------------------------------------------------------------------------------- /compiler/src/test/resources/info/teksol/mc/mindcode/tests/processor/function-inlining.mnd: -------------------------------------------------------------------------------- 1 | def foo(n) 2 | sum = 0; 3 | r = rand(10); // Prevents compile-time evaluation 4 | for i in 0 ... 50 do 5 | sum += n + r; 6 | end; 7 | print(floor(sum - 50 * r + 0.5), "|"); 8 | end; 9 | 10 | def bar(s) 11 | foo(10 + s); 12 | foo(20 + s); 13 | foo(30 + s); 14 | foo(40 + s); 15 | end; 16 | 17 | def test() 18 | bar(1); 19 | bar(2); 20 | bar(3); 21 | bar(4); 22 | end; 23 | 24 | assertPrints( 25 | "550|1050|1550|2050|600|1100|1600|2100|650|1150|1650|2150|700|1200|1700|2200|", 26 | test(), 27 | "function-inlining"); 28 | stopProcessor(); 29 | -------------------------------------------------------------------------------- /compiler/src/test/resources/info/teksol/mc/mindcode/tests/processor/iterated-for-loop-break-continue.mnd: -------------------------------------------------------------------------------- 1 | noinline def d(n) n; end; 2 | 3 | def test() 4 | for i = 0, j = 10; d(i) <= d(j); i += 2, j += 1 do 5 | if d(i) == 4 then continue; end; 6 | print(i, "|", j, "|"); 7 | if d(i) == 10 then break; end; 8 | end; 9 | end; 10 | 11 | assertPrints("0|10|2|11|6|13|8|14|10|15|", test(), "iterated-for-loop-break-continue"); 12 | stopProcessor(); 13 | -------------------------------------------------------------------------------- /compiler/src/test/resources/info/teksol/mc/mindcode/tests/processor/loops-in-conditions.mnd: -------------------------------------------------------------------------------- 1 | inline def sum(n) 2 | c = 0; 3 | for i in 0 ... n do 4 | c += i; 5 | end; 6 | print(c, "|"); 7 | return c; 8 | end; 9 | 10 | def test() 11 | result = if sum(4) < sum(8) then 12 | print("Less"); 13 | 0; 14 | else 15 | 1; 16 | end; 17 | print("|", result); 18 | end; 19 | 20 | assertPrints("6|28|Less|0", test(), "loops in conditions"); 21 | stopProcessor(); 22 | -------------------------------------------------------------------------------- /compiler/src/test/resources/info/teksol/mc/mindcode/tests/processor/prints-values.mnd: -------------------------------------------------------------------------------- 1 | param a = 1; 2 | param b = 0; 3 | param p = @coal; 4 | 5 | assertPrints("Hello", print("Hello"), "prints Hello"); 6 | assertPrints("10", print(10), "prints 10"); 7 | assertPrints("5.5", print(5.5), "prints 5.5"); 8 | assertPrints("bank", print(bank1), "prints bank"); 9 | assertPrints("memory-bank", print(bank1.@type), "prints memory-bank"); 10 | assertPrints("null", print(null), "prints null"); 11 | assertPrints("1", print(true), "prints true"); 12 | assertPrints("0", print(false), "prints false"); 13 | assertPrints("null", print(a / b), "prints 1 / 0"); 14 | assertPrints("5", print(p.@id), "prints @coal.@id"); 15 | assertPrints("0", print(packcolor(1,1,1,1)), "prints packcolor"); 16 | 17 | x = y = @counter; 18 | assertEquals(x, y, "chained assignments"); 19 | 20 | stopProcessor(); 21 | -------------------------------------------------------------------------------- /compiler/src/test/resources/info/teksol/mc/mindcode/tests/processor/ranged-for-loop-break-continue.mnd: -------------------------------------------------------------------------------- 1 | noinline def d(n) n; end; 2 | 3 | def test() 4 | for i in d(1) ... d(10) do 5 | if i == 3 then continue; end; 6 | print(i, "|"); 7 | if i == d(5) then break; end; 8 | end; 9 | end; 10 | 11 | assertPrints("1|2|4|5|", test(), "iterated-for-loop-break-continue"); 12 | stopProcessor(); 13 | -------------------------------------------------------------------------------- /compiler/src/test/resources/info/teksol/mc/mindcode/tests/processor/recursive-calls.mnd: -------------------------------------------------------------------------------- 1 | allocate stack in bank1; 2 | 3 | def foo(n, a, b) 4 | print(a, b); 5 | a = a + 1; 6 | if n > 0 then 7 | foo(n - 1, b, a); 8 | end; 9 | b = b + 1; 10 | print(a, b); 11 | end; 12 | 13 | def bar(n, in out a, in out b) 14 | print(a, b); 15 | a = a + 1; 16 | if n > 0 then 17 | bar(n - 1, out b, out a); 18 | end; 19 | b = b + 1; 20 | print(a, b); 21 | end; 22 | 23 | def baz(n, in out a, in out b) 24 | print(a, b); 25 | a = a + 1; 26 | if n > 0 then 27 | baz(n - 1, in b, in a); 28 | end; 29 | b = b + 1; 30 | print(a, b); 31 | end; 32 | 33 | assertPrints("0001111223221211", foo(3, in 0, in 0), "foo"); 34 | assertPrints("0001111223333444", bar(3, in 0, in 0), "bar"); 35 | assertPrints("0001111223221211", baz(3, in 0, in 0), "baz"); 36 | stopProcessor(); 37 | -------------------------------------------------------------------------------- /compiler/src/test/resources/info/teksol/mc/mindcode/tests/processor/recursive-function-condition.mnd: -------------------------------------------------------------------------------- 1 | allocate stack in bank1[0...512]; 2 | 3 | def foo(n) 4 | n > 0 ? foo(n - 1) : 10; 5 | end; 6 | 7 | assertEquals(10, foo(1), "recursive-function-condition"); 8 | stopProcessor(); 9 | -------------------------------------------------------------------------------- /compiler/src/test/resources/info/teksol/mc/mindcode/tests/processor/while-loop.mnd: -------------------------------------------------------------------------------- 1 | noinline def d(n) n; end; 2 | 3 | def test() 4 | i = d(j = d(0)); 5 | while i < 10 do 6 | print(j += i, "|"); 7 | i += 1; 8 | end; 9 | end; 10 | 11 | assertPrints("0|1|3|6|10|15|21|28|36|45|", test(), "while-loop"); 12 | stopProcessor(); 13 | -------------------------------------------------------------------------------- /compiler/src/test/resources/junit-platform.properties: -------------------------------------------------------------------------------- 1 | junit.platform.output.capture.stdout = true 2 | junit.platform.output.capture.stderr = true 3 | junit.jupiter.execution.parallel.enabled = true 4 | junit.jupiter.execution.parallel.mode.default = concurrent 5 | junit.jupiter.execution.parallel.mode.classes.default = concurrent 6 | junit.jupiter.testclass.order.default = org.junit.jupiter.api.ClassOrderer$OrderAnnotation 7 | -------------------------------------------------------------------------------- /compiler/src/test/resources/library/outputs/arrays.mnd: -------------------------------------------------------------------------------- 1 | require arrays; 2 | 3 | param p = 0; 4 | var a[5]; 5 | var b[10]; 6 | var c[10]; 7 | 8 | begin 9 | fill(ref a, "x"); 10 | assertPrints("xxxxx", print(a), "Array fill"); 11 | 12 | for var i in 0 ... length(b) do 13 | b[i] = p + i; 14 | c[i] = p + i; 15 | end; 16 | 17 | reverse(ref b); 18 | assertPrints("9876543210", print(b), "Array reverse"); 19 | 20 | bubblesort(ref b, false); 21 | assertPrints("0123456789", print(b), "Array sort 1"); 22 | 23 | bubblesort(ref b, ref c, true); 24 | assertPrints("9876543210", print(c), "Array sort 2"); 25 | end; 26 | -------------------------------------------------------------------------------- /compiler/src/test/resources/library/outputs/blocks.mnd: -------------------------------------------------------------------------------- 1 | // Unit test for blocks system library 2 | 3 | require blocks; 4 | 5 | linked message1; 6 | 7 | begin 8 | var display, message, switch, memory; 9 | 10 | findLinkedBlocks("Example program.\nTrying to locate linked blocks", message1, 11 | @large-logic-display, "Display", out display, true, 12 | @message, "Message", out message, false, 13 | @switch, "Switch", out switch, false, 14 | @memory-bank, "Memory", out memory, true, 15 | @memory-cell, "Memory", out memory, true 16 | ); 17 | 18 | assertEquals(message, message1, "Located message1 block"); 19 | end; 20 | -------------------------------------------------------------------------------- /compiler/src/test/resources/library/outputs/units.mnd: -------------------------------------------------------------------------------- 1 | require units; 2 | 3 | begin 4 | 5 | var initial_flag = null; 6 | var message = null; 7 | var preface = null; 8 | var radius = null; 9 | var unit_type = null; 10 | var x = null; 11 | var y = null; 12 | 13 | println(noControlWithin(x, y, radius)); 14 | println(findFreeUnit(unit_type, initial_flag)); 15 | println(findClosestUnit(x, y, unit_type, initial_flag)); 16 | println(waitForFreeUnit(unit_type, initial_flag)); 17 | println(waitForFreeUnit(message, preface, unit_type, initial_flag)); 18 | 19 | end; -------------------------------------------------------------------------------- /compiler/src/test/resources/library/tests/arrays.mnd: -------------------------------------------------------------------------------- 1 | require arrays; 2 | 3 | param p = 0; 4 | var a[5]; 5 | var b[10]; 6 | var c[10]; 7 | 8 | begin 9 | fill(ref a, "x"); 10 | assertPrints("xxxxx", print(a), "Array fill"); 11 | 12 | for var i in 0 ... length(b) do 13 | b[i] = p + i; 14 | c[i] = p + i; 15 | end; 16 | 17 | reverse(ref b); 18 | assertPrints("9876543210", print(b), "Array reverse"); 19 | 20 | bubblesort(ref b, false); 21 | assertPrints("0123456789", print(b), "Array sort 1"); 22 | 23 | bubblesort(ref b, ref c, true); 24 | assertPrints("9876543210", print(c), "Array sort 2"); 25 | end; 26 | -------------------------------------------------------------------------------- /compiler/src/test/resources/library/tests/blocks.mnd: -------------------------------------------------------------------------------- 1 | // Unit test for blocks system library 2 | 3 | require blocks; 4 | 5 | linked message1; 6 | 7 | begin 8 | var display, message, switch, memory; 9 | 10 | findLinkedBlocks("Example program.\nTrying to locate linked blocks", message1, 11 | @large-logic-display, "Display", out display, true, 12 | @message, "Message", out message, false, 13 | @switch, "Switch", out switch, false, 14 | @memory-bank, "Memory", out memory, true, 15 | @memory-cell, "Memory", out memory, true 16 | ); 17 | 18 | assertEquals(message, message1, "Located message1 block"); 19 | end; 20 | -------------------------------------------------------------------------------- /doc/syntax/TUTORIAL-MINDCODE.markdown: -------------------------------------------------------------------------------- 1 | # Mindcode tutorial 2 | 3 | This tutorial will guide you through creating a few simple programs in Mindcode. -------------------------------------------------------------------------------- /docker-compose.yaml: -------------------------------------------------------------------------------- 1 | services: 2 | 3 | mindcode-db: 4 | image: postgres:13 5 | restart: on-failure 6 | environment: 7 | POSTGRES_DB: mindcode_development 8 | POSTGRES_USER: postgres 9 | POSTGRES_PASSWORD: pg_password 10 | volumes: 11 | - mindcode-postgres-data:/var/lib/postgresql/data 12 | ports: 13 | - "5432:5432" 14 | 15 | mindcode-web: 16 | build: 17 | context: . 18 | 19 | depends_on: 20 | - mindcode-db 21 | ports: 22 | - "127.0.0.1:8080:8080" 23 | 24 | volumes: 25 | mindcode-postgres-data: 26 | driver: local 27 | -------------------------------------------------------------------------------- /errors/001-loop-unroller.log: -------------------------------------------------------------------------------- 1 | Internal error: Jump instruction not allowed in BODY subcontext.BaseInstruction{astContext.id: 149, opcode='jump', args=[LogicLabel{label='__label53'}, EQUAL, TRUE, FALSE]} 2 | -------------------------------------------------------------------------------- /errors/001-loop-unroller.mlog: -------------------------------------------------------------------------------- 1 | print "Error" 2 | 3 | -------------------------------------------------------------------------------- /errors/001-loop-unroller.mnd: -------------------------------------------------------------------------------- 1 | #set optimization = experimental; 2 | 3 | print(foo()); 4 | 5 | inline def foo() 6 | for i in 1 .. 1 do 7 | if bar(i) then 8 | return i; 9 | end; 10 | end; 11 | "Error"; 12 | end; 13 | 14 | inline def bar(n) 15 | lt = gt = 0; 16 | for i in 1 .. 1 do 17 | if i < n then 18 | lt += 1; 19 | elsif i > n then 20 | gt += 1; 21 | end; 22 | end; 23 | dif = abs(gt - lt); 24 | if gt + lt >= length(x) - 1 then 25 | true; 26 | else 27 | false; 28 | end; 29 | end; -------------------------------------------------------------------------------- /errors/002-dfo.mlog: -------------------------------------------------------------------------------- 1 | set __tmp1 11 2 | set __tmp3 7 3 | jump 4 always 0 0 4 | jump 6 always 0 0 5 | jump 6 always 0 0 6 | jump 6 always 0 0 7 | set @counter __tmp3 8 | jump 8 always 0 0 9 | jump 11 always 0 0 10 | jump 10 always 0 0 11 | set @counter __tmp1 12 | print "Error" 13 | end 14 | print "Compiled by Mindcode - github.com/cardillan/mindcode" 15 | 16 | -------------------------------------------------------------------------------- /errors/002-dfo.mnd: -------------------------------------------------------------------------------- 1 | #set optimization = none; 2 | #set data-flow-optimization = advanced; 3 | #set function-inlining = advanced; 4 | #set if-expression-optimization = advanced; 5 | #set jump-normalization = advanced; 6 | #set loop-hoisting = advanced; 7 | 8 | print(foo(1)); 9 | 10 | inline def foo(y...) 11 | for j in y do 12 | if bar(j, y) then 13 | return j; 14 | end; 15 | end; 16 | "Error"; 17 | end; 18 | 19 | inline def bar(n, x...) 20 | lt = gt = 0; 21 | for i in x do 22 | if i < n then 23 | lt += 1; 24 | elsif i > n then 25 | gt += 1; 26 | end; 27 | end; 28 | dif = abs(gt - lt); 29 | if gt + lt >= length(x) - 1 then 30 | true; 31 | else 32 | false; 33 | end; 34 | end; 35 | -------------------------------------------------------------------------------- /exttest/.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | !.mvn/wrapper/maven-wrapper.jar 3 | !**/src/main/**/target/ 4 | !**/src/test/**/target/ 5 | 6 | ### IntelliJ IDEA ### 7 | .idea/modules.xml 8 | .idea/jarRepositories.xml 9 | .idea/compiler.xml 10 | .idea/libraries/ 11 | *.iws 12 | *.iml 13 | *.ipr 14 | 15 | ### Eclipse ### 16 | .apt_generated 17 | .classpath 18 | .factorypath 19 | .project 20 | .settings 21 | .springBeans 22 | .sts4-cache 23 | 24 | ### VS Code ### 25 | .vscode/ 26 | 27 | ### Mac OS ### 28 | .DS_Store 29 | /data/results*.txt 30 | -------------------------------------------------------------------------------- /exttest/data/case-homogenous-both.mnd: -------------------------------------------------------------------------------- 1 | #set builtin-evaluation = full; 2 | #set err-invalid-content = false; 3 | //#set single-step-elimination = none; 4 | //#set jump-straightening = none; 5 | //#set jump-threading = none; 6 | 7 | def isWall(block) 8 | case block 9 | when null, 10 | @graphite-press, 11 | @copper-wall, @copper-wall-large, @titanium-wall, @titanium-wall-large, 12 | @plastanium-wall, @plastanium-wall-large, @thorium-wall, @thorium-wall-large, 13 | @phase-wall, @phase-wall-large, @surge-wall, @surge-wall-large, 14 | @scrap-wall, @scrap-wall-large, @scrap-wall-huge, @scrap-wall-gigantic, 15 | @beryllium-wall, @beryllium-wall-large, @tungsten-wall, @tungsten-wall-large, 16 | @reinforced-surge-wall, @reinforced-surge-wall-large, @carbide-wall, @carbide-wall-large 17 | then true; 18 | else false; 19 | end; 20 | end; 21 | 22 | for i in 0 ... @blockCount do 23 | print(isWall(lookup(:block, i))); 24 | end; 25 | -------------------------------------------------------------------------------- /exttest/data/case-homogenous-max.mnd: -------------------------------------------------------------------------------- 1 | #set target = 8; 2 | #set builtin-evaluation = full; 3 | #set err-invalid-content = false; 4 | //#set single-step-elimination = none; 5 | //#set jump-straightening = none; 6 | //#set jump-threading = none; 7 | 8 | def isWall(block) 9 | case block 10 | when @graphite-press, 11 | @copper-wall, @copper-wall-large, @titanium-wall, @titanium-wall-large, 12 | @plastanium-wall, @plastanium-wall-large, @thorium-wall, @thorium-wall-large, 13 | @phase-wall, @phase-wall-large, @surge-wall, @surge-wall-large, 14 | @scrap-wall, @scrap-wall-large, @scrap-wall-huge, @scrap-wall-gigantic, 15 | @beryllium-wall, @beryllium-wall-large, @tungsten-wall, @tungsten-wall-large, 16 | @reinforced-surge-wall, @reinforced-surge-wall-large, @carbide-wall, @carbide-wall-large, 17 | @tile-logic-display 18 | then true; 19 | else false; 20 | end; 21 | end; 22 | 23 | for i in 0 ... @blockCount do 24 | print(isWall(lookup(:block, i))); 25 | end; 26 | -------------------------------------------------------------------------------- /exttest/data/case-homogenous-none.mnd: -------------------------------------------------------------------------------- 1 | #set builtin-evaluation = full; 2 | #set err-invalid-content = false; 3 | //#set single-step-elimination = none; 4 | //#set jump-straightening = none; 5 | //#set jump-threading = none; 6 | 7 | def isWall(block) 8 | case block 9 | when @copper-wall, @copper-wall-large, @titanium-wall, @titanium-wall-large, 10 | @plastanium-wall, @plastanium-wall-large, @thorium-wall, @thorium-wall-large, 11 | @phase-wall, @phase-wall-large, @surge-wall, @surge-wall-large, 12 | @scrap-wall, @scrap-wall-large, @scrap-wall-huge, @scrap-wall-gigantic, 13 | @beryllium-wall, @beryllium-wall-large, @tungsten-wall, @tungsten-wall-large, 14 | @reinforced-surge-wall, @reinforced-surge-wall-large, @carbide-wall, @carbide-wall-large 15 | then true; 16 | else false; 17 | end; 18 | end; 19 | 20 | for i in 0 ... @blockCount do 21 | print(isWall(lookup(:block, i))); 22 | end; 23 | -------------------------------------------------------------------------------- /exttest/data/case-homogenous-null.mnd: -------------------------------------------------------------------------------- 1 | #set builtin-evaluation = full; 2 | #set err-invalid-content = false; 3 | //#set single-step-elimination = none; 4 | //#set jump-straightening = none; 5 | //#set jump-threading = none; 6 | 7 | def isWall(block) 8 | case block 9 | when null, 10 | @copper-wall, @copper-wall-large, @titanium-wall, @titanium-wall-large, 11 | @plastanium-wall, @plastanium-wall-large, @thorium-wall, @thorium-wall-large, 12 | @phase-wall, @phase-wall-large, @surge-wall, @surge-wall-large, 13 | @scrap-wall, @scrap-wall-large, @scrap-wall-huge, @scrap-wall-gigantic, 14 | @beryllium-wall, @beryllium-wall-large, @tungsten-wall, @tungsten-wall-large, 15 | @reinforced-surge-wall, @reinforced-surge-wall-large, @carbide-wall, @carbide-wall-large 16 | then true; 17 | else false; 18 | end; 19 | end; 20 | 21 | for i in 0 ... @blockCount do 22 | print(isWall(lookup(:block, i))); 23 | end; 24 | -------------------------------------------------------------------------------- /exttest/data/case-homogenous-zero.mnd: -------------------------------------------------------------------------------- 1 | #set builtin-evaluation = full; 2 | #set err-invalid-content = false; 3 | //#set single-step-elimination = none; 4 | //#set jump-straightening = none; 5 | //#set jump-threading = none; 6 | 7 | def isWall(block) 8 | case block 9 | when @graphite-press, 10 | @copper-wall, @copper-wall-large, @titanium-wall, @titanium-wall-large, 11 | @plastanium-wall, @plastanium-wall-large, @thorium-wall, @thorium-wall-large, 12 | @phase-wall, @phase-wall-large, @surge-wall, @surge-wall-large, 13 | @scrap-wall, @scrap-wall-large, @scrap-wall-huge, @scrap-wall-gigantic, 14 | @beryllium-wall, @beryllium-wall-large, @tungsten-wall, @tungsten-wall-large, 15 | @reinforced-surge-wall, @reinforced-surge-wall-large, @carbide-wall, @carbide-wall-large 16 | then true; 17 | else false; 18 | end; 19 | end; 20 | 21 | for i in 0 ... @blockCount do 22 | print(isWall(lookup(:block, i))); 23 | end; 24 | -------------------------------------------------------------------------------- /exttest/data/case-range.mnd: -------------------------------------------------------------------------------- 1 | #set builtin-evaluation = full; 2 | #set err-invalid-content = false; 3 | //#set single-step-elimination = none; 4 | //#set jump-straightening = none; 5 | //#set jump-threading = none; 6 | 7 | def convertHexDigit(digit) 8 | case digit 9 | when 0 .. 9 then print(digit); 10 | when 10 then print("A"); 11 | when 11 then print("B"); 12 | when 12 then print("C"); 13 | when 13 then print("D"); 14 | when 14 then print("E"); 15 | when 15 then print("F"); 16 | end; 17 | end; 18 | 19 | param p = 16; 20 | 21 | for i in 0 ... p do 22 | print(convertHexDigit(i)); 23 | end; 24 | -------------------------------------------------------------------------------- /exttest/data/case-small.mnd: -------------------------------------------------------------------------------- 1 | #set builtin-evaluation = full; 2 | #set err-invalid-content = false; 3 | //#set single-step-elimination = none; 4 | //#set jump-straightening = none; 5 | //#set jump-threading = none; 6 | 7 | def identifyBlock(block) 8 | case block 9 | when @message then "M"; 10 | when @switch then "S"; 11 | when @memory-bank, @memory-cell then "R"; 12 | else "0"; 13 | end; 14 | end; 15 | 16 | for i in 0 ... @blockCount do 17 | print(identifyBlock(lookup(:block, i))); 18 | end; 19 | -------------------------------------------------------------------------------- /exttest/data/recursion.mnd: -------------------------------------------------------------------------------- 1 | allocate stack in bank1; 2 | 3 | def fib(n) 4 | return n < 2 ? max(n, 0) : fib(n - 1); 5 | end; 6 | 7 | assertEquals(0, fib(0), "recursion"); 8 | 9 | stopProcessor(); 10 | 11 | def bbb(y) 12 | ccc(y); 13 | end; 14 | 15 | def ccc(z) 16 | print(z); 17 | end; 18 | -------------------------------------------------------------------------------- /exttest/src/main/java/info/teksol/mindcode/exttest/ErrorResult.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mindcode.exttest; 2 | 3 | import info.teksol.mc.emulator.processor.ExecutionException; 4 | import info.teksol.mc.profile.CompilerProfile; 5 | import org.jspecify.annotations.NullMarked; 6 | import org.jspecify.annotations.Nullable; 7 | 8 | @NullMarked 9 | public record ErrorResult(String testCaseId, CompilerProfile profile, String unexpectedMessages, 10 | @Nullable ExecutionException executionException, String failedTests) { 11 | 12 | @Override 13 | public String toString() { 14 | return testCaseId + ":" 15 | + "\n#set profile = " + profile.encode() + ";" 16 | + (unexpectedMessages.isEmpty() ? "" : "\nUnexpected messages: \n" + unexpectedMessages) 17 | + (executionException == null ? "" : "\n" + executionException.getMessage()) 18 | + (failedTests.isEmpty() ? "" : "\nFailed tests: \n" + failedTests) 19 | + "\n"; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /exttest/src/main/java/info/teksol/mindcode/exttest/ExecutionFramework.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mindcode.exttest; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | 5 | import java.io.PrintWriter; 6 | 7 | @NullMarked 8 | public interface ExecutionFramework { 9 | void process(PrintWriter writer); 10 | } 11 | -------------------------------------------------------------------------------- /exttest/src/main/java/info/teksol/mindcode/exttest/TestProgress.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mindcode.exttest; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | 5 | import java.io.PrintWriter; 6 | 7 | @NullMarked 8 | public interface TestProgress { 9 | 10 | boolean finished(); 11 | 12 | int nextTestRun(); 13 | 14 | int getSuccessCount(); 15 | 16 | int getFailureCount(); 17 | 18 | void printFinalMessage(PrintWriter writer); 19 | 20 | void printProgress(boolean finished); 21 | 22 | void printStatistics(PrintWriter writer); 23 | 24 | void processResults(PrintWriter writer); 25 | 26 | void reportError(ErrorResult errorResult); 27 | 28 | void reportSuccess(); 29 | 30 | void updateStatistics(ErrorResult errorResult); 31 | } 32 | -------------------------------------------------------------------------------- /exttest/src/main/java/info/teksol/mindcode/exttest/cases/TestCaseCreator.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mindcode.exttest.cases; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | 5 | @NullMarked 6 | public interface TestCaseCreator { 7 | 8 | /// Returns the total number of cases 9 | int getTotalCases(); 10 | 11 | /// Returns the number of samples to be processed by this selector 12 | int getSampleCount(); 13 | 14 | /// Provides a test case executor for a given test run 15 | TestCaseExecutor createExecutor(int testRunNumber); 16 | } 17 | -------------------------------------------------------------------------------- /exttest/src/main/java/info/teksol/mindcode/exttest/cases/TestCaseExecutor.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mindcode.exttest.cases; 2 | 3 | import info.teksol.mindcode.exttest.TestProgress; 4 | import org.jspecify.annotations.NullMarked; 5 | 6 | @NullMarked 7 | public interface TestCaseExecutor { 8 | void runTest(TestProgress progress); 9 | } 10 | -------------------------------------------------------------------------------- /exttest/src/test/java/info/teksol/mindcode/exttest/cases/TestCaseCreatorSampledTest.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mindcode.exttest.cases; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import static org.junit.jupiter.api.Assertions.assertEquals; 6 | 7 | class TestCaseCreatorSampledTest { 8 | 9 | @Test 10 | void providesCorrectTestCaseNumbers() { 11 | TestCaseCreatorSampled instance = new TestCaseCreatorSampled(null, 100, 10); 12 | assertEquals(5, instance.getTestCaseNumber(0)); 13 | assertEquals(15, instance.getTestCaseNumber(1)); 14 | assertEquals(85, instance.getTestCaseNumber(8)); 15 | assertEquals(95, instance.getTestCaseNumber(9)); 16 | } 17 | 18 | } -------------------------------------------------------------------------------- /exttest/src/test/resources/junit-platform.properties: -------------------------------------------------------------------------------- 1 | junit.platform.output.capture.stdout = true 2 | junit.platform.output.capture.stderr = true 3 | junit.jupiter.execution.parallel.enabled = true 4 | junit.jupiter.execution.parallel.mode.default = concurrent 5 | junit.jupiter.execution.parallel.mode.classes.default = concurrent 6 | junit.jupiter.testclass.order.default = org.junit.jupiter.api.ClassOrderer$OrderAnnotation 7 | -------------------------------------------------------------------------------- /java/util/annotations.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cardillan/mindcode/ed0453b0cd24b5cff4d623923c79bbcc3e3191ba/logo.png -------------------------------------------------------------------------------- /samples/.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | !.mvn/wrapper/maven-wrapper.jar 3 | !**/src/main/**/target/ 4 | !**/src/test/**/target/ 5 | 6 | ### IntelliJ IDEA ### 7 | .idea/modules.xml 8 | .idea/jarRepositories.xml 9 | .idea/compiler.xml 10 | .idea/libraries/ 11 | *.iws 12 | *.iml 13 | *.ipr 14 | 15 | ### Eclipse ### 16 | .apt_generated 17 | .classpath 18 | .factorypath 19 | .project 20 | .settings 21 | .springBeans 22 | .sts4-cache 23 | 24 | ### VS Code ### 25 | .vscode/ 26 | 27 | ### Mac OS ### 28 | .DS_Store -------------------------------------------------------------------------------- /samples/src/main/java/info/teksol/mindcode/samples/Sample.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mindcode.samples; 2 | 3 | public record Sample(String name, String source, boolean slow, boolean relaxed) { 4 | } 5 | -------------------------------------------------------------------------------- /samples/src/main/resources/samples/mindcode/many-thorium.mnd: -------------------------------------------------------------------------------- 1 | // To use this script, build several thorium reactors and attach them to a processor 2 | // with this code. 3 | 4 | // This script loops through all blocks linked to the processor 5 | // If a thorium reactor is found, it is disabled if it doesn't have enough cryofluid 6 | 7 | // @links is the number of blocks lined to the processor 8 | // We iterate through indexes 0 to @links - 1 9 | for n in 0 ... @links do 10 | // Obtain n-th block linked to the processor 11 | reactor = getlink(n); 12 | 13 | // Only process thorium reactors. If a different block got linked by mistake, it might become disabled 14 | if reactor.@type == @thorium-reactor then 15 | reactor.enabled = reactor.@cryofluid >= 0.25 * reactor.@liquidCapacity; 16 | end; 17 | end; 18 | -------------------------------------------------------------------------------- /samples/src/main/resources/samples/mindcode/one-thorium.mnd: -------------------------------------------------------------------------------- 1 | // To use this script, build a thorium reactor and attach it to a processor 2 | // with this code. The reactor will be linked to the processor as reactor1. 3 | 4 | // This script then checks that the cryofluid level is at least on 25% of the reactor capacity. 5 | // If it isn't, the reactor is disabled, preventing a blow up. 6 | 7 | reactor1.enabled = reactor1.@cryofluid >= 0.25 * reactor1.@liquidCapacity; 8 | -------------------------------------------------------------------------------- /samples/src/main/resources/samples/schematics/on-off-switch.sdf: -------------------------------------------------------------------------------- 1 | schematic 2 | name = "On/off switch" 3 | description = """ 4 | Enables/disables linked blocks according to switch state. 5 | 6 | Usage: link blocks to be controlled, use switch to enable/disable them. 7 | """ 8 | tag = "Schematic Builder" 9 | tag = BLOCK-MICRO-PROCESSOR 10 | 11 | switch1: 12 | @switch at ( 0, 0) facing south enabled 13 | @micro-processor at ( 1, 0) facing south processor 14 | links 15 | switch1 as switch1 16 | end 17 | mindcode = """ 18 | on = switch1.@enabled; 19 | // Starting at 1, we want to skip the switch 20 | for link in 1 ... @links do 21 | getlink(link).enabled = on; 22 | end; 23 | """ 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /samples/src/test/resources/junit-platform.properties: -------------------------------------------------------------------------------- 1 | junit.platform.output.capture.stdout = true 2 | junit.platform.output.capture.stderr = true 3 | junit.jupiter.execution.parallel.enabled = true 4 | junit.jupiter.execution.parallel.mode.default = concurrent 5 | junit.jupiter.execution.parallel.mode.classes.default = concurrent 6 | junit.jupiter.testclass.order.default = org.junit.jupiter.api.ClassOrderer$OrderAnnotation 7 | -------------------------------------------------------------------------------- /schemacode/src/main/java/info/teksol/schemacode/IOConsumer.java: -------------------------------------------------------------------------------- 1 | package info.teksol.schemacode; 2 | 3 | import java.io.IOException; 4 | 5 | public interface IOConsumer { 6 | void accept(E item) throws IOException; 7 | } 8 | -------------------------------------------------------------------------------- /schemacode/src/main/java/info/teksol/schemacode/IOSupplier.java: -------------------------------------------------------------------------------- 1 | package info.teksol.schemacode; 2 | 3 | import java.io.IOException; 4 | 5 | public interface IOSupplier { 6 | T get() throws IOException; 7 | } 8 | -------------------------------------------------------------------------------- /schemacode/src/main/java/info/teksol/schemacode/SchematicsInternalError.java: -------------------------------------------------------------------------------- 1 | package info.teksol.schemacode; 2 | 3 | import org.intellij.lang.annotations.PrintFormat; 4 | 5 | public class SchematicsInternalError extends RuntimeException { 6 | 7 | public SchematicsInternalError(String message) { 8 | super(message); 9 | } 10 | 11 | public SchematicsInternalError(Throwable cause) { 12 | super(cause); 13 | } 14 | 15 | public SchematicsInternalError(Throwable cause, String message) { 16 | super(message, cause); 17 | } 18 | 19 | public SchematicsInternalError(@PrintFormat String format, Object... args) { 20 | super(String.format(format, args)); 21 | } 22 | 23 | public SchematicsInternalError(Throwable cause, @PrintFormat String format, Object... args) { 24 | super(String.format(format, args), cause); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /schemacode/src/main/java/info/teksol/schemacode/SchematicsMetadata.java: -------------------------------------------------------------------------------- 1 | package info.teksol.schemacode; 2 | 3 | import info.teksol.mc.mindcode.logic.mimex.MindustryMetadata; 4 | 5 | public class SchematicsMetadata { 6 | // Always use the latest metadata here - certainly for loading schematics. 7 | // We might want to target a specific version when creating schematics one day, in which case it would be 8 | // necessary to use the correct metadata version when writing the schematics. 9 | private static final ThreadLocal metadata = ThreadLocal.withInitial(MindustryMetadata::getLatest); 10 | 11 | public static MindustryMetadata getMetadata() { 12 | return metadata.get(); 13 | } 14 | 15 | public static void setMetadata(MindustryMetadata newMetadata) { 16 | metadata.set(newMetadata); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /schemacode/src/main/java/info/teksol/schemacode/ast/AstBlock.java: -------------------------------------------------------------------------------- 1 | package info.teksol.schemacode.ast; 2 | 3 | import info.teksol.mc.common.SourcePosition; 4 | import org.jspecify.annotations.NullMarked; 5 | import org.jspecify.annotations.Nullable; 6 | 7 | import java.util.List; 8 | 9 | @NullMarked 10 | public record AstBlock(SourcePosition sourcePosition, Listlabels, String type, AstCoordinates position, 11 | @Nullable AstDirection direction, @Nullable AstConfiguration configuration) implements AstSchemaItem { 12 | 13 | @Override 14 | public AstBlock withEmptyPosition() { 15 | return new AstBlock(SourcePosition.EMPTY, labels, type, 16 | erasePosition(position), 17 | eraseNullablePosition(direction), 18 | eraseNullablePosition(configuration)); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /schemacode/src/main/java/info/teksol/schemacode/ast/AstBlockReference.java: -------------------------------------------------------------------------------- 1 | package info.teksol.schemacode.ast; 2 | 3 | import info.teksol.mc.common.SourcePosition; 4 | import info.teksol.schemacode.config.Configuration; 5 | import info.teksol.schemacode.mindustry.BlockConfiguration; 6 | import org.jspecify.annotations.NullMarked; 7 | 8 | @NullMarked 9 | public record AstBlockReference(SourcePosition sourcePosition, String block) implements AstContentsReference { 10 | 11 | @Override 12 | public String getConfigurationText() { 13 | return block; 14 | } 15 | 16 | @Override 17 | public Configuration getConfiguration() { 18 | return BlockConfiguration.forName(block); 19 | } 20 | 21 | @Override 22 | public AstBlockReference withEmptyPosition() { 23 | return new AstBlockReference(SourcePosition.EMPTY, block); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /schemacode/src/main/java/info/teksol/schemacode/ast/AstBoolean.java: -------------------------------------------------------------------------------- 1 | package info.teksol.schemacode.ast; 2 | 3 | import info.teksol.mc.common.SourcePosition; 4 | import org.jspecify.annotations.NullMarked; 5 | 6 | @NullMarked 7 | public record AstBoolean(SourcePosition sourcePosition, boolean value) implements AstConfiguration { 8 | 9 | @Override 10 | public AstBoolean withEmptyPosition() { 11 | return new AstBoolean(SourcePosition.EMPTY, value); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /schemacode/src/main/java/info/teksol/schemacode/ast/AstColor.java: -------------------------------------------------------------------------------- 1 | package info.teksol.schemacode.ast; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | 5 | @NullMarked 6 | public interface AstColor extends AstConfiguration { 7 | 8 | } 9 | -------------------------------------------------------------------------------- /schemacode/src/main/java/info/teksol/schemacode/ast/AstConfiguration.java: -------------------------------------------------------------------------------- 1 | package info.teksol.schemacode.ast; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | 5 | @NullMarked 6 | public interface AstConfiguration extends AstSchemaItem { 7 | 8 | } 9 | -------------------------------------------------------------------------------- /schemacode/src/main/java/info/teksol/schemacode/ast/AstConnections.java: -------------------------------------------------------------------------------- 1 | package info.teksol.schemacode.ast; 2 | 3 | import info.teksol.mc.common.SourcePosition; 4 | import org.jspecify.annotations.NullMarked; 5 | 6 | import java.util.List; 7 | 8 | @NullMarked 9 | public record AstConnections(SourcePosition sourcePosition, List connections) implements AstConfiguration { 10 | 11 | public AstConnections(SourcePosition sourcePosition, AstConnection... connections) { 12 | this(sourcePosition, List.of(connections)); 13 | } 14 | 15 | @Override 16 | public AstConnections withEmptyPosition() { 17 | return new AstConnections(SourcePosition.EMPTY, erasePositions(connections)); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /schemacode/src/main/java/info/teksol/schemacode/ast/AstContentsReference.java: -------------------------------------------------------------------------------- 1 | package info.teksol.schemacode.ast; 2 | 3 | import info.teksol.schemacode.config.Configuration; 4 | 5 | public interface AstContentsReference extends AstConfiguration { 6 | 7 | String getConfigurationText(); 8 | 9 | Configuration getConfiguration(); 10 | } 11 | -------------------------------------------------------------------------------- /schemacode/src/main/java/info/teksol/schemacode/ast/AstDefinition.java: -------------------------------------------------------------------------------- 1 | package info.teksol.schemacode.ast; 2 | 3 | import org.jspecify.annotations.NullMarked; 4 | 5 | @NullMarked 6 | public interface AstDefinition extends AstSchemaItem { 7 | 8 | 9 | } 10 | -------------------------------------------------------------------------------- /schemacode/src/main/java/info/teksol/schemacode/ast/AstDefinitions.java: -------------------------------------------------------------------------------- 1 | package info.teksol.schemacode.ast; 2 | 3 | import info.teksol.mc.common.SourcePosition; 4 | import org.jspecify.annotations.NullMarked; 5 | 6 | import java.util.List; 7 | 8 | @NullMarked 9 | public record AstDefinitions(SourcePosition sourcePosition, List definitions) implements AstSchemaItem { 10 | 11 | @Override 12 | public AstDefinitions withEmptyPosition() { 13 | return new AstDefinitions(SourcePosition.EMPTY, erasePositions(definitions)); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /schemacode/src/main/java/info/teksol/schemacode/ast/AstDirection.java: -------------------------------------------------------------------------------- 1 | package info.teksol.schemacode.ast; 2 | 3 | import info.teksol.mc.common.SourcePosition; 4 | import org.jspecify.annotations.NullMarked; 5 | 6 | @NullMarked 7 | public record AstDirection(SourcePosition sourcePosition, String direction) implements AstSchemaItem { 8 | 9 | @Override 10 | public AstDirection withEmptyPosition() { 11 | return new AstDirection(SourcePosition.EMPTY, direction); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /schemacode/src/main/java/info/teksol/schemacode/ast/AstItemReference.java: -------------------------------------------------------------------------------- 1 | package info.teksol.schemacode.ast; 2 | 3 | import info.teksol.mc.common.SourcePosition; 4 | import info.teksol.schemacode.config.Configuration; 5 | import info.teksol.schemacode.mindustry.ItemConfiguration; 6 | import org.jspecify.annotations.NullMarked; 7 | 8 | @NullMarked 9 | public record AstItemReference(SourcePosition sourcePosition, String item) implements AstContentsReference { 10 | 11 | @Override 12 | public String getConfigurationText() { 13 | return item; 14 | } 15 | 16 | @Override 17 | public Configuration getConfiguration() { 18 | return ItemConfiguration.forName(item); 19 | } 20 | 21 | @Override 22 | public AstItemReference withEmptyPosition() { 23 | return new AstItemReference(SourcePosition.EMPTY, item); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /schemacode/src/main/java/info/teksol/schemacode/ast/AstLink.java: -------------------------------------------------------------------------------- 1 | package info.teksol.schemacode.ast; 2 | 3 | import info.teksol.schemacode.mindustry.Position; 4 | import info.teksol.schemacode.mindustry.ProcessorConfiguration.Link; 5 | import info.teksol.schemacode.schematics.SchematicsBuilder; 6 | import org.jspecify.annotations.NullMarked; 7 | 8 | import java.util.function.Consumer; 9 | 10 | @NullMarked 11 | public interface AstLink extends AstSchemaItem { 12 | 13 | void getProcessorLinks(Consumer linkConsumer, SchematicsBuilder builder, Position processorPosition); 14 | 15 | default String stripPrefix(String linkName) { 16 | int pos = linkName.indexOf("-"); 17 | return pos < 0 ? linkName : linkName.substring(pos + 1); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /schemacode/src/main/java/info/teksol/schemacode/ast/AstLiquidReference.java: -------------------------------------------------------------------------------- 1 | package info.teksol.schemacode.ast; 2 | 3 | import info.teksol.mc.common.SourcePosition; 4 | import info.teksol.schemacode.config.Configuration; 5 | import info.teksol.schemacode.mindustry.LiquidConfiguration; 6 | import org.jspecify.annotations.NullMarked; 7 | 8 | @NullMarked 9 | public record AstLiquidReference(SourcePosition sourcePosition, String liquid) implements AstContentsReference { 10 | 11 | @Override 12 | public String getConfigurationText() { 13 | return liquid; 14 | } 15 | 16 | @Override 17 | public Configuration getConfiguration() { 18 | return LiquidConfiguration.forName(liquid); 19 | } 20 | 21 | @Override 22 | public AstLiquidReference withEmptyPosition() { 23 | return new AstLiquidReference(SourcePosition.EMPTY, liquid); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /schemacode/src/main/java/info/teksol/schemacode/ast/AstProcessor.java: -------------------------------------------------------------------------------- 1 | package info.teksol.schemacode.ast; 2 | 3 | import info.teksol.mc.common.SourcePosition; 4 | import info.teksol.schemacode.schematics.Language; 5 | import org.jspecify.annotations.NullMarked; 6 | import org.jspecify.annotations.Nullable; 7 | 8 | import java.util.List; 9 | 10 | @NullMarked 11 | public record AstProcessor(SourcePosition sourcePosition, List links, @Nullable AstProgram program, Language language) implements AstConfiguration { 12 | 13 | @Override 14 | public AstProcessor withEmptyPosition() { 15 | return new AstProcessor(SourcePosition.EMPTY, 16 | erasePositions(links), 17 | eraseNullablePosition(program), 18 | language); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /schemacode/src/main/java/info/teksol/schemacode/ast/AstProgramSnippet.java: -------------------------------------------------------------------------------- 1 | package info.teksol.schemacode.ast; 2 | 3 | import info.teksol.mc.common.SourcePosition; 4 | import info.teksol.schemacode.schematics.SchematicsBuilder; 5 | import org.jspecify.annotations.NullMarked; 6 | 7 | @NullMarked 8 | public interface AstProgramSnippet extends AstSchemaItem { 9 | 10 | String getProgramId(SchematicsBuilder builder); 11 | 12 | String getProgramText(SchematicsBuilder builder); 13 | 14 | SourcePosition getSourcePosition(SchematicsBuilder builder); 15 | 16 | default int getIndent(SchematicsBuilder builder) { 17 | return 0; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /schemacode/src/main/java/info/teksol/schemacode/ast/AstRgbaValue.java: -------------------------------------------------------------------------------- 1 | package info.teksol.schemacode.ast; 2 | 3 | import info.teksol.mc.common.SourcePosition; 4 | import org.jspecify.annotations.NullMarked; 5 | 6 | @NullMarked 7 | public record AstRgbaValue(SourcePosition sourcePosition, int red, int green, int blue, int alpha) implements AstColor { 8 | 9 | @Override 10 | public AstRgbaValue withEmptyPosition() { 11 | return new AstRgbaValue(SourcePosition.EMPTY, red, green, blue, alpha); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /schemacode/src/main/java/info/teksol/schemacode/ast/AstSchemaAttribute.java: -------------------------------------------------------------------------------- 1 | package info.teksol.schemacode.ast; 2 | 3 | import info.teksol.mc.common.SourcePosition; 4 | import org.jspecify.annotations.NullMarked; 5 | 6 | @NullMarked 7 | public record AstSchemaAttribute(SourcePosition sourcePosition, String attribute, AstSchemaItem value) implements AstSchemaItem { 8 | 9 | @Override 10 | public AstSchemaAttribute withEmptyPosition() { 11 | return new AstSchemaAttribute(SourcePosition.EMPTY, attribute, erasePosition(value)); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /schemacode/src/main/java/info/teksol/schemacode/ast/AstSchemaItem.java: -------------------------------------------------------------------------------- 1 | package info.teksol.schemacode.ast; 2 | 3 | import info.teksol.mc.common.SourceElement; 4 | import org.jspecify.annotations.NullMarked; 5 | import org.jspecify.annotations.Nullable; 6 | 7 | import java.util.List; 8 | 9 | @NullMarked 10 | public interface AstSchemaItem extends SourceElement { 11 | 12 | AstSchemaItem withEmptyPosition(); 13 | 14 | @SuppressWarnings("unchecked") 15 | default E eraseNullablePosition(@Nullable E item) { 16 | return item == null ? null : (E) item.withEmptyPosition(); 17 | } 18 | 19 | @SuppressWarnings("unchecked") 20 | default E erasePosition(E item) { 21 | return (E) item.withEmptyPosition(); 22 | } 23 | 24 | default List erasePositions(List items) { 25 | return items.stream().map(this::erasePosition).toList(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /schemacode/src/main/java/info/teksol/schemacode/ast/AstSchematic.java: -------------------------------------------------------------------------------- 1 | package info.teksol.schemacode.ast; 2 | 3 | import info.teksol.mc.common.SourcePosition; 4 | import org.jspecify.annotations.NullMarked; 5 | 6 | import java.util.List; 7 | 8 | @NullMarked 9 | public record AstSchematic(SourcePosition sourcePosition, List attributes, List blocks) implements AstDefinition { 10 | 11 | @Override 12 | public AstSchematic withEmptyPosition() { 13 | return new AstSchematic(SourcePosition.EMPTY, 14 | erasePositions(attributes), 15 | erasePositions(blocks)); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /schemacode/src/main/java/info/teksol/schemacode/ast/AstStringConstant.java: -------------------------------------------------------------------------------- 1 | package info.teksol.schemacode.ast; 2 | 3 | import info.teksol.mc.common.SourcePosition; 4 | import org.jspecify.annotations.NullMarked; 5 | 6 | @NullMarked 7 | public record AstStringConstant(SourcePosition sourcePosition, String name, AstText value) implements AstDefinition { 8 | 9 | @Override 10 | public AstStringConstant withEmptyPosition() { 11 | return new AstStringConstant(SourcePosition.EMPTY, name, erasePosition(value)); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /schemacode/src/main/java/info/teksol/schemacode/ast/AstStringRef.java: -------------------------------------------------------------------------------- 1 | package info.teksol.schemacode.ast; 2 | 3 | import info.teksol.mc.common.SourcePosition; 4 | import info.teksol.schemacode.schematics.SchematicsBuilder; 5 | import org.jspecify.annotations.NullMarked; 6 | 7 | @NullMarked 8 | public record AstStringRef(SourcePosition sourcePosition, String reference) implements AstText { 9 | 10 | @Override 11 | public String getText(SchematicsBuilder builder) { 12 | return builder.getText(this, reference).getText(builder); 13 | } 14 | 15 | @Override 16 | public SourcePosition getTextPosition(SchematicsBuilder builder) { 17 | return builder.getText(this, reference).getTextPosition(builder); 18 | } 19 | 20 | @Override 21 | public int getIndent(SchematicsBuilder builder) { 22 | return builder.getText(this, reference).getIndent(builder); 23 | } 24 | 25 | @Override 26 | public AstStringRef withEmptyPosition() { 27 | return new AstStringRef(SourcePosition.EMPTY, reference); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /schemacode/src/main/java/info/teksol/schemacode/ast/AstText.java: -------------------------------------------------------------------------------- 1 | package info.teksol.schemacode.ast; 2 | 3 | import info.teksol.mc.common.SourcePosition; 4 | import info.teksol.schemacode.schematics.SchematicsBuilder; 5 | import org.jspecify.annotations.NullMarked; 6 | 7 | @NullMarked 8 | public interface AstText extends AstConfiguration { 9 | 10 | String getText(SchematicsBuilder builder); 11 | 12 | /// Returns the text position within the source file 13 | /// 14 | /// @return the text position within the source file 15 | SourcePosition getTextPosition(SchematicsBuilder builder); 16 | 17 | default int getIndent(SchematicsBuilder builder) { 18 | return 0; 19 | } 20 | } -------------------------------------------------------------------------------- /schemacode/src/main/java/info/teksol/schemacode/ast/AstUnitCommandReference.java: -------------------------------------------------------------------------------- 1 | package info.teksol.schemacode.ast; 2 | 3 | import info.teksol.mc.common.SourcePosition; 4 | import info.teksol.schemacode.config.Configuration; 5 | import info.teksol.schemacode.mindustry.UnitCommandConfiguration; 6 | import org.jspecify.annotations.NullMarked; 7 | 8 | @NullMarked 9 | public record AstUnitCommandReference(SourcePosition sourcePosition, String command) implements AstContentsReference { 10 | 11 | @Override 12 | public String getConfigurationText() { 13 | return command; 14 | } 15 | 16 | @Override 17 | public Configuration getConfiguration() { 18 | return UnitCommandConfiguration.forName(command); 19 | } 20 | 21 | @Override 22 | public AstUnitCommandReference withEmptyPosition() { 23 | return new AstUnitCommandReference(SourcePosition.EMPTY, command); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /schemacode/src/main/java/info/teksol/schemacode/ast/AstUnitReference.java: -------------------------------------------------------------------------------- 1 | package info.teksol.schemacode.ast; 2 | 3 | import info.teksol.mc.common.SourcePosition; 4 | import info.teksol.schemacode.config.Configuration; 5 | import info.teksol.schemacode.mindustry.UnitConfiguration; 6 | import org.jspecify.annotations.NullMarked; 7 | 8 | @NullMarked 9 | public record AstUnitReference(SourcePosition sourcePosition, String unit) implements AstContentsReference { 10 | 11 | @Override 12 | public String getConfigurationText() { 13 | return unit; 14 | } 15 | 16 | @Override 17 | public Configuration getConfiguration() { 18 | return UnitConfiguration.forName(unit); 19 | } 20 | 21 | @Override 22 | public AstUnitReference withEmptyPosition() { 23 | return new AstUnitReference(SourcePosition.EMPTY, unit); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /schemacode/src/main/java/info/teksol/schemacode/ast/AstVirtual.java: -------------------------------------------------------------------------------- 1 | package info.teksol.schemacode.ast; 2 | 3 | import info.teksol.mc.common.SourcePosition; 4 | import org.jspecify.annotations.NullMarked; 5 | 6 | @NullMarked 7 | public record AstVirtual(SourcePosition sourcePosition) implements AstConfiguration { 8 | 9 | @Override 10 | public AstVirtual withEmptyPosition() { 11 | return new AstVirtual(SourcePosition.EMPTY); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /schemacode/src/main/java/info/teksol/schemacode/config/Array.java: -------------------------------------------------------------------------------- 1 | package info.teksol.schemacode.config; 2 | 3 | import info.teksol.schemacode.IOConsumer; 4 | import info.teksol.schemacode.IOSupplier; 5 | 6 | import java.io.IOException; 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | public record Array(Class dataClass, List array) implements Configuration { 11 | 12 | @Override 13 | public String toString() { 14 | return dataClass.getSimpleName() + "[" + array.size() + "]"; 15 | } 16 | 17 | public int size() { 18 | return array.size(); 19 | } 20 | 21 | public void store(IOConsumer consumer) throws IOException { 22 | for (E item : array) { 23 | consumer.accept(item); 24 | } 25 | } 26 | 27 | public static Array create(Class dataClass, int length, IOSupplier supplier) throws IOException { 28 | List array = new ArrayList<>(); 29 | for (int i = 0; i < length; i++) { 30 | array.add(supplier.get()); 31 | } 32 | return new Array<>(dataClass, array); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /schemacode/src/main/java/info/teksol/schemacode/config/BooleanConfiguration.java: -------------------------------------------------------------------------------- 1 | package info.teksol.schemacode.config; 2 | 3 | public record BooleanConfiguration(boolean value) implements Configuration { 4 | 5 | public static final BooleanConfiguration FALSE = new BooleanConfiguration(false); 6 | 7 | public static final BooleanConfiguration TRUE = new BooleanConfiguration(true); 8 | 9 | public static BooleanConfiguration of(boolean value) { 10 | return value ? TRUE : FALSE; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /schemacode/src/main/java/info/teksol/schemacode/config/ByteArray.java: -------------------------------------------------------------------------------- 1 | package info.teksol.schemacode.config; 2 | 3 | public record ByteArray(byte[] bytes) implements Configuration { 4 | 5 | public int size() { 6 | return bytes.length; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /schemacode/src/main/java/info/teksol/schemacode/config/Configuration.java: -------------------------------------------------------------------------------- 1 | package info.teksol.schemacode.config; 2 | 3 | import info.teksol.schemacode.SchematicsInternalError; 4 | import info.teksol.schemacode.mindustry.Position; 5 | import info.teksol.schemacode.schematics.Block; 6 | 7 | import java.util.function.UnaryOperator; 8 | 9 | public interface Configuration { 10 | 11 | default T as (Class type) { 12 | if (type.isInstance(this)) { 13 | return type.cast(this); 14 | } 15 | 16 | // Internal error; wrong configuration in schematics should be caught prior to this 17 | throw new SchematicsInternalError("Unexpected configuration type, expected %s, got %s.", 18 | type.getSimpleName(), getClass().getSimpleName()); 19 | } 20 | 21 | default Configuration encode(Block block) { 22 | return this; 23 | } 24 | 25 | default Configuration remap(UnaryOperator mapping) { 26 | return this; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /schemacode/src/main/java/info/teksol/schemacode/config/DoubleConfiguration.java: -------------------------------------------------------------------------------- 1 | package info.teksol.schemacode.config; 2 | 3 | public record DoubleConfiguration(double value) implements Configuration { 4 | } 5 | -------------------------------------------------------------------------------- /schemacode/src/main/java/info/teksol/schemacode/config/EmptyConfiguration.java: -------------------------------------------------------------------------------- 1 | package info.teksol.schemacode.config; 2 | 3 | import info.teksol.schemacode.mindustry.ConfigurationType; 4 | 5 | public enum EmptyConfiguration implements Configuration { 6 | EMPTY; 7 | 8 | @Override 9 | public T as(Class type) { 10 | return ConfigurationType.createEmpty(type); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /schemacode/src/main/java/info/teksol/schemacode/config/FloatConfiguration.java: -------------------------------------------------------------------------------- 1 | package info.teksol.schemacode.config; 2 | 3 | public record FloatConfiguration(float value) implements Configuration { 4 | } 5 | -------------------------------------------------------------------------------- /schemacode/src/main/java/info/teksol/schemacode/config/IntConfiguration.java: -------------------------------------------------------------------------------- 1 | package info.teksol.schemacode.config; 2 | 3 | public record IntConfiguration(int value) implements Configuration { 4 | 5 | public static final IntConfiguration ZERO = new IntConfiguration(0); 6 | 7 | } 8 | -------------------------------------------------------------------------------- /schemacode/src/main/java/info/teksol/schemacode/config/LongConfiguration.java: -------------------------------------------------------------------------------- 1 | package info.teksol.schemacode.config; 2 | 3 | public record LongConfiguration(long value) implements Configuration { 4 | } 5 | -------------------------------------------------------------------------------- /schemacode/src/main/java/info/teksol/schemacode/config/TextConfiguration.java: -------------------------------------------------------------------------------- 1 | package info.teksol.schemacode.config; 2 | 3 | public record TextConfiguration(String value) implements Configuration { 4 | 5 | public static final TextConfiguration EMPTY = new TextConfiguration(""); 6 | 7 | @Override 8 | public String toString() { 9 | return '"' + value + '"'; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /schemacode/src/main/java/info/teksol/schemacode/config/UnhandledItem.java: -------------------------------------------------------------------------------- 1 | package info.teksol.schemacode.config; 2 | 3 | public record UnhandledItem(String name, String content) implements Configuration { 4 | } 5 | -------------------------------------------------------------------------------- /schemacode/src/main/java/info/teksol/schemacode/mindustry/Color.java: -------------------------------------------------------------------------------- 1 | package info.teksol.schemacode.mindustry; 2 | 3 | import info.teksol.schemacode.config.Configuration; 4 | import info.teksol.schemacode.config.IntConfiguration; 5 | import info.teksol.schemacode.schematics.Block; 6 | 7 | public record Color(int red, int green, int blue, int alpha) implements Configuration { 8 | 9 | public static final Color WHITE = new Color(255, 255, 255, 255); 10 | 11 | @Override 12 | public Configuration encode(Block block) { 13 | return new IntConfiguration(encode()); 14 | } 15 | 16 | public int encode() { 17 | return (red << 24) | (green << 16) | (blue << 8) | alpha; 18 | } 19 | 20 | public static Color decode(int value) { 21 | int red = ((value & 0xff000000) >>> 24); 22 | int green = ((value & 0x00ff0000) >>> 16); 23 | int blue = ((value & 0x0000ff00) >>> 8); 24 | int alpha = ((value & 0x000000ff)); 25 | return new Color(red, green, blue, alpha); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /schemacode/src/main/java/info/teksol/schemacode/mindustry/ContentConfiguration.java: -------------------------------------------------------------------------------- 1 | package info.teksol.schemacode.mindustry; 2 | 3 | import info.teksol.mc.mindcode.logic.mimex.ContentType; 4 | import info.teksol.schemacode.config.Configuration; 5 | 6 | public interface ContentConfiguration extends Configuration { 7 | ContentType getContentType(); 8 | String getContentName(); 9 | int getId(); 10 | } 11 | -------------------------------------------------------------------------------- /schemacode/src/main/java/info/teksol/schemacode/mindustry/Direction.java: -------------------------------------------------------------------------------- 1 | package info.teksol.schemacode.mindustry; 2 | 3 | public enum Direction { 4 | EAST, 5 | NORTH, 6 | WEST, 7 | SOUTH, 8 | ; 9 | 10 | private final String schemacode; 11 | 12 | Direction() { 13 | schemacode = name().toLowerCase().concat(" ").substring(0, 5); 14 | } 15 | 16 | public static Direction convert(byte code) { 17 | return switch (code) { 18 | case 0 -> EAST; 19 | case 1 -> NORTH; 20 | case 2 -> WEST; 21 | case 3 -> SOUTH; 22 | default -> EAST; //throw new UnsupportedOperationException("Unknown rotation " + code); 23 | }; 24 | } 25 | 26 | public String toSchemacode() { 27 | return schemacode; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /schemacode/src/main/java/info/teksol/schemacode/mindustry/UnitOrBlockConfiguration.java: -------------------------------------------------------------------------------- 1 | package info.teksol.schemacode.mindustry; 2 | 3 | public interface UnitOrBlockConfiguration extends ContentConfiguration { 4 | } 5 | -------------------------------------------------------------------------------- /schemacode/src/main/java/info/teksol/schemacode/mindustry/UnitPlan.java: -------------------------------------------------------------------------------- 1 | package info.teksol.schemacode.mindustry; 2 | 3 | import info.teksol.schemacode.config.Configuration; 4 | import info.teksol.schemacode.config.EmptyConfiguration; 5 | import info.teksol.schemacode.config.IntConfiguration; 6 | import info.teksol.schemacode.schematics.Block; 7 | 8 | public record UnitPlan(String unitName) implements Configuration { 9 | @Override 10 | public Configuration encode(Block block) { 11 | int index = block.blockType().unitPlans().indexOf(unitName); 12 | return index < 0 ? EmptyConfiguration.EMPTY : new IntConfiguration(index); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /schemacode/src/main/java/info/teksol/schemacode/mindustry/Vector.java: -------------------------------------------------------------------------------- 1 | package info.teksol.schemacode.mindustry; 2 | 3 | import info.teksol.schemacode.config.Configuration; 4 | 5 | public record Vector(float x, float y) implements Configuration { 6 | } 7 | -------------------------------------------------------------------------------- /schemacode/src/main/java/info/teksol/schemacode/schematics/BlockOrder.java: -------------------------------------------------------------------------------- 1 | package info.teksol.schemacode.schematics; 2 | 3 | public enum BlockOrder { 4 | ORIGINAL, 5 | HORIZONTAL, 6 | VERTICAL 7 | } 8 | -------------------------------------------------------------------------------- /schemacode/src/main/java/info/teksol/schemacode/schematics/DirectionLevel.java: -------------------------------------------------------------------------------- 1 | package info.teksol.schemacode.schematics; 2 | 3 | public enum DirectionLevel { 4 | ROTATABLE, 5 | NON_DEFAULT, 6 | ALL 7 | } 8 | -------------------------------------------------------------------------------- /schemacode/src/main/java/info/teksol/schemacode/schematics/Language.java: -------------------------------------------------------------------------------- 1 | package info.teksol.schemacode.schematics; 2 | 3 | public enum Language { 4 | NONE, 5 | MLOG, 6 | MINDCODE, 7 | } 8 | -------------------------------------------------------------------------------- /schemacode/src/main/java/info/teksol/schemacode/schematics/Schematic.java: -------------------------------------------------------------------------------- 1 | package info.teksol.schemacode.schematics; 2 | 3 | import java.util.List; 4 | 5 | public record Schematic(String name, String filename, String description, List labels, int width, int height, List blocks) { 6 | 7 | public static Schematic empty() { 8 | return new Schematic("Empty", "", "", List.of(), 0, 0, List.of()); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /schemacode/src/test/java/info/teksol/schemacode/mindustry/ImplementationTest.java: -------------------------------------------------------------------------------- 1 | package info.teksol.schemacode.mindustry; 2 | 3 | import info.teksol.mc.mindcode.logic.mimex.BlockType; 4 | import info.teksol.mc.mindcode.logic.mimex.MindustryMetadata; 5 | import info.teksol.mc.mindcode.logic.opcodes.ProcessorVersion; 6 | import org.jspecify.annotations.NullMarked; 7 | import org.junit.jupiter.api.Test; 8 | 9 | import java.util.List; 10 | 11 | import static org.junit.jupiter.api.Assertions.assertTrue; 12 | 13 | @NullMarked 14 | class ImplementationTest { 15 | 16 | private final MindustryMetadata metadata = MindustryMetadata.forVersion(ProcessorVersion.MAX); 17 | 18 | @Test 19 | void ensureAllImplementationsExist() { 20 | List blocks = metadata.getAllBlocks() 21 | .stream() 22 | .filter(b -> Implementation.fromBlockType(b) == null) 23 | .toList(); 24 | 25 | blocks.forEach(b -> System.out.println("Block type " + b.name() + ": missing implementation " + b.implementation())); 26 | assertTrue(blocks.isEmpty()); 27 | } 28 | } -------------------------------------------------------------------------------- /schemacode/src/test/resources/junit-platform.properties: -------------------------------------------------------------------------------- 1 | junit.platform.output.capture.stdout = true 2 | junit.platform.output.capture.stderr = true 3 | junit.jupiter.execution.parallel.enabled = true 4 | junit.jupiter.execution.parallel.mode.default = concurrent 5 | junit.jupiter.execution.parallel.mode.classes.default = concurrent 6 | junit.jupiter.testclass.order.default = org.junit.jupiter.api.ClassOrderer$OrderAnnotation 7 | -------------------------------------------------------------------------------- /schemacode/src/test/resources/schematics/detector.msch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cardillan/mindcode/ed0453b0cd24b5cff4d623923c79bbcc3e3191ba/schemacode/src/test/resources/schematics/detector.msch -------------------------------------------------------------------------------- /schemacode/src/test/resources/schematics/driver-monitor-for-surge-alloy-factory.msch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cardillan/mindcode/ed0453b0cd24b5cff4d623923c79bbcc3e3191ba/schemacode/src/test/resources/schematics/driver-monitor-for-surge-alloy-factory.msch -------------------------------------------------------------------------------- /schemacode/src/test/resources/schematics/factory-monitor-silicon.msch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cardillan/mindcode/ed0453b0cd24b5cff4d623923c79bbcc3e3191ba/schemacode/src/test/resources/schematics/factory-monitor-silicon.msch -------------------------------------------------------------------------------- /schemacode/src/test/resources/schematics/factory-monitor-surge-alloy.msch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cardillan/mindcode/ed0453b0cd24b5cff4d623923c79bbcc3e3191ba/schemacode/src/test/resources/schematics/factory-monitor-surge-alloy.msch -------------------------------------------------------------------------------- /schemacode/src/test/resources/schematics/factory-monitor.msch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cardillan/mindcode/ed0453b0cd24b5cff4d623923c79bbcc3e3191ba/schemacode/src/test/resources/schematics/factory-monitor.msch -------------------------------------------------------------------------------- /schemacode/src/test/resources/schematics/impact-power-plant.msch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cardillan/mindcode/ed0453b0cd24b5cff4d623923c79bbcc3e3191ba/schemacode/src/test/resources/schematics/impact-power-plant.msch -------------------------------------------------------------------------------- /schemacode/src/test/resources/schematics/instant-overdrive-dome.msch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cardillan/mindcode/ed0453b0cd24b5cff4d623923c79bbcc3e3191ba/schemacode/src/test/resources/schematics/instant-overdrive-dome.msch -------------------------------------------------------------------------------- /schemacode/src/test/resources/schematics/instant-overdrive-projector.msch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cardillan/mindcode/ed0453b0cd24b5cff4d623923c79bbcc3e3191ba/schemacode/src/test/resources/schematics/instant-overdrive-projector.msch -------------------------------------------------------------------------------- /schemacode/src/test/resources/schematics/item-counter.msch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cardillan/mindcode/ed0453b0cd24b5cff4d623923c79bbcc3e3191ba/schemacode/src/test/resources/schematics/item-counter.msch -------------------------------------------------------------------------------- /schemacode/src/test/resources/schematics/item-rate-display.msch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cardillan/mindcode/ed0453b0cd24b5cff4d623923c79bbcc3e3191ba/schemacode/src/test/resources/schematics/item-rate-display.msch -------------------------------------------------------------------------------- /schemacode/src/test/resources/schematics/item-rate-meter.msch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cardillan/mindcode/ed0453b0cd24b5cff4d623923c79bbcc3e3191ba/schemacode/src/test/resources/schematics/item-rate-meter.msch -------------------------------------------------------------------------------- /schemacode/src/test/resources/schematics/level-display.msch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cardillan/mindcode/ed0453b0cd24b5cff4d623923c79bbcc3e3191ba/schemacode/src/test/resources/schematics/level-display.msch -------------------------------------------------------------------------------- /schemacode/src/test/resources/schematics/level-meter-water+cryo.msch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cardillan/mindcode/ed0453b0cd24b5cff4d623923c79bbcc3e3191ba/schemacode/src/test/resources/schematics/level-meter-water+cryo.msch -------------------------------------------------------------------------------- /schemacode/src/test/resources/schematics/level-meter.msch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cardillan/mindcode/ed0453b0cd24b5cff4d623923c79bbcc3e3191ba/schemacode/src/test/resources/schematics/level-meter.msch -------------------------------------------------------------------------------- /schemacode/src/test/resources/schematics/mass-driver-monitor.msch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cardillan/mindcode/ed0453b0cd24b5cff4d623923c79bbcc3e3191ba/schemacode/src/test/resources/schematics/mass-driver-monitor.msch -------------------------------------------------------------------------------- /schemacode/src/test/resources/schematics/regulator.msch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cardillan/mindcode/ed0453b0cd24b5cff4d623923c79bbcc3e3191ba/schemacode/src/test/resources/schematics/regulator.msch -------------------------------------------------------------------------------- /schemacode/src/test/resources/schematics/sample.msch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cardillan/mindcode/ed0453b0cd24b5cff4d623923c79bbcc3e3191ba/schemacode/src/test/resources/schematics/sample.msch -------------------------------------------------------------------------------- /schemacode/src/test/resources/schematics/unit-transport-single.msch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cardillan/mindcode/ed0453b0cd24b5cff4d623923c79bbcc3e3191ba/schemacode/src/test/resources/schematics/unit-transport-single.msch -------------------------------------------------------------------------------- /support/idea/settings-filetypes.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cardillan/mindcode/ed0453b0cd24b5cff4d623923c79bbcc3e3191ba/support/idea/settings-filetypes.zip -------------------------------------------------------------------------------- /support/idea/settings-tools-linux.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cardillan/mindcode/ed0453b0cd24b5cff4d623923c79bbcc3e3191ba/support/idea/settings-tools-linux.zip -------------------------------------------------------------------------------- /support/idea/settings-tools-windows.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cardillan/mindcode/ed0453b0cd24b5cff4d623923c79bbcc3e3191ba/support/idea/settings-tools-windows.zip -------------------------------------------------------------------------------- /system.properties: -------------------------------------------------------------------------------- 1 | java.runtime.version=22 2 | -------------------------------------------------------------------------------- /toolapp/.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | !.mvn/wrapper/maven-wrapper.jar 3 | !**/src/main/**/target/ 4 | !**/src/test/**/target/ 5 | 6 | ### IntelliJ IDEA ### 7 | .idea/modules.xml 8 | .idea/jarRepositories.xml 9 | .idea/compiler.xml 10 | .idea/libraries/ 11 | *.iws 12 | *.iml 13 | *.ipr 14 | 15 | ### Eclipse ### 16 | .apt_generated 17 | .classpath 18 | .factorypath 19 | .project 20 | .settings 21 | .springBeans 22 | .sts4-cache 23 | 24 | ### NetBeans ### 25 | /nbproject/private/ 26 | /nbbuild/ 27 | /dist/ 28 | /nbdist/ 29 | /.nb-gradle/ 30 | build/ 31 | !**/src/main/**/build/ 32 | !**/src/test/**/build/ 33 | 34 | ### VS Code ### 35 | .vscode/ 36 | 37 | ### Mac OS ### 38 | .DS_Store -------------------------------------------------------------------------------- /toolapp/src/main/java/info/teksol/mindcode/cmdline/ProcessingException.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mindcode.cmdline; 2 | 3 | import org.intellij.lang.annotations.PrintFormat; 4 | import org.jspecify.annotations.NullMarked; 5 | 6 | @NullMarked 7 | class ProcessingException extends RuntimeException { 8 | 9 | public ProcessingException(String message) { 10 | super(message); 11 | } 12 | 13 | public ProcessingException(Throwable cause) { 14 | super(cause); 15 | } 16 | 17 | public ProcessingException(Throwable cause, String message) { 18 | super(message, cause); 19 | } 20 | 21 | public ProcessingException(@PrintFormat String format, Object... args) { 22 | super(String.format(format, args)); 23 | } 24 | 25 | public ProcessingException(Throwable cause, @PrintFormat String format, Object... args) { 26 | super(format.formatted(args), cause); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /toolapp/src/main/resources/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Main-Class: info.teksol.mindcode.cmdline.Main 3 | 4 | -------------------------------------------------------------------------------- /toolapp/src/test/resources/ide/idea/IntelliJ IDEA Global Settings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cardillan/mindcode/ed0453b0cd24b5cff4d623923c79bbcc3e3191ba/toolapp/src/test/resources/ide/idea/IntelliJ IDEA Global Settings -------------------------------------------------------------------------------- /toolapp/src/test/resources/ide/idea/filetypes/Mindcode.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /toolapp/src/test/resources/ide/idea/filetypes/Schema Definition File.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /toolapp/src/test/resources/ide/idea/filetypes/mlog.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /toolapp/src/test/resources/ide/idea/installed.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cardillan/mindcode/ed0453b0cd24b5cff4d623923c79bbcc3e3191ba/toolapp/src/test/resources/ide/idea/installed.txt -------------------------------------------------------------------------------- /webapp/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/**/target/ 5 | !**/src/test/**/target/ 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | build/ 29 | !**/src/main/**/build/ 30 | !**/src/test/**/build/ 31 | 32 | ### VS Code ### 33 | .vscode/ 34 | -------------------------------------------------------------------------------- /webapp/src/main/java/info/teksol/mindcode/webapp/SourceRepository.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mindcode.webapp; 2 | 3 | import org.springframework.data.repository.CrudRepository; 4 | 5 | import java.util.UUID; 6 | 7 | public interface SourceRepository extends CrudRepository { 8 | } 9 | -------------------------------------------------------------------------------- /webapp/src/main/java/info/teksol/mindcode/webapp/WebappApplication.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mindcode.webapp; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.boot.CommandLineRunner; 5 | import org.springframework.boot.SpringApplication; 6 | import org.springframework.boot.autoconfigure.SpringBootApplication; 7 | import org.springframework.jdbc.core.JdbcTemplate; 8 | 9 | @SpringBootApplication 10 | public class WebappApplication implements CommandLineRunner { 11 | 12 | @Autowired 13 | private JdbcTemplate template; 14 | 15 | public static void main(String[] args) { 16 | SpringApplication.run(WebappApplication.class, args); 17 | } 18 | 19 | @Override 20 | public void run(String... args) { 21 | new DbMigrator().migrate(template); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /webapp/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.datasource.url=jdbc:postgresql://localhost:5432/mindcode_development 2 | spring.datasource.username= 3 | spring.datasource.password= 4 | 5 | spring.session.store-type=jdbc 6 | spring.session.jdbc.initialize-schema=always 7 | spring.session.timeout.seconds=86400 8 | -------------------------------------------------------------------------------- /webapp/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 6 | 7 | System.err 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /webapp/src/test/java/info/teksol/mindcode/webapp/WebappApplicationTests.java: -------------------------------------------------------------------------------- 1 | package info.teksol.mindcode.webapp; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class WebappApplicationTests { 8 | 9 | @SuppressWarnings("EmptyMethod") 10 | @Test 11 | void contextLoads() { 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /webapp/src/test/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.datasource.url=jdbc:postgresql://localhost:5432/mindcode_test 2 | spring.datasource.username= 3 | spring.datasource.password= 4 | -------------------------------------------------------------------------------- /webapp/src/test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 7 | 8 | System.err 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /wide-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cardillan/mindcode/ed0453b0cd24b5cff4d623923c79bbcc3e3191ba/wide-logo.png --------------------------------------------------------------------------------