From 7f9356fe4566b3bece97f246faa5417844006f3a Mon Sep 17 00:00:00 2001 From: "timothe.rosaz" Date: Tue, 21 Oct 2025 23:14:14 +0200 Subject: [PATCH 01/38] WIP with new DSL (it compiles lol) --- dsl2/README.md | 97 +++++ dsl2/pom.xml | 57 +++ .../dsl2/UltimateSpellSystemDSL.java | 81 +++++ .../errors/MetadataRuleFailureException.java | 18 + .../dsl2/errors/ParsingException.java | 30 ++ .../dsl2/errors/SyntaxException.java | 50 +++ .../dsl2/errors/TreeValidationException.java | 18 + .../dsl2/errors/TypeException.java | 39 ++ .../dsl2/errors/UnknownFunctionException.java | 19 + .../dsl2/errors/UssException.java | 31 ++ .../dsl2/metadata/MetadataRule.java | 24 ++ .../dsl2/metadata/MetadataRulesManager.java | 42 +++ .../metadata/rules/DefaultMetadataRules.java | 24 ++ .../dsl2/nodes/ExpressionNode.java | 259 +++++++++++++ .../ultimatespellsystem/dsl2/nodes/Node.java | 79 ++++ .../dsl2/nodes/StatementNode.java | 127 +++++++ .../nodes/expressions/ArrayExpression.java | 95 +++++ .../expressions/ArrayGetterExpression.java | 55 +++ .../nodes/expressions/FieldGetExpression.java | 45 +++ .../expressions/FunctionCallExpression.java | 45 +++ .../expressions/ParenthesisExpression.java | 55 +++ .../expressions/ReferenceExpression.java | 60 +++ .../functions/FunctionArgument.java | 19 + .../functions/FunctionCallExpression.java | 94 +++++ .../functions/FunctionDefinition.java | 27 ++ .../litteral/BooleanExpression.java | 44 +++ .../litteral/DurationExpression.java | 46 +++ .../litteral/LiteralExpression.java | 38 ++ .../expressions/litteral/LocationLiteral.java | 105 ++++++ .../expressions/litteral/MapLiteral.java | 88 +++++ .../expressions/litteral/NullExpression.java | 39 ++ .../litteral/NumberExpression.java | 55 +++ .../litteral/StringExpression.java | 44 +++ .../expressions/operators/AddOperator.java | 59 +++ .../expressions/operators/BiOperator.java | 107 ++++++ .../operators/LogicalOperator.java | 75 ++++ .../expressions/operators/MonoOperator.java | 71 ++++ .../expressions/operators/MulDivOperator.java | 69 ++++ .../expressions/operators/NotOperator.java | 51 +++ .../nodes/expressions/operators/Operator.java | 40 ++ .../expressions/operators/SubOperator.java | 59 +++ .../statements/AffectationStatement.java | 55 +++ .../dsl2/nodes/statements/BlockStatement.java | 65 ++++ .../statements/BreakContinueStatement.java | 47 +++ .../nodes/statements/DeclareNewVariable.java | 58 +++ .../FunctionDeclarationStatement.java | 65 ++++ .../nodes/statements/IncrementStatement.java | 59 +++ .../nodes/statements/ReturnStatement.java | 57 +++ .../statements/SimpleExpressionStatement.java | 40 ++ .../nodes/statements/blocks/BlockHolder.java | 34 ++ .../statements/blocks/ForLoopStatement.java | 82 +++++ .../statements/blocks/IfElseStatement.java | 78 ++++ .../statements/blocks/WhileLoopStatement.java | 79 ++++ .../dsl2/nodes/type/CollectionFilter.java | 38 ++ .../dsl2/nodes/type/Duration.java | 136 +++++++ .../dsl2/nodes/type/SpellEntity.java | 79 ++++ .../dsl2/nodes/type/Type.java | 87 +++++ .../dsl2/nodes/type/TypePrimitive.java | 78 ++++ .../nodes/type/variables/TypesContext.java | 89 +++++ .../type/variables/VariableDefinition.java | 59 +++ .../type/variables/VariableReference.java | 78 ++++ .../dsl2/objects/CallbackEvent.java | 58 +++ .../registries/CallbackEventRegistry.java | 58 +++ .../dsl2/registries/EntityTypeRegistry.java | 65 ++++ .../FunctionDefinitionsRegistry.java | 55 +++ .../dsl2/registries/RegistryException.java | 21 ++ .../dsl2/tokenization/CharStream.java | 112 ++++++ .../dsl2/tokenization/PreviousIndicator.java | 23 ++ .../dsl2/tokenization/Token.java | 149 ++++++++ .../dsl2/tokenization/TokenPosition.java | 26 ++ .../dsl2/tokenization/TokenStream.java | 153 ++++++++ .../dsl2/tokenization/TokenType.java | 94 +++++ .../dsl2/tokenization/Tokenizer.java | 283 +++++++++++++++ .../dsl2/validators/DslValidator.java | 45 +++ .../StructureValidationVisitor.java | 86 +++++ .../dsl2/visitor/ExpressionVisitor.java | 38 ++ .../dsl2/visitor/PrintingVisitor.java | 341 ++++++++++++++++++ .../dsl2/visitor/StatementVisitor.java | 25 ++ .../dsl2/CorrectParsingTests.java | 76 ++++ .../dsl2/FailuresParsingTests.java | 59 +++ .../ultimatespellsystem/dsl2/ParsingTest.java | 97 +++++ .../dsl2/nodes/type/DurationTests.java | 38 ++ dsl2/src/test/resources/demo.cpp | 11 + .../parsing/bad_mix/invalid_param_meta.uss | 3 + .../parsing/bad_mix/unknown_function.uss | 1 + .../parsing/bad_parsing/bad_number.uss | 1 + .../parsing/bad_parsing/bad_string.uss | 2 + .../resources/parsing/bad_syntax/bad_else.uss | 3 + .../parsing/bad_syntax/bad_entity_type.uss | 3 + .../resources/parsing/bad_syntax/bad_send.uss | 3 + .../resources/parsing/bad_syntax/bad_var.uss | 2 + .../parsing/bad_syntax/redefine_caster.uss | 1 + .../parsing/bad_tree/after_break.uss | 6 + .../parsing/bad_tree/after_meta_1.uss | 5 + .../parsing/bad_tree/after_meta_2.uss | 5 + .../parsing/bad_tree/after_stop_1.uss | 2 + .../parsing/bad_tree/after_stop_2.uss | 3 + .../parsing/bad_tree/after_stop_3.uss | 5 + .../bad_type/bad_collection_teleport.uss | 4 + .../parsing/bad_type/bad_list_append.uss | 3 + .../resources/parsing/bad_type/bad_ope.uss | 5 + .../resources/parsing/bad_type/bad_ope_2.uss | 6 + .../resources/parsing/bad_type/bad_ope_3.uss | 7 + .../parsing/bad_type/increment_type.uss | 2 + .../parsing/bad_type/redefine_difftype.uss | 2 + .../resources/parsing/bad_type/stop_type.uss | 1 + .../resources/parsing/corrects/blocks/for.uss | 14 + .../parsing/corrects/blocks/for_break.uss | 5 + .../parsing/corrects/blocks/foreach.uss | 6 + .../parsing/corrects/blocks/ifelse_p1.uss | 7 + .../parsing/corrects/blocks/ifelse_p2.uss | 20 + .../parsing/corrects/blocks/repeat.uss | 13 + .../parsing/corrects/blocks/repeat_2.uss | 9 + .../parsing/corrects/blocks/run_later.uss | 9 + .../parsing/corrects/blocks/while.uss | 15 + .../corrects/metadata/param_metadata.uss | 3 + .../resources/parsing/corrects/mix/cercle.uss | 12 + .../parsing/corrects/mix/collections.uss | 8 + .../resources/parsing/corrects/mix/empty.uss | 0 .../parsing/corrects/mix/implicit_define.uss | 2 + .../parsing/corrects/mix/metadata.uss | 5 + .../parsing/corrects/mix/null_recovery.uss | 6 + .../parsing/corrects/mix/null_set.uss | 7 + .../parsing/corrects/mix/particle_shape.uss | 8 + .../parsing/corrects/mix/test_allof.uss | 6 + .../parsing/corrects/mix/test_basic.uss | 4 + .../parsing/corrects/mix/test_complex_tp.uss | 27 ++ .../corrects/mix/test_location_literal.uss | 2 + .../parsing/corrects/mix/test_null.uss | 5 + .../parsing/corrects/mix/test_teleport.uss | 6 + .../corrects/operators/bool_operators.uss | 2 + .../parsing/corrects/operators/conditions.uss | 13 + .../corrects/operators/list_append.uss | 16 + .../parsing/corrects/operators/math.uss | 3 + .../corrects/operators/operator_priority.uss | 11 + .../corrects/operators/parenthesis.uss | 6 + .../corrects/operators/type_operators.uss | 5 + .../parsing/corrects/statements/define.uss | 12 + .../parsing/corrects/statements/give.uss | 10 + .../parsing/corrects/statements/increment.uss | 3 + .../parsing/corrects/statements/play.uss | 17 + .../parsing/corrects/statements/send.uss | 22 ++ .../parsing/corrects/statements/send_nbt.uss | 1 + .../parsing/corrects/statements/stop_1.uss | 2 + .../parsing/corrects/statements/stop_2.uss | 2 + .../parsing/corrects/statements/stop_3.uss | 3 + .../parsing/corrects/statements/summon.uss | 9 + .../parsing/corrects/statements/teleport.uss | 4 + .../parsing/corrects_with_custom/callback.uss | 6 + .../parsing/corrects_with_custom/custom.uss | 4 + pom.xml | 1 + 151 files changed, 6182 insertions(+) create mode 100644 dsl2/README.md create mode 100644 dsl2/pom.xml create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/UltimateSpellSystemDSL.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/errors/MetadataRuleFailureException.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/errors/ParsingException.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/errors/SyntaxException.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/errors/TreeValidationException.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/errors/TypeException.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/errors/UnknownFunctionException.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/errors/UssException.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/metadata/MetadataRule.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/metadata/MetadataRulesManager.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/metadata/rules/DefaultMetadataRules.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/ExpressionNode.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/Node.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/StatementNode.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/ArrayExpression.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/ArrayGetterExpression.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/FieldGetExpression.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/FunctionCallExpression.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/ParenthesisExpression.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/ReferenceExpression.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/functions/FunctionArgument.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/functions/FunctionCallExpression.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/functions/FunctionDefinition.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/BooleanExpression.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/DurationExpression.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/LiteralExpression.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/LocationLiteral.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/MapLiteral.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/NullExpression.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/NumberExpression.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/StringExpression.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/AddOperator.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/BiOperator.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/LogicalOperator.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/MonoOperator.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/MulDivOperator.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/NotOperator.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/Operator.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/SubOperator.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/AffectationStatement.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/BlockStatement.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/BreakContinueStatement.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/DeclareNewVariable.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/FunctionDeclarationStatement.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/IncrementStatement.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/ReturnStatement.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/SimpleExpressionStatement.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/blocks/BlockHolder.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/blocks/ForLoopStatement.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/blocks/IfElseStatement.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/blocks/WhileLoopStatement.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/CollectionFilter.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/Duration.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/SpellEntity.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/Type.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/TypePrimitive.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/variables/TypesContext.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/variables/VariableDefinition.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/variables/VariableReference.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/objects/CallbackEvent.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/registries/CallbackEventRegistry.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/registries/EntityTypeRegistry.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/registries/FunctionDefinitionsRegistry.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/registries/RegistryException.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/tokenization/CharStream.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/tokenization/PreviousIndicator.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/tokenization/Token.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/tokenization/TokenPosition.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/tokenization/TokenStream.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/tokenization/TokenType.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/tokenization/Tokenizer.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/validators/DslValidator.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/validators/StructureValidationVisitor.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/ExpressionVisitor.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/PrintingVisitor.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/StatementVisitor.java create mode 100644 dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/CorrectParsingTests.java create mode 100644 dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/FailuresParsingTests.java create mode 100644 dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/ParsingTest.java create mode 100644 dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/DurationTests.java create mode 100644 dsl2/src/test/resources/demo.cpp create mode 100644 dsl2/src/test/resources/parsing/bad_mix/invalid_param_meta.uss create mode 100644 dsl2/src/test/resources/parsing/bad_mix/unknown_function.uss create mode 100644 dsl2/src/test/resources/parsing/bad_parsing/bad_number.uss create mode 100644 dsl2/src/test/resources/parsing/bad_parsing/bad_string.uss create mode 100644 dsl2/src/test/resources/parsing/bad_syntax/bad_else.uss create mode 100644 dsl2/src/test/resources/parsing/bad_syntax/bad_entity_type.uss create mode 100644 dsl2/src/test/resources/parsing/bad_syntax/bad_send.uss create mode 100644 dsl2/src/test/resources/parsing/bad_syntax/bad_var.uss create mode 100644 dsl2/src/test/resources/parsing/bad_syntax/redefine_caster.uss create mode 100644 dsl2/src/test/resources/parsing/bad_tree/after_break.uss create mode 100644 dsl2/src/test/resources/parsing/bad_tree/after_meta_1.uss create mode 100644 dsl2/src/test/resources/parsing/bad_tree/after_meta_2.uss create mode 100644 dsl2/src/test/resources/parsing/bad_tree/after_stop_1.uss create mode 100644 dsl2/src/test/resources/parsing/bad_tree/after_stop_2.uss create mode 100644 dsl2/src/test/resources/parsing/bad_tree/after_stop_3.uss create mode 100644 dsl2/src/test/resources/parsing/bad_type/bad_collection_teleport.uss create mode 100644 dsl2/src/test/resources/parsing/bad_type/bad_list_append.uss create mode 100644 dsl2/src/test/resources/parsing/bad_type/bad_ope.uss create mode 100644 dsl2/src/test/resources/parsing/bad_type/bad_ope_2.uss create mode 100644 dsl2/src/test/resources/parsing/bad_type/bad_ope_3.uss create mode 100644 dsl2/src/test/resources/parsing/bad_type/increment_type.uss create mode 100644 dsl2/src/test/resources/parsing/bad_type/redefine_difftype.uss create mode 100644 dsl2/src/test/resources/parsing/bad_type/stop_type.uss create mode 100644 dsl2/src/test/resources/parsing/corrects/blocks/for.uss create mode 100644 dsl2/src/test/resources/parsing/corrects/blocks/for_break.uss create mode 100644 dsl2/src/test/resources/parsing/corrects/blocks/foreach.uss create mode 100644 dsl2/src/test/resources/parsing/corrects/blocks/ifelse_p1.uss create mode 100644 dsl2/src/test/resources/parsing/corrects/blocks/ifelse_p2.uss create mode 100644 dsl2/src/test/resources/parsing/corrects/blocks/repeat.uss create mode 100644 dsl2/src/test/resources/parsing/corrects/blocks/repeat_2.uss create mode 100644 dsl2/src/test/resources/parsing/corrects/blocks/run_later.uss create mode 100644 dsl2/src/test/resources/parsing/corrects/blocks/while.uss create mode 100644 dsl2/src/test/resources/parsing/corrects/metadata/param_metadata.uss create mode 100644 dsl2/src/test/resources/parsing/corrects/mix/cercle.uss create mode 100644 dsl2/src/test/resources/parsing/corrects/mix/collections.uss create mode 100644 dsl2/src/test/resources/parsing/corrects/mix/empty.uss create mode 100644 dsl2/src/test/resources/parsing/corrects/mix/implicit_define.uss create mode 100644 dsl2/src/test/resources/parsing/corrects/mix/metadata.uss create mode 100644 dsl2/src/test/resources/parsing/corrects/mix/null_recovery.uss create mode 100644 dsl2/src/test/resources/parsing/corrects/mix/null_set.uss create mode 100644 dsl2/src/test/resources/parsing/corrects/mix/particle_shape.uss create mode 100644 dsl2/src/test/resources/parsing/corrects/mix/test_allof.uss create mode 100644 dsl2/src/test/resources/parsing/corrects/mix/test_basic.uss create mode 100644 dsl2/src/test/resources/parsing/corrects/mix/test_complex_tp.uss create mode 100644 dsl2/src/test/resources/parsing/corrects/mix/test_location_literal.uss create mode 100644 dsl2/src/test/resources/parsing/corrects/mix/test_null.uss create mode 100644 dsl2/src/test/resources/parsing/corrects/mix/test_teleport.uss create mode 100644 dsl2/src/test/resources/parsing/corrects/operators/bool_operators.uss create mode 100644 dsl2/src/test/resources/parsing/corrects/operators/conditions.uss create mode 100644 dsl2/src/test/resources/parsing/corrects/operators/list_append.uss create mode 100644 dsl2/src/test/resources/parsing/corrects/operators/math.uss create mode 100644 dsl2/src/test/resources/parsing/corrects/operators/operator_priority.uss create mode 100644 dsl2/src/test/resources/parsing/corrects/operators/parenthesis.uss create mode 100644 dsl2/src/test/resources/parsing/corrects/operators/type_operators.uss create mode 100644 dsl2/src/test/resources/parsing/corrects/statements/define.uss create mode 100644 dsl2/src/test/resources/parsing/corrects/statements/give.uss create mode 100644 dsl2/src/test/resources/parsing/corrects/statements/increment.uss create mode 100644 dsl2/src/test/resources/parsing/corrects/statements/play.uss create mode 100644 dsl2/src/test/resources/parsing/corrects/statements/send.uss create mode 100644 dsl2/src/test/resources/parsing/corrects/statements/send_nbt.uss create mode 100644 dsl2/src/test/resources/parsing/corrects/statements/stop_1.uss create mode 100644 dsl2/src/test/resources/parsing/corrects/statements/stop_2.uss create mode 100644 dsl2/src/test/resources/parsing/corrects/statements/stop_3.uss create mode 100644 dsl2/src/test/resources/parsing/corrects/statements/summon.uss create mode 100644 dsl2/src/test/resources/parsing/corrects/statements/teleport.uss create mode 100644 dsl2/src/test/resources/parsing/corrects_with_custom/callback.uss create mode 100644 dsl2/src/test/resources/parsing/corrects_with_custom/custom.uss diff --git a/dsl2/README.md b/dsl2/README.md new file mode 100644 index 00000000..dc661274 --- /dev/null +++ b/dsl2/README.md @@ -0,0 +1,97 @@ +# USS - DSL 2 + +### Objectif + +```javascript + +let position = position_of(caster); +position += [0, 2, 0]; + +for(let entity in query_entities(position, 20, "players")) { + entity.send_message("Hello World!"); + entity.send_effect("resistance", D`20s`, 1); +} + + +``` + +```cpp +void main() { + vector position = position_of(caster); + position += (vector){0, 2, 0}; + + entity_query_result result = query_entities(position, 20, "players"); + for(int i = 0; i < result.size; i++) { + entity entity = result.entities[i]; + entity_send_message(entity, "Hello World!"); + entity_send_effect(entity, "resistance", duration_from_seconds(20), 1); + } +} +``` + + +## syntax + +``` +IDENTIFIER ::= [a-zA-Z_][a-zA-Z0-9_]* +STRING ::= '"' .* '"' +NUMBER ::= [0-9]*(.[0-9]+)? +BOOLEAN ::= "true" | "false" + +LITERAL ::= + STRING + | NUMBER + | BOOLEAN + | "null" + | LIST + | MAP + +LIST ::= [ (EXPRESSION (EXPRESSION )*)? ] + +MAP ::= { (IDENTIFIER: EXPRESSION,)* } + +a.b[c].d(x).e = z + +EXPRESSION ::= + LITERAL + | IDENTIFIER + | IDENTIFIER(PARAMETERS) + | EXPRESSION OPERATOR EXPRESSION + | (EXPRESSION) + | -EXPRESSION + | !EXPRESSION + | EXPRESSION[EXPRESSION] + | EXPRESSION.EXPRESSION + +ANNOTATION ::= "@" IDENTIFIER ( "(" EXPRESSIONS (, EXPRESSION)* ")" )? + +PARAMETERS ::= TYPE IDENTIFIER (, TYPE IDENTIFIER)* | ε + +TYPE ::= IDENTIFIER | "void" + +OPERATOR ::= "+" | "-" | "*" | "/" | "%" | "==" | "!=" | "<" | ">" | "<=" | ">=" | "&&" | "||" + +STATEMENT ::= + TYPE IDENTIFIER (= EXPRESSION)?; + | EXPRESSION = EXPRESSION; + | for(STATEMENT; STATEMENT; STATEMENT) BLOCK_STATEMENTS + | foreach(TYPE IDENTIFIER in EXPRESSION) BLOCK_STATEMENTS + | while(EXPRESSION) BLOCK_STATEMENTS + | do BLOCK_STATEMENTS while(EXPRESSION); + | if(EXPRESSION) BLOCK_STATEMENTS (else BLOCK_STATEMENTS)? + | "break"; | "continue"; | "return" (EXPRESSION)?; + | EXPRESSION(PARAMETERS); + +BLOCK_STATEMENTS ::= + { + STATEMENT (, STATEMENT)* + } + +FUNCTION ::= + TYPE IDENTIFIER(PARAMETERS) { + STATEMENT (, STATEMENT)* + } + + +``` + diff --git a/dsl2/pom.xml b/dsl2/pom.xml new file mode 100644 index 00000000..bfb855ab --- /dev/null +++ b/dsl2/pom.xml @@ -0,0 +1,57 @@ + + + 4.0.0 + + ultimate-spell-system-dsl2 + 3.0.0-SNAPSHOT + + + fr.jamailun.paper + ultimate-spell-system + 2.6.1-SNAPSHOT + + + + 21 + 21 + UTF-8 + + + 0.8.12 + 3.5.2 + + + + + + org.jacoco + jacoco-maven-plugin + ${jacoco.version} + + + + prepare-agent + + + + + report + test + + report + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + ${surefire.version} + + + + + diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/UltimateSpellSystemDSL.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/UltimateSpellSystemDSL.java new file mode 100644 index 00000000..26c0f7e5 --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/UltimateSpellSystemDSL.java @@ -0,0 +1,81 @@ +package fr.jamailun.ultimatespellsystem.dsl2; + +import fr.jamailun.ultimatespellsystem.dsl2.metadata.rules.DefaultMetadataRules; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.ExpressionNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.StatementNode; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.CharStream; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenStream; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenType; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.Tokenizer; +import org.jetbrains.annotations.NotNull; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +/** + * Central access to the DSL. + */ +public final class UltimateSpellSystemDSL { + private UltimateSpellSystemDSL() {} + + // Load the default metadata rules on class load. + static { + DefaultMetadataRules.initialize(); + } + + /** + * Parse a stream of tokens. + * @param tokens the tokens to parse. + * @return a parsed collection of statements. + */ + public static @NotNull List parse(@NotNull TokenStream tokens) { + List statements = new ArrayList<>(); + while(tokens.hasMore()) { + if(tokens.peek().getType() == TokenType.EOF) + break; + StatementNode node = StatementNode.parseNextStatement(tokens); + statements.add(node); + } + return statements; + } + + /** + * Parse a stream of characters. + * @param chars the characters to parse. + * @return a parsed collection of statements. + */ + public static @NotNull List parse(@NotNull CharStream chars) { + TokenStream tokens = Tokenizer.tokenize(chars); + return parse(tokens); + } + + /** + * Parse a string. + * @param string the string to parse. + * @return a parsed collection of statements. + */ + public static @NotNull List parse(@NotNull String string) { + return parse(CharStream.from(string)); + } + + /** + * Parse a file. + * @param file the file to read and parse. + * @return a parsed collection of statements. + */ + public static @NotNull List parse(@NotNull File file) { + return parse(CharStream.from(file)); + } + + /** + * Parse any expression... Will stop at the first one ! + * @param string string to parse. + * @return a non-null expression. + */ + public static @NotNull ExpressionNode parseExpression(@NotNull String string) { + TokenStream tokens = Tokenizer.tokenize(CharStream.from(string)); + return ExpressionNode.readNextExpression(tokens); + } + +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/errors/MetadataRuleFailureException.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/errors/MetadataRuleFailureException.java new file mode 100644 index 00000000..9ffa32a9 --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/errors/MetadataRuleFailureException.java @@ -0,0 +1,18 @@ +package fr.jamailun.ultimatespellsystem.dsl2.errors; + +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenPosition; +import org.jetbrains.annotations.NotNull; + +/** + * Exception for invalid metadata. + */ +public class MetadataRuleFailureException extends UssException { + /** + * New exception instance. + * @param pos token position. + * @param message metadata error message. + */ + public MetadataRuleFailureException(@NotNull TokenPosition pos, @NotNull String message) { + super(pos, message); + } +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/errors/ParsingException.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/errors/ParsingException.java new file mode 100644 index 00000000..231be5bd --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/errors/ParsingException.java @@ -0,0 +1,30 @@ +package fr.jamailun.ultimatespellsystem.dsl2.errors; + +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenPosition; +import org.jetbrains.annotations.NotNull; + +/** + * Exception throw in the parsing phase. + */ +public class ParsingException extends UssException { + + /** + * New exception instance with an unexpected character. + * @param pos token position. + * @param c unexpected character. + * @param message additional message. + */ + public ParsingException(@NotNull TokenPosition pos, char c, @NotNull String message) { + super(pos, "Unexpected character : '" + c + "'. " + message); + } + + /** + * New parsing exception. + * @param pos token position. + * @param message message to display. + */ + public ParsingException(@NotNull TokenPosition pos, @NotNull String message) { + super(pos, message); + } + +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/errors/SyntaxException.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/errors/SyntaxException.java new file mode 100644 index 00000000..cf81d603 --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/errors/SyntaxException.java @@ -0,0 +1,50 @@ +package fr.jamailun.ultimatespellsystem.dsl2.errors; + +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.Token; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenPosition; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenType; + +import java.util.List; + +/** + * Syntax exception : the spell has a user error. + */ +public class SyntaxException extends UssException { + + /** + * Standard syntax exception. + * @param position token position. + * @param message exception description. + */ + public SyntaxException(TokenPosition position, String message) { + super(position, message); + } + + /** + * Standard syntax exception. + * @param token token source of the error. + * @param message exception description. + */ + public SyntaxException(Token token, String message) { + super(token, message); + } + + /** + * Bad token exception. + * @param token problematic token. + * @param expected expected token type. + */ + public SyntaxException(Token token, TokenType expected) { + super(token, "Expected a " + expected + "."); + } + + /** + * Bad token exception. + * @param token problematic token. + * @param expected expected token type list (OR). + */ + public SyntaxException(Token token, List expected) { + super(token, "Expected one of: " + expected + "."); + } + +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/errors/TreeValidationException.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/errors/TreeValidationException.java new file mode 100644 index 00000000..699daf52 --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/errors/TreeValidationException.java @@ -0,0 +1,18 @@ +package fr.jamailun.ultimatespellsystem.dsl2.errors; + +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenPosition; + +/** + * Tree validation : relation between statements. + */ +public class TreeValidationException extends UssException { + + /** + * Tree validation failure. + * @param pos token position. + * @param message error description. + */ + public TreeValidationException(TokenPosition pos, String message) { + super(pos, message); + } +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/errors/TypeException.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/errors/TypeException.java new file mode 100644 index 00000000..33684408 --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/errors/TypeException.java @@ -0,0 +1,39 @@ +package fr.jamailun.ultimatespellsystem.dsl2.errors; + +import fr.jamailun.ultimatespellsystem.dsl2.nodes.ExpressionNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenPosition; + +/** + * Bad type in a spell. + */ +public class TypeException extends UssException { + + /** + * Unexpected expression type. + * @param expression expression source of tbe error. Must have a type set. + * @param expected expected type instead. + */ + public TypeException(ExpressionNode expression, TypePrimitive expected) { + super(expression.firstTokenPosition(), "Expression " + expression + " has type " + expression.getExpressionType() + ", expected " + expected); + } + + /** + * Unexpected expression type. + * @param expression expression source of tbe exception. Must have a type set. + * @param message exception details. + */ + public TypeException(ExpressionNode expression, String message) { + super(expression.firstTokenPosition(), "Expression " + expression + " of type " + expression.getExpressionType() + " : " + message); + } + + /** + * Bad token type. + * @param pos position of tbe token. + * @param message exception details. + */ + public TypeException(TokenPosition pos, String message) { + super(pos, message); + } + +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/errors/UnknownFunctionException.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/errors/UnknownFunctionException.java new file mode 100644 index 00000000..daf16f10 --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/errors/UnknownFunctionException.java @@ -0,0 +1,19 @@ +package fr.jamailun.ultimatespellsystem.dsl2.errors; + +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenPosition; +import org.jetbrains.annotations.NotNull; + +/** + * An exception threw when a function has not been registered. + */ +public class UnknownFunctionException extends UssException { + + /** + * New exception. + * @param pos token position. + * @param functionId ID of the unknown function. + */ + public UnknownFunctionException(@NotNull TokenPosition pos, @NotNull String functionId) { + super(pos, "Unknown function ID: '"+functionId+"'."); + } +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/errors/UssException.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/errors/UssException.java new file mode 100644 index 00000000..2dfcdb6f --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/errors/UssException.java @@ -0,0 +1,31 @@ +package fr.jamailun.ultimatespellsystem.dsl2.errors; + +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.Token; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenPosition; +import org.jetbrains.annotations.NotNull; + +/** + * Abstract exception for USS related problems. + * Provides access to the position in the source. + */ +public abstract class UssException extends RuntimeException { + + /** + * New instance with a token position only. + * @param pos token position. + * @param message exception details. + */ + public UssException(@NotNull TokenPosition pos, @NotNull String message) { + super("At " + pos + ". " + message); + } + + /** + * New instance with a real token instance. + * @param token token source of the exception. + * @param message exception details. + */ + public UssException(@NotNull Token token, @NotNull String message) { + super("With " + token + " at " + token.pos() + ". " + message); + } + +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/metadata/MetadataRule.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/metadata/MetadataRule.java new file mode 100644 index 00000000..d764c79e --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/metadata/MetadataRule.java @@ -0,0 +1,24 @@ +package fr.jamailun.ultimatespellsystem.dsl2.metadata; + +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.variables.TypesContext; +import org.jetbrains.annotations.NotNull; + +/** + * A metadata rule uses the metadata statements to change the behaviour of the spell compilation. + */ +public interface MetadataRule { + + /** + * Get the name this rule will apply to. + * @return a non-null string. + */ + @NotNull String getName(); + + /** + * Apply this rule to a context. + * @param context the context. + * @param metadata the statement to apply the rule to. + */ + // void apply(@NotNull TypesContext context, @NotNull MetadataStatement metadata); + +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/metadata/MetadataRulesManager.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/metadata/MetadataRulesManager.java new file mode 100644 index 00000000..691b630f --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/metadata/MetadataRulesManager.java @@ -0,0 +1,42 @@ +package fr.jamailun.ultimatespellsystem.dsl2.metadata; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Unmodifiable; + +import java.util.*; + +/** + * Register and expose all {@link MetadataRule}. + */ +public final class MetadataRulesManager { + private MetadataRulesManager() {} + + private static final Map> RULES = new HashMap<>(); + + /** + * Register a new rule. + * @param rule the rule to register. + */ + public static void registerRule(@NotNull MetadataRule rule) { + RULES.putIfAbsent(rule.getName(), new ArrayList<>()); + RULES.get(rule.getName()).add(rule); + } + + /** + * Get all rules for a name. + * @param name a non-null name. + * @return an unmodifiable list of rules. If not rule exist, the list will be empty. + */ + public static @NotNull @Unmodifiable List getRulesForName(@NotNull String name) { + return Collections.unmodifiableList(RULES.getOrDefault(name, Collections.emptyList())); + } + + /** + * List existing rules. + * @return an unmodifiable collection of names. + */ + public static @NotNull @Unmodifiable Collection existingKeys() { + return Collections.unmodifiableSet( RULES.keySet() ); + } + +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/metadata/rules/DefaultMetadataRules.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/metadata/rules/DefaultMetadataRules.java new file mode 100644 index 00000000..d8c75405 --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/metadata/rules/DefaultMetadataRules.java @@ -0,0 +1,24 @@ +package fr.jamailun.ultimatespellsystem.dsl2.metadata.rules; + +import fr.jamailun.ultimatespellsystem.dsl2.metadata.MetadataRulesManager; + +/** + * Load the default ruleset for metadata statements. + */ +public final class DefaultMetadataRules { + private DefaultMetadataRules() {} + + private static boolean initialized = false; + + /** + * Initialize the metadata rules system. + */ + public static void initialize() { + if(initialized) return; + initialized = true; + + // Register rules + //MetadataRulesManager.registerRule(new ParamDefinitionMetadata()); + } + +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/ExpressionNode.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/ExpressionNode.java new file mode 100644 index 00000000..60f33685 --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/ExpressionNode.java @@ -0,0 +1,259 @@ +package fr.jamailun.ultimatespellsystem.dsl2.nodes; + +import fr.jamailun.ultimatespellsystem.dsl2.errors.SyntaxException; +import fr.jamailun.ultimatespellsystem.dsl2.errors.UssException; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.*; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.litteral.*; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.operators.BiOperator; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.operators.NotOperator; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.operators.SubOperator; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.Token; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenPosition; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenStream; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenType; +import fr.jamailun.ultimatespellsystem.dsl2.visitor.ExpressionVisitor; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Deque; +import java.util.List; + +/** + * An "expression" is a typed element, used by {@link StatementNode statements}.
+ * Types are statically checked.
+ * This class can parse expressions using the {@link #readNextExpression(TokenStream)} method. + */ +public abstract class ExpressionNode extends Node { + + private final TokenPosition position; + + /** + * New instance of an expression, needs a position. + * @param position non-null position of the first token. + */ + protected ExpressionNode(@NotNull TokenPosition position) { + this.position = position; + } + + /** + * Get the position of the first token of the expression. + * @return a non-null token position. + */ + public @NotNull TokenPosition firstTokenPosition() { + return position; + } + + /** + * Get the {@link Type} of this expression. + * @return a valid and non-null Type. + */ + public abstract @NotNull Type getExpressionType(); + + /** + * Make a Visitor visit this node. + * @param visitor the non-null visitor to call. + */ + public abstract void visit(@NotNull ExpressionVisitor visitor); + + /** + * Extract the next Expression-Node from a tokens-stream. + * @param tokens the tokens-stream to create the next expression with. + * @return a non-null expression. + * @throws UssException if a problems occurs. + */ + public static @NotNull ExpressionNode readNextExpression(@NotNull TokenStream tokens) { + return readNextExpression(tokens, new MathParsingQueue(false), true); + } + + private static ExpressionNode readNextExpression(TokenStream tokens, MathParsingQueue mathStack, boolean logicFirst) { + ExpressionNode raw = readNextExpressionBuffer(tokens); + // Check if the element is accessed ! + if(tokens.dropOptional(TokenType.SQUARE_BRACKET_OPEN)) { + ExpressionNode index = readNextExpression(tokens); + tokens.dropOrThrow(TokenType.SQUARE_BRACKET_CLOSE); + raw = new ArrayGetterExpression(raw, index); + } + + ExpressionNode withMath = tryConvertMathOperations(raw, tokens, mathStack); + return tryConvertLogicalExpression(withMath, tokens, logicFirst); + } + + private static @NotNull ExpressionNode readNextExpressionBuffer(@NotNull TokenStream tokens) { + Token token = tokens.next(); + return switch (token.getType()) { + // Mono-operators + case OPE_NOT -> { + ExpressionNode nextExpression = readNextExpression(tokens); + yield new NotOperator(token, nextExpression); + } + case OPE_SUB -> { + TokenPosition position = tokens.position(); + ExpressionNode nextExpression = readNextExpression(tokens); + yield new SubOperator(position, new NumberExpression(position, 0), nextExpression); + } + + // Literals + case VALUE_NUMBER -> new NumberExpression(token); + case VALUE_BOOLEAN -> new BooleanExpression(token); + case VALUE_STRING -> new StringExpression(token); + case VALUE_DURATION -> new DurationExpression(token); + case NULL -> new NullExpression(token.pos()); + case CHAR_AT -> LocationLiteral.readNextLocation(tokens); + + + // Toutes les compositions de + // "A.B", "A.B(...)", "A[B]" et "A". + case IDENTIFIER -> parseIdentifierExpression(token, tokens); + + + // Openers: '{', '[', '(' + case BRACES_OPEN -> MapLiteral.parseMap(tokens); + case SQUARE_BRACKET_OPEN -> ArrayExpression.parseRawArray(tokens); + case BRACKET_OPEN -> ParenthesisExpression.parseParenthesis(tokens); + + + // Other + default -> throw new SyntaxException(token, "Unexpected expression-start."); + }; + } + + + private static ExpressionNode parseIdentifierExpression(Token first, TokenStream tokens) { + ExpressionNode left = new ReferenceExpression(first); + return parseIdentifierExpression(left, tokens); + } + + // a.b.c + // first = 'a' + private static @NotNull ExpressionNode parseIdentifierExpression(@NotNull ExpressionNode left, @NotNull TokenStream tokens) { + // IDENTIFIER. ? + if(tokens.dropOptional(TokenType.DOT)) { + // Il faut une expression ! + // i.e. "a.IDENTIFIER" ! + Token identifier = tokens.nextOrThrow(TokenType.IDENTIFIER, "After 'IDENTIFIER.' can only accept a 'IDENTIFIER'."); + + // Parenthèse ? + // a.IDENTIFIER(...) + if(tokens.dropOptional(TokenType.BRACES_OPEN)) { + List arguments = parseArgumentsParameter(tokens); + String fctName = identifier.getContentString(); + ExpressionNode fctCall = new FunctionCallExpression(left, fctName, arguments); + + // Après "a.b(...)" on peut avoir une suite. Donc, on refait une boucle. + return parseIdentifierExpression(fctCall, tokens); + } + + // Pas de parenthèse, on a bien un simple "a.b" + // On package le tout en une expression + ExpressionNode fieldGet = new FieldGetExpression(left, identifier.getContentString()); + + // (a.b).c + return parseIdentifierExpression(fieldGet, tokens); + } + + // IDENTIFIER[ ? + if(tokens.dropOptional(TokenType.SQUARE_BRACKET_OPEN)) { + ExpressionNode index = ExpressionNode.readNextExpression(tokens); + tokens.dropOrThrow(TokenType.SQUARE_BRACKET_CLOSE, "Expected an array-get close ']' after it was opened."); + ArrayGetterExpression arrayGet = new ArrayGetterExpression(left, index); + + // On peut avoir "a[b].c", donc on refait un tour + return parseIdentifierExpression(arrayGet, tokens); + } + + // à priori, cas par défaut : on renvoie tout simplement l'expression qu'on a reçu. + // Dans le cas VRAIMENT par défaut, c'est donc une référence de variable. + return left; + } + + public static List parseArgumentsParameter(@NotNull TokenStream tokens) { + List list = new ArrayList<>(); + boolean first = true; + while(!tokens.dropOptional(TokenType.BRACES_CLOSE)) { + if(first) first = false; else tokens.dropOrThrow(TokenType.COMMA, "A COMMA is required between parameters."); + ExpressionNode expression = ExpressionNode.readNextExpression(tokens); + list.add(expression); + } + return list; + } + + private final static List LOW_PRIORITY_OPERATORS = List.of(TokenType.OPE_ADD, TokenType.OPE_SUB); + private final static List HIGH_PRIORITY_OPERATORS = List.of(TokenType.OPE_MUL, TokenType.OPE_DIV); + + private static ExpressionNode tryConvertMathOperations(ExpressionNode expr, @NotNull TokenStream tokens, MathParsingQueue stack) { + Token token = tokens.peek(); + + // Low-priority : push to stack + if(LOW_PRIORITY_OPERATORS.contains(token.getType()) && !stack.priority) { + tokens.drop(); + // push to stack + stack.expressionStack.push(expr); + stack.operandsStack.push(token); + // fetch next one + return readNextExpression(tokens, stack, true); + } + + // High-priority operators + if(HIGH_PRIORITY_OPERATORS.contains(token.getType())) { + tokens.drop(); + // don't push to stack. Get the next one and convert directly + ExpressionNode nextOne = readNextExpression(tokens, new MathParsingQueue(true), true); + BiOperator current = BiOperator.parseBiOperator(expr, token, nextOne); + // And redo (try to have more operators) + return tryConvertMathOperations(current, tokens, stack); + } + + // No operator after (EOE) : unstack the stack, build expression tree, return it. + return stack.deStack(expr); + } + + private static @NotNull ExpressionNode tryConvertLogicalExpression(ExpressionNode expr, @NotNull TokenStream tokens, boolean firstLevel) { + Token token = tokens.peek(); + return switch(token.getType()) { + case OPE_OR, OPE_AND -> { + if(!firstLevel) + yield expr; + tokens.drop(); + ExpressionNode right = readNextExpression(tokens, new MathParsingQueue(false), true); + yield BiOperator.parseBiOperator(expr, token, right); + } + case COMP_NE, COMP_EQ, COMP_GT, COMP_LT, COMP_LE, COMP_GE -> { + tokens.drop(); + ExpressionNode right = readNextExpression(tokens, new MathParsingQueue(false), false); + BiOperator newFormed = BiOperator.parseBiOperator(expr, token, right); + yield tryConvertLogicalExpression(newFormed, tokens, true); + } + default -> expr; + }; + } + + private static class MathParsingQueue { + final Deque expressionStack = new ArrayDeque<>(); + final Deque operandsStack = new ArrayDeque<>(); + final boolean priority; + + MathParsingQueue(boolean priority) { + this.priority = priority; + } + + @Override + public String toString() { + return "{"+(priority?"! ":"")+"E="+expressionStack+", O="+operandsStack+"}"; + } + + ExpressionNode deStack(ExpressionNode expr) { + ExpressionNode topRight = expr; + // Dépiler peu à peu + while( ! expressionStack.isEmpty()) { + ExpressionNode node = expressionStack.pop(); + Token ope = operandsStack.pop(); + // Fusion right operators + topRight = BiOperator.parseBiOperator(node, ope, topRight); + } + return topRight; + } + } + +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/Node.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/Node.java new file mode 100644 index 00000000..dddc3a64 --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/Node.java @@ -0,0 +1,79 @@ +package fr.jamailun.ultimatespellsystem.dsl2.nodes; + +import fr.jamailun.ultimatespellsystem.dsl2.errors.TypeException; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.CollectionFilter; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.variables.TypesContext; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +/** + * A node is an element of the AST. + * It can be a statement of an expression. + */ +public abstract class Node { + + /** + * Validates the TYPE of the handled elements. No logic test is done here. + * @param context the typing context. + */ + public abstract void validateTypes(@NotNull TypesContext context); + + /** + * Assert an expression to be of a specific type. + * @param expression the expression to check. + * @param filter the filter for collection. + * @param type the expected type. + * @param otherTypes a variadic for other allowed types. + */ + protected void assertExpressionType(@NotNull ExpressionNode expression, @NotNull CollectionFilter filter, @NotNull TypePrimitive type, TypePrimitive... otherTypes) { + if(expression.getExpressionType().is(TypePrimitive.NULL)) + return; // Ignore NULL type : it is accepted by everything. + + List allowed = new ArrayList<>(List.of(otherTypes)); + allowed.add(type); + + if(! expression.getExpressionType().isOneOf(allowed.toArray(new TypePrimitive[0]))) + throw new TypeException(expression, type); + + if(!filter.isValid(expression.getExpressionType())) { + throw new TypeException(expression, "Type is correct, but expected a "+filter+"."); + } + } + + protected void assertExpressionType(@NotNull ExpressionNode expression, @NotNull Type type) { + if(type.is(TypePrimitive.NULL)) + return; // On ignore tlr type null + + if(!expression.getExpressionType().equals(type)) + throw new TypeException(expression, "Type is correct, but expected a "+type+"."); + } + + /** + * Validate the type of expression, and then it to be of a specific type. + * @param expression the expression to check. + * @param filter the filter for collection. + * @param context the current context. + * @param type the expected type. + * @param otherTypes a variadic for other allowed types. + */ + protected void assertExpressionType(@NotNull ExpressionNode expression, @NotNull CollectionFilter filter, @NotNull TypesContext context, @NotNull TypePrimitive type, TypePrimitive... otherTypes) { + expression.validateTypes(context); + assertExpressionType(expression, filter, type, otherTypes); + } + + /** + * Validate the type of expression, and then it to be of a specific type. + * @param expression the expression to check. + * @param context the current context. + * @param type the expected type. + * @param otherTypes a variadic for other allowed types. + */ + protected void assertExpressionType(@NotNull ExpressionNode expression, @NotNull TypesContext context, @NotNull TypePrimitive type, TypePrimitive... otherTypes) { + assertExpressionType(expression, CollectionFilter.ANY, context, type, otherTypes); + } + +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/StatementNode.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/StatementNode.java new file mode 100644 index 00000000..e605f10d --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/StatementNode.java @@ -0,0 +1,127 @@ +package fr.jamailun.ultimatespellsystem.dsl2.nodes; + +import fr.jamailun.ultimatespellsystem.dsl2.errors.SyntaxException; +import fr.jamailun.ultimatespellsystem.dsl2.errors.UssException; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.statements.*; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.statements.blocks.ForLoopStatement; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.statements.blocks.IfElseStatement; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.statements.blocks.WhileLoopStatement; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.Token; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenStream; +import fr.jamailun.ultimatespellsystem.dsl2.visitor.StatementVisitor; +import org.jetbrains.annotations.NotNull; +/** + * A statement is an instruction in the code. It can use other statements, or {@link ExpressionNode expressions}.
+ * Can be visited by a {@link StatementVisitor}. + * This class can parse a statement with the {@link #parseNextStatement(TokenStream)} method. + */ +public abstract class StatementNode extends Node { + + + /** + * Make this statement be visited. + * @param visitor the visitor to use. + */ + public abstract void visit(@NotNull StatementVisitor visitor); +/* + private static @NotNull StatementNode parseFromIdentifier(@NotNull Token first, @NotNull TokenStream tokens) { + if(!tokens.hasMore()) + throw new ParsingException(tokens.position(), "Unexpected end of tokens after identifier."); + + // Pas d'identifier après. Donc c'est une expression simple. + // Genre 'IDENTIFIER.' ou 'IDENTIFIER[' + if(!tokens.peekIs(TokenType.IDENTIFIER, TokenType.EQUAL)) { + //TODO + ExpressionNode expressionNode = ExpressionNode.readNextExpression(tokens, true); + return new SimpleExpressionStatement(expressionNode); + } + + // Cas simple : égal + if(tokens.dropOptional(TokenType.EQUAL)) { + //FIXME ne pas passer un token mais une expression (wra sous forme de variable) + return AffectationStatement.parseNextDefine(first, tokens); + } + + // "IDENTIFIER.IDENTIFIER" ... tout ça c'est le cas complexe. On estime qu'on veut une expression. + + + Token second = tokens.next(); + if(second.getType() != TokenType.IDENTIFIER) { + throw new SyntaxException(second, "Expected an identifier after '" + first.getContentString() + "'."); + } + + // "IDENTIFIER = ..." :: C'est une affectation + if(tokens.dropOptional(TokenType.EQUAL)) { + return AffectationStatement.parseNextDefine(first, tokens); + } + + // "IDENTIFIER IDENTIFIER" on peut soit déclarer une variable, soit une fonction + Token second = tokens.next(); + if(second.getType() != TokenType.IDENTIFIER) { + throw new SyntaxException(second, "Expected an identifier after '" + first.getContentString() + "'."); + } + + // Point-virgule : variable déclarée sans valeur + // "TYPE IDENTIFIER ;" + if(tokens.dropOptional(TokenType.SEMI_COLON)) { + return DeclareNewVariable.parseNextDefine(first, second, false, tokens); + } + // "TYPE IDENTIFIER = ..." + if(tokens.dropOptional(TokenType.EQUAL)) { + return DeclareNewVariable.parseNextDefine(first, second, true, tokens); + } + + // Ici, on attend donc une déclaration de fonction + return FunctionDeclarationStatement.parseNextFunction(first, second, tokens); + } +*/ + /** + * Read a new statement from the tokens stream. + * @param tokens the stream of tokens. + * @return a non-null statement. + * @throws UssException if a problem occurs. + */ + public static @NotNull StatementNode parseNextStatement(@NotNull TokenStream tokens) { + Token token = tokens.next(); + return switch (token.getType()) { + // Empty statement + case SEMI_COLON -> parseNextStatement(tokens); + + case IDENTIFIER -> { + tokens.back(); + ExpressionNode expression = ExpressionNode.readNextExpression(tokens); + // TODO convert me into affectation :) + yield new SimpleExpressionStatement(expression); + } + + // Metadata + //TODO case CHAR_AT -> MetadataStatement.parseMetadata(tokens); + + // Blocks + case BRACES_OPEN -> BlockStatement.parseNextBlock(tokens); + + // Increment / decrement + case INCREMENT -> IncrementStatement.parseIncrementOrDecrement(tokens, true); + case DECREMENT -> IncrementStatement.parseIncrementOrDecrement(tokens, false); + + // Control-Flow + case IF -> IfElseStatement.parseIfStatement(tokens); + case ELSE -> throw new SyntaxException(token, "An ELSE must follow an IF (or the IF's child statement)."); + case FOR -> ForLoopStatement.parseForLoop(tokens); + //TODO case FOREACH -> ForeachLoopStatement.parseForLoop(tokens); + case WHILE -> WhileLoopStatement.parseWhileLoop(tokens, true); + case DO -> WhileLoopStatement.parseWhileLoop(tokens, false); + case BREAK -> BreakContinueStatement.parseNextBreakContinue(tokens, false); + case CONTINUE -> BreakContinueStatement.parseNextBreakContinue(tokens, true); + case RETURN -> ReturnStatement.parseReturn(tokens); + + default -> { + tokens.back(); + ExpressionNode expressionNode = ExpressionNode.readNextExpression(tokens); + yield new SimpleExpressionStatement(expressionNode); + } + //throw new SyntaxException(token, "Unexpected token to begin a statement."); + }; + } + +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/ArrayExpression.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/ArrayExpression.java new file mode 100644 index 00000000..30571655 --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/ArrayExpression.java @@ -0,0 +1,95 @@ +package fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions; + +import fr.jamailun.ultimatespellsystem.dsl2.errors.TypeException; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.ExpressionNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.variables.TypesContext; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.*; +import fr.jamailun.ultimatespellsystem.dsl2.visitor.ExpressionVisitor; +import lombok.Getter; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +/** + * Raw array value. + */ +public class ArrayExpression extends ExpressionNode { + + @Getter + private final List elements; + + private Type selfType; + private Type elementsType; + + protected ArrayExpression(TokenPosition position, List elements) { + super(position); + this.elements = elements; + } + + @Override + public @NotNull Type getExpressionType() { + if(selfType == null) + throw new TypeException(firstTokenPosition(), "Type of primitive has not been set."); + return selfType; + } + + @Override + public void visit(@NotNull ExpressionVisitor visitor) { + visitor.handleArray(this); + } + + @Override + public void validateTypes(@NotNull TypesContext contextParent) { + // avoid non-intentional propagation + TypesContext context = contextParent.childContext(); + + // Check type for all expressions : they must share the same type. + for(ExpressionNode node : elements) { + node.validateTypes(context); + + if(elementsType == null) { + elementsType = node.getExpressionType(); + } else { + //TODO + assertExpressionType(node, elementsType); + } + } + + // Array is empty : type is null as array ? + if(elementsType == null) { + elementsType = TypePrimitive.NULL.asType(); + } + + // Set self type at the end + selfType = elementsType.pushArray(); + } + + @PreviousIndicator(expected = TokenType.SQUARE_BRACKET_OPEN) + public static ArrayExpression parseRawArray(@NotNull TokenStream tokens) { + TokenPosition pos = tokens.position(); + List nodes = new ArrayList<>(); + boolean first = true; + while(tokens.hasMore()) { + Token peek = tokens.peek(); + if(peek.getType() == TokenType.SQUARE_BRACKET_CLOSE) + break; + if( ! first) { + tokens.dropOrThrow(TokenType.COMMA); + } + first = false; + ExpressionNode node = ExpressionNode.readNextExpression(tokens); + nodes.add(node); + } + tokens.dropOrThrow(TokenType.SQUARE_BRACKET_CLOSE); + return new ArrayExpression(pos, nodes); + } + + @Override + public String toString() { + return "ARRAY("+(selfType==null?"? type":selfType)+")[" + elements + "]"; + } + +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/ArrayGetterExpression.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/ArrayGetterExpression.java new file mode 100644 index 00000000..318ea54f --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/ArrayGetterExpression.java @@ -0,0 +1,55 @@ +package fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions; + +import fr.jamailun.ultimatespellsystem.dsl2.errors.TypeException; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.ExpressionNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.CollectionFilter; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.variables.TypesContext; +import fr.jamailun.ultimatespellsystem.dsl2.visitor.ExpressionVisitor; +import lombok.Getter; +import org.jetbrains.annotations.NotNull; + +/** + * Get array value at index. + */ +@Getter +public class ArrayGetterExpression extends ExpressionNode { + + private final ExpressionNode array; + private final ExpressionNode index; + + public ArrayGetterExpression(@NotNull ExpressionNode array, @NotNull ExpressionNode index) { + super(array.firstTokenPosition()); + this.array = array; + this.index = index; + } + + @Override + public @NotNull Type getExpressionType() { + return array.getExpressionType().popArray(); + } + + @Override + public void validateTypes(@NotNull TypesContext context) { + // Index must be a number + assertExpressionType(index, CollectionFilter.MONO_ELEMENT, context, TypePrimitive.NUMBER); + + // Array must be a collection + array.validateTypes(context); + Type typeArray = array.getExpressionType(); + if( ! typeArray.is(TypePrimitive.NULL) && ! typeArray.isCollection()) { + throw new TypeException(this, "Cannot get the value of a non-array."); + } + } + + @Override + public void visit(@NotNull ExpressionVisitor visitor) { + visitor.handleArrayGet(this); + } + + @Override + public String toString() { + return array + "[" + index + "]"; + } +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/FieldGetExpression.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/FieldGetExpression.java new file mode 100644 index 00000000..2a8ee6be --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/FieldGetExpression.java @@ -0,0 +1,45 @@ +package fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions; + +import fr.jamailun.ultimatespellsystem.dsl2.nodes.ExpressionNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.variables.TypesContext; +import fr.jamailun.ultimatespellsystem.dsl2.visitor.ExpressionVisitor; +import lombok.Getter; +import org.jetbrains.annotations.NotNull; + +/** + * Get array value at index. + */ +@Getter +public class FieldGetExpression extends ExpressionNode { + + private final ExpressionNode leftExpression; + private final String fieldName; + + public FieldGetExpression(@NotNull ExpressionNode leftExpression, @NotNull String fieldName) { + super(leftExpression.firstTokenPosition()); + this.leftExpression = leftExpression; + this.fieldName = fieldName; + } + + @Override + public @NotNull Type getExpressionType() { + //TODO pas facile, il faut les définitions des structures. + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void validateTypes(@NotNull TypesContext context) { + //TODO + } + + @Override + public void visit(@NotNull ExpressionVisitor visitor) { + visitor.handleFieldGet(this); + } + + @Override + public String toString() { + return firstTokenPosition() + "." + fieldName; + } +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/FunctionCallExpression.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/FunctionCallExpression.java new file mode 100644 index 00000000..08707923 --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/FunctionCallExpression.java @@ -0,0 +1,45 @@ +package fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions; + +import fr.jamailun.ultimatespellsystem.dsl2.nodes.ExpressionNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.variables.TypesContext; +import fr.jamailun.ultimatespellsystem.dsl2.visitor.ExpressionVisitor; +import lombok.Getter; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +@Getter +public class FunctionCallExpression extends ExpressionNode { + + private final ExpressionNode caller; + private final String functionName; + private final List arguments; + + public FunctionCallExpression(@NotNull ExpressionNode caller, @NotNull String functionName, @NotNull List arguments) { + super(caller.firstTokenPosition()); + this.caller = caller; + this.functionName = functionName; + this.arguments = arguments; + } + + @Override + public @NotNull Type getExpressionType() { + // Pas facile : il faut un registre de définition. + // Ne peut être su qu'après avoir défini toutes les "classes". + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void validateTypes(@NotNull TypesContext context) { + // 1. On vérifie que nos arguments existent :) + for(ExpressionNode argument : arguments) { + argument.validateTypes(context.childContext()); + } + } + + @Override + public void visit(@NotNull ExpressionVisitor visitor) { + throw new UnsupportedOperationException("Not supported yet."); + } +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/ParenthesisExpression.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/ParenthesisExpression.java new file mode 100644 index 00000000..e5e1a565 --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/ParenthesisExpression.java @@ -0,0 +1,55 @@ +package fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions; + +import fr.jamailun.ultimatespellsystem.dsl2.nodes.ExpressionNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.variables.TypesContext; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.PreviousIndicator; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenPosition; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenStream; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenType; +import fr.jamailun.ultimatespellsystem.dsl2.visitor.ExpressionVisitor; +import lombok.Getter; +import org.jetbrains.annotations.NotNull; + +/** + * Group of parenthesis. + */ +@Getter +public class ParenthesisExpression extends ExpressionNode { + + private final ExpressionNode expression; + + protected ParenthesisExpression(@NotNull TokenPosition position, @NotNull ExpressionNode expression) { + super(position); + this.expression = expression; + } + + @Override + public @NotNull Type getExpressionType() { + return expression.getExpressionType(); + } + + @Override + public void visit(@NotNull ExpressionVisitor visitor) { + visitor.handleParenthesis(this); + } + + @Override + public void validateTypes(@NotNull TypesContext context) { + // Keep the same context. + expression.validateTypes(context); + } + + @Override + public String toString() { + return " (" + expression + ") "; + } + + @PreviousIndicator(expected = {TokenType.BRACKET_OPEN}) + public static ParenthesisExpression parseParenthesis(TokenStream tokens) { + TokenPosition pos = tokens.position(); + ExpressionNode expression = ExpressionNode.readNextExpression(tokens); + tokens.dropOrThrow(TokenType.BRACKET_CLOSE); + return new ParenthesisExpression(pos, expression); + } +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/ReferenceExpression.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/ReferenceExpression.java new file mode 100644 index 00000000..09a3947e --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/ReferenceExpression.java @@ -0,0 +1,60 @@ +package fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions; + +import fr.jamailun.ultimatespellsystem.dsl2.errors.SyntaxException; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.ExpressionNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.variables.TypesContext; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.variables.VariableDefinition; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.Token; +import fr.jamailun.ultimatespellsystem.dsl2.visitor.ExpressionVisitor; +import org.jetbrains.annotations.NotNull; + +/** + * A raw reference expression + */ +public class ReferenceExpression extends ExpressionNode { + + private final String varName; + private Type runtimeType; + + /** + * Create a variable expression, which is a REFERENCE to something else. + * The reference will be obtained during type validation. + * @param token the token of the variable itself. + */ + public ReferenceExpression(@NotNull Token token) { + super(token.pos()); + this.varName = token.getContentString(); + } + + /** + * Get the name of the variable. + * @return a non-null string. + */ + public @NotNull String getVariableName() { + return varName; + } + + @Override + public @NotNull Type getExpressionType() { + return runtimeType; + } + + @Override + public void validateTypes(@NotNull TypesContext context) { + VariableDefinition var = context.findVariable(varName); + if(var == null) + throw new SyntaxException(firstTokenPosition(), "Undefined variable '" + varName + "'."); + runtimeType = var.getType(context); + } + + @Override + public String toString() { + return "%" + varName; + } + + @Override + public void visit(@NotNull ExpressionVisitor visitor) { + visitor.handleVariable(this); + } +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/functions/FunctionArgument.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/functions/FunctionArgument.java new file mode 100644 index 00000000..cad108aa --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/functions/FunctionArgument.java @@ -0,0 +1,19 @@ +package fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions; + +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; + +/** + * A declaration of a function argument. + * @param type the type of the argument. + * @param debugName the name of the argument. + * @param optional if true, argument is not mandatory. + */ +public record FunctionArgument(@NotNull Type type, @NotNull String debugName, boolean optional) { + @Contract(pure = true) + @Override + public @NotNull String toString() { + return type + " " + debugName + (optional?"*":""); + } +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/functions/FunctionCallExpression.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/functions/FunctionCallExpression.java new file mode 100644 index 00000000..be09d288 --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/functions/FunctionCallExpression.java @@ -0,0 +1,94 @@ +package fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions; + +import fr.jamailun.ultimatespellsystem.dsl2.errors.SyntaxException; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.ExpressionNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.variables.TypesContext; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.*; +import fr.jamailun.ultimatespellsystem.dsl2.visitor.ExpressionVisitor; +import lombok.Getter; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +/** + * A function call statement. + */ +@Getter +public final class FunctionCallExpression extends ExpressionNode { + + private final FunctionDefinition function; + private final List arguments; + + public FunctionCallExpression(@NotNull TokenPosition position, @NotNull FunctionDefinition function, @NotNull List arguments) { + super(position); + this.function = function; + this.arguments = arguments; + } + + @Override + public void validateTypes(@NotNull TypesContext contextRaw) { + TypesContext context = contextRaw.childContext(); + + // Check argument amount + List listArgs = function.arguments(); + + // Then validate arguments types + for(int i = 0; i < arguments.size(); i++) { + FunctionArgument expected = listArgs.get(i); + ExpressionNode obtained = arguments.get(i); + obtained.validateTypes(context); + } + } + + @Override + public void visit(@NotNull ExpressionVisitor visitor) { + visitor.handleFunction(this); + } + + @Override + public @NotNull Type getExpressionType() { + return function.returnedType(); + } + + /** + * Parse a new function call expression from the tokens stream. + * @param functionDefinition found definition. + * @param tokens tokens streams. + * @return a new instance. + */ + @PreviousIndicator(expected = TokenType.BRACKET_OPEN) + public static @NotNull FunctionCallExpression readNextFunctionCall(@NotNull FunctionDefinition functionDefinition, @NotNull TokenStream tokens) { + List arguments = new ArrayList<>(); + TokenPosition position = tokens.position(); + + boolean first = true; + while(tokens.hasMore()) { + Token peek = tokens.peek(); + if(peek.getType() == TokenType.BRACKET_CLOSE) + break; + if( ! first) { + tokens.dropOrThrow(TokenType.COMMA); + } first = false; + + ExpressionNode argument = ExpressionNode.readNextExpression(tokens); + arguments.add(argument); + } + tokens.dropOrThrow(TokenType.BRACKET_CLOSE); + + // Assert obtained arguments count is expected + if(arguments.size() < functionDefinition.mandatoryArgumentsCount()) + throw new SyntaxException(position, "Invalid arguments count. Expected " + functionDefinition.arguments().size() + " mandatory, got " + arguments.size()); + if(arguments.size() > functionDefinition.arguments().size()) + throw new SyntaxException(position, "Invalid arguments count. Expected " + functionDefinition.arguments().size() + ", got " + arguments.size()); + + // Create and return node + return new FunctionCallExpression(position, functionDefinition, arguments); + } + + @Override + public @NotNull String toString() { + return "F-call{"+function.id()+" (" + arguments + ")}"; + } +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/functions/FunctionDefinition.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/functions/FunctionDefinition.java new file mode 100644 index 00000000..f7085cab --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/functions/FunctionDefinition.java @@ -0,0 +1,27 @@ +package fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions; + +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * Definition for a function to run. But because this is the DSL only, we don't care about really handling the functions. + * @param id the ID of the function. + * @param returnedType the type returned by this function. + * @param arguments the arguments. + */ +public record FunctionDefinition(@NotNull String id, @NotNull Type returnedType, @NotNull List arguments) { + + /** + * Get the amount of mandatory arguments. + * @return a non-negative integer. + */ + public int mandatoryArgumentsCount() { + return (int) arguments.stream() + .filter(a -> ! a.optional()) + .count(); + + } + +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/BooleanExpression.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/BooleanExpression.java new file mode 100644 index 00000000..164d31e7 --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/BooleanExpression.java @@ -0,0 +1,44 @@ +package fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.litteral; + +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.Token; +import fr.jamailun.ultimatespellsystem.dsl2.visitor.ExpressionVisitor; +import org.jetbrains.annotations.NotNull; + +/** + * A raw boolean literal. + */ +public class BooleanExpression extends LiteralExpression { + + private final boolean rawValue; + + /** + * New instance, from a token. + * @param token non-null token to use. + */ + public BooleanExpression(@NotNull Token token) { + super(token.pos()); + this.rawValue = token.getContentBoolean(); + } + + @Override + public @NotNull Boolean getRaw() { + return rawValue; + } + + @Override + public @NotNull Type getExpressionType() { + return TypePrimitive.BOOLEAN.asType(); + } + + @Override + public void visit(@NotNull ExpressionVisitor visitor) { + visitor.handleBooleanLiteral(this); + } + + @Override + public String toString() { + return PREFIX + (rawValue?"TRUE":"FALSE") + SUFFIX; + } +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/DurationExpression.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/DurationExpression.java new file mode 100644 index 00000000..b2fa8156 --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/DurationExpression.java @@ -0,0 +1,46 @@ +package fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.litteral; + +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Duration; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.Token; +import fr.jamailun.ultimatespellsystem.dsl2.visitor.ExpressionVisitor; +import org.jetbrains.annotations.NotNull; + +/** + * A raw {@link Duration} literal. + */ +public class DurationExpression extends LiteralExpression { + + private final Duration duration; + + /** + * New instance, from a token. + * @param token token to use. + */ + public DurationExpression(@NotNull Token token) { + super(token.pos()); + this.duration = new Duration(token.getContentNumber(), token.getContentTimeUnit()); + } + + @Override + public Duration getRaw() { + return duration; + } + + @Override + public @NotNull Type getExpressionType() { + return TypePrimitive.DURATION.asType(); + } + + @Override + public String toString() { + return PREFIX + duration.amount() + " " + duration.timeUnit() + SUFFIX; + } + + @Override + public void visit(@NotNull ExpressionVisitor visitor) { + visitor.handleDurationLiteral(this); + } + +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/LiteralExpression.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/LiteralExpression.java new file mode 100644 index 00000000..23cd5a58 --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/LiteralExpression.java @@ -0,0 +1,38 @@ +package fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.litteral; + +import fr.jamailun.ultimatespellsystem.dsl2.nodes.ExpressionNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.variables.TypesContext; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenPosition; +import org.jetbrains.annotations.NotNull; + +/** + * A literal is a raw value in the code, such as a number, a string, ... + * @param the underlying type to handle. + */ +public abstract class LiteralExpression extends ExpressionNode { + + /** Prefix to toString's */ + protected final static String PREFIX = "<"; + /** Suffix to toString's */ + protected final static String SUFFIX = ">"; + + /** + * New literal. + * @param position position of the corresponding (first) token. + */ + protected LiteralExpression(@NotNull TokenPosition position) { + super(position); + } + + @Override + public void validateTypes(@NotNull TypesContext context) { + // Nothing to do + } + + /** + * Get the underlying value to use. + * @return the literal. + */ + public abstract T getRaw(); + +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/LocationLiteral.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/LocationLiteral.java new file mode 100644 index 00000000..90a35ae9 --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/LocationLiteral.java @@ -0,0 +1,105 @@ +package fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.litteral; + +import fr.jamailun.ultimatespellsystem.dsl2.nodes.ExpressionNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.variables.TypesContext; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.PreviousIndicator; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenPosition; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenStream; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenType; +import fr.jamailun.ultimatespellsystem.dsl2.visitor.ExpressionVisitor; +import lombok.Getter; +import org.jetbrains.annotations.NotNull; + +/** + * A raw {@link org.bukkit.Location} literal. + */ +@Getter +public class LocationLiteral extends ExpressionNode { + + private final ExpressionNode world; + private final ExpressionNode vectorX; + private final ExpressionNode vectorY; + private final ExpressionNode vectorZ; + private final ExpressionNode yaw; + private final ExpressionNode pitch; + + protected LocationLiteral(TokenPosition position, ExpressionNode world, ExpressionNode vectorX, ExpressionNode vectorY, ExpressionNode vectorZ, ExpressionNode yaw, ExpressionNode pitch) { + super(position); + this.world = world; + this.vectorX = vectorX; + this.vectorY = vectorY; + this.vectorZ = vectorZ; + this.yaw = yaw; + this.pitch = pitch; + } + + public boolean asYawAndPitch() { + return yaw != null && pitch != null; + } + + @Override + public @NotNull Type getExpressionType() { + return TypePrimitive.LOCATION.asType(); + } + + @Override + public void visit(@NotNull ExpressionVisitor visitor) { + visitor.handleLocationLiteral(this); + } + + @Override + public void validateTypes(@NotNull TypesContext context) { + assertExpressionType(world, context, TypePrimitive.STRING); + assertExpressionType(vectorX, context, TypePrimitive.NUMBER); + assertExpressionType(vectorY, context, TypePrimitive.NUMBER); + assertExpressionType(vectorZ, context, TypePrimitive.NUMBER); + + if(asYawAndPitch()) { + assertExpressionType(yaw, context, TypePrimitive.NUMBER); + assertExpressionType(pitch, context, TypePrimitive.NUMBER); + } + } + + /** + * Parse a new raw location. + * @param tokens stream of tokens. + * @return a new instance. + */ + @PreviousIndicator(expected = TokenType.CHAR_AT) + public static @NotNull LocationLiteral readNextLocation(@NotNull TokenStream tokens) { + TokenPosition position = tokens.position(); + // Open + tokens.dropOrThrow(TokenType.BRACKET_OPEN); + + // World + vector + ExpressionNode world = ExpressionNode.readNextExpression(tokens); + tokens.dropOrThrow(TokenType.COMMA); + ExpressionNode x = ExpressionNode.readNextExpression(tokens); + tokens.dropOrThrow(TokenType.COMMA); + ExpressionNode y = ExpressionNode.readNextExpression(tokens); + tokens.dropOrThrow(TokenType.COMMA); + ExpressionNode z = ExpressionNode.readNextExpression(tokens); + + // Optional yaw + pitch + ExpressionNode yaw = null; + ExpressionNode pitch = null; + if(tokens.dropOptional(TokenType.COMMA)) { + yaw = ExpressionNode.readNextExpression(tokens); + } + if(tokens.dropOptional(TokenType.COMMA)) { + pitch = ExpressionNode.readNextExpression(tokens); + } + + // Close + tokens.dropOrThrow(TokenType.BRACKET_CLOSE); + + return new LocationLiteral(position, world, x, y, z, yaw, pitch); + } + + @Override + public String toString() { + return "Loc{"+world+", ("+vectorX+","+vectorY+","+vectorZ+")}"; + } +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/MapLiteral.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/MapLiteral.java new file mode 100644 index 00000000..ab1eb4de --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/MapLiteral.java @@ -0,0 +1,88 @@ +package fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.litteral; + +import fr.jamailun.ultimatespellsystem.dsl2.errors.SyntaxException; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.ExpressionNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.variables.TypesContext; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.*; +import fr.jamailun.ultimatespellsystem.dsl2.visitor.ExpressionVisitor; +import lombok.Getter; +import org.jetbrains.annotations.NotNull; + +import java.util.HashMap; +import java.util.Map; + +/** + * Raw properties set. + */ +@Getter +public class MapLiteral extends LiteralExpression> { + + private final Map expressions; + + public MapLiteral(TokenPosition pos, Map expressions) { + super(pos); + this.expressions = expressions; + } + + @Override + public @NotNull Type getExpressionType() { + return TypePrimitive.MAP.asType(); + } + + @Override + public void visit(@NotNull ExpressionVisitor visitor) { + visitor.handleMapLiteral(this); + } + + @Override + public String toString() { + return "{" + expressions + "}"; + } + + @Override + public void validateTypes(@NotNull TypesContext contextParent) { + TypesContext context = contextParent.childContext(); + for(ExpressionNode expression : expressions.values()) + expression.validateTypes(context); + } + + @Override + public Map getRaw() { + return expressions; + } + + @PreviousIndicator(expected = {TokenType.BRACKET_OPEN}) + public static MapLiteral parseMap(TokenStream tokens) { + TokenPosition pos = tokens.position(); + Map expressions = new HashMap<>(); + while(tokens.hasMore()) { + if(tokens.peek().getType() == TokenType.BRACKET_CLOSE) { + // EOP + break; + } + if( ! expressions.isEmpty()) { + tokens.dropOrThrow(TokenType.COMMA); + } + // KEY + String propKey; + Token word = tokens.next(); + if(word.getType() == TokenType.IDENTIFIER) { + propKey = word.getContentString(); + } else if(word.getType().letters) { + propKey = word.getType().name().toLowerCase(); + } else { + throw new SyntaxException(word, "Unexpected token for property-key."); + } + // : + tokens.dropOrThrow(TokenType.COLON); + // VALUE + ExpressionNode value = ExpressionNode.readNextExpression(tokens); + // build + expressions.put(propKey, value); + } + tokens.dropOrThrow(TokenType.BRACKET_CLOSE); + return new MapLiteral(pos, expressions); + } +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/NullExpression.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/NullExpression.java new file mode 100644 index 00000000..4a40e3cb --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/NullExpression.java @@ -0,0 +1,39 @@ +package fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.litteral; + +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenPosition; +import fr.jamailun.ultimatespellsystem.dsl2.visitor.ExpressionVisitor; +import org.jetbrains.annotations.NotNull; + +/** + * The {@code NULL} representation. + */ +public class NullExpression extends LiteralExpression { + + /** + * New instance. + * @param pos position of the keyword. + */ + public NullExpression(@NotNull TokenPosition pos) { + super(pos); + } + + @Override + public Void getRaw() {return null;} + + @Override + public @NotNull Type getExpressionType() { + return TypePrimitive.NULL.asType(); + } + + @Override + public String toString() { + return "NULL"; + } + + @Override + public void visit(@NotNull ExpressionVisitor visitor) { + visitor.handleNullLiteral(this); + } +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/NumberExpression.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/NumberExpression.java new file mode 100644 index 00000000..5916e6f0 --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/NumberExpression.java @@ -0,0 +1,55 @@ +package fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.litteral; + +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.Token; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenPosition; +import fr.jamailun.ultimatespellsystem.dsl2.visitor.ExpressionVisitor; +import org.jetbrains.annotations.NotNull; + +/** + * A raw number literal. + */ +public class NumberExpression extends LiteralExpression { + + private final Double rawValue; + + /** + * New literal, using a token. + * @param token token to use. + */ + public NumberExpression(@NotNull Token token) { + super(token.pos()); + this.rawValue = token.getContentNumber(); + } + + /** + * New instance. + * @param position position of the token. + * @param number value. + */ + public NumberExpression(@NotNull TokenPosition position, double number) { + super(position); + this.rawValue = number; + } + + @Override + public Double getRaw() { + return rawValue; + } + + @Override + public @NotNull Type getExpressionType() { + return TypePrimitive.NUMBER.asType(); + } + + @Override + public String toString() { + return PREFIX + rawValue + SUFFIX; + } + + @Override + public void visit(@NotNull ExpressionVisitor visitor) { + visitor.handleNumberLiteral(this); + } +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/StringExpression.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/StringExpression.java new file mode 100644 index 00000000..40015b47 --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/StringExpression.java @@ -0,0 +1,44 @@ +package fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.litteral; + +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.Token; +import fr.jamailun.ultimatespellsystem.dsl2.visitor.ExpressionVisitor; +import org.jetbrains.annotations.NotNull; + +/** + * A raw string literal. + */ +public class StringExpression extends LiteralExpression { + + private final String rawValue; + + /** + * New raw string. + * @param token token to use. + */ + public StringExpression(@NotNull Token token) { + super(token.pos()); + this.rawValue = token.getContentString(); + } + + @Override + public String getRaw() { + return rawValue; + } + + @Override + public @NotNull Type getExpressionType() { + return TypePrimitive.STRING.asType(); + } + + @Override + public String toString() { + return PREFIX + "\"" + rawValue + "\"" + SUFFIX; + } + + @Override + public void visit(@NotNull ExpressionVisitor visitor) { + visitor.handleStringLiteral(this); + } +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/AddOperator.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/AddOperator.java new file mode 100644 index 00000000..3286ac2e --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/AddOperator.java @@ -0,0 +1,59 @@ +package fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.operators; + +import fr.jamailun.ultimatespellsystem.dsl2.errors.TypeException; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.ExpressionNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.variables.TypesContext; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenPosition; +import org.jetbrains.annotations.NotNull; + +/** + * Addition operator. + */ +public class AddOperator extends BiOperator { + + /** + * New instance. + * @param pos token position. + * @param left first operand. + * @param right second operand + */ + public AddOperator(TokenPosition pos, ExpressionNode left, ExpressionNode right) { + super(pos, left, right); + } + + @Override + public @NotNull BiOpeType getType() { + return BiOpeType.ADD; + } + + @Override + public void validateTypes(@NotNull Type leftType, @NotNull Type rightType, @NotNull TypesContext context) { + //FIXME il faut changer tout ça. + // Les types seront indiqués comme supportant telle ou telle opération. + + // 1) One of them is a String : always compatible + if(leftType.is(TypePrimitive.STRING) || rightType.is(TypePrimitive.STRING)) { + producedType = TypePrimitive.STRING.asType(); + return; + } + + // 2) Some types cannot be added at all. + assertNotMathIncompatible(leftType); + assertNotMathIncompatible(rightType); + + // 3) Same type : always compatible + if(leftType.equals(rightType)) { + producedType = leftType; + return; + } + + throw new TypeException(this, "Incompatibles types for an ADD : " + leftType + " and " + rightType); + } + + @Override + public String toString() { + return "(" + left + "+" + right + ")"; + } +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/BiOperator.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/BiOperator.java new file mode 100644 index 00000000..9a1bae2a --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/BiOperator.java @@ -0,0 +1,107 @@ +package fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.operators; + +import fr.jamailun.ultimatespellsystem.dsl2.errors.SyntaxException; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.ExpressionNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.variables.TypesContext; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.Token; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenPosition; +import fr.jamailun.ultimatespellsystem.dsl2.visitor.ExpressionVisitor; +import org.jetbrains.annotations.NotNull; + +/** + * Operator between two elements. + */ +public abstract class BiOperator extends Operator { + + protected Type producedType = TypePrimitive.NULL.asType(); + + protected final ExpressionNode left; + protected final ExpressionNode right; + + protected BiOperator(@NotNull TokenPosition position, @NotNull ExpressionNode left, @NotNull ExpressionNode right) { + super(position); + this.left = left; + this.right = right; + } + + public abstract @NotNull BiOpeType getType(); + + @Override + public @NotNull Type getExpressionType() { + return producedType; + } + + @Override + public final void validateTypes(@NotNull TypesContext context) { + // Validate + left.validateTypes(context); + right.validateTypes(context); + + // Assert + Type leftType = left.getExpressionType(); + Type rightType = right.getExpressionType(); + + validateTypes(leftType, rightType, context); + } + + protected abstract void validateTypes(@NotNull Type leftType, @NotNull Type rightType, @NotNull TypesContext context); + + @Override + public void visit(@NotNull ExpressionVisitor visitor) { + visitor.handleBiOperator(this); + } + + public static @NotNull BiOperator parseBiOperator(@NotNull ExpressionNode left, @NotNull Token operand, @NotNull ExpressionNode right) { + TokenPosition pos = operand.pos(); + return switch (operand.getType()) { + case OPE_ADD -> new AddOperator(pos, left, right); + case OPE_SUB -> new SubOperator(pos, left, right); + case OPE_MUL, OPE_DIV -> new MulDivOperator(operand, left, right); + case COMP_EQ, COMP_NE, + COMP_GE, COMP_GT, + COMP_LE, COMP_LT, + OPE_AND, OPE_OR -> new LogicalOperator(operand, left, right); + default -> throw new SyntaxException(operand, "Unknown Bi-operator."); + }; + } + + public @NotNull ExpressionNode getLeft() { + return left; + } + + public @NotNull ExpressionNode getRight() { + return right; + } + + public enum BiOpeType { + + // Math + + ADD, + SUB, + MUL, + DIV, + + // Logical + + EQUAL, + NOT_EQUAL, + GREATER_OR_EQ, + GREATER, + LESSER_OR_EQ, + LESSER, + + AND, + OR, + + // List + + LIST_ADD, + LIST_REM, + LIST_REM_INDEX, + LIST_CONTAINS + } + +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/LogicalOperator.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/LogicalOperator.java new file mode 100644 index 00000000..95a4755b --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/LogicalOperator.java @@ -0,0 +1,75 @@ +package fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.operators; + +import fr.jamailun.ultimatespellsystem.dsl2.errors.TypeException; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.ExpressionNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.variables.TypesContext; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.Token; +import org.jetbrains.annotations.NotNull; + +/** + * A logical operator, returning a boolean after comparing two expressions. + */ +public class LogicalOperator extends BiOperator { + + private final BiOpeType type; + + /** + * New instance. + * @param operator token to use. + * @param left first operand. + * @param right second operand + */ + public LogicalOperator(Token operator, ExpressionNode left, ExpressionNode right) { + super(operator.pos(), left, right); + this.type = switch (operator.getType()) { + case COMP_EQ -> BiOpeType.EQUAL; + case COMP_NE -> BiOpeType.NOT_EQUAL; + case COMP_LE -> BiOpeType.LESSER_OR_EQ; + case COMP_LT -> BiOpeType.LESSER; + case COMP_GE -> BiOpeType.GREATER_OR_EQ; + case COMP_GT -> BiOpeType.GREATER; + case OPE_AND -> BiOpeType.AND; + case OPE_OR -> BiOpeType.OR; + default -> throw new RuntimeException("Invalid logical operator : " + operator + " at " + operator.pos()); + }; + } + + @Override + public void validateTypes(@NotNull Type leftType, @NotNull Type rightType, @NotNull TypesContext context) { + // Do not allow collections + if(leftType.isCollection() || rightType.isCollection()) { + throw new TypeException(this, "A " + type + " cannot handle collections."); + } + + // Only allow same type (but still allow NULL :) ) + if(!(leftType.is(TypePrimitive.NULL) || rightType.is(TypePrimitive.NULL))) { + if (!(leftType.equals(rightType))) { + throw new TypeException(firstTokenPosition(), "Logical operator " + this + " has unequal types : " + leftType + " and " + rightType + "."); + } + } + + // If inequality, must be numeric + if(type == BiOpeType.GREATER || type == BiOpeType.GREATER_OR_EQ || type == BiOpeType.LESSER || type == BiOpeType.LESSER_OR_EQ) { + if( ! leftType.isOneOf(TypePrimitive.NUMBER, TypePrimitive.DURATION)) { + throw new TypeException(this, "A comparison can only compare numeric values !"); + } + } + } + + @Override + public @NotNull BiOpeType getType() { + return type; + } + + @Override + public @NotNull Type getExpressionType() { + return TypePrimitive.BOOLEAN.asType(); + } + + @Override + public String toString() { + return "(" + left + " " + type + " " + right + ")"; + } +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/MonoOperator.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/MonoOperator.java new file mode 100644 index 00000000..c7ab96dd --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/MonoOperator.java @@ -0,0 +1,71 @@ +package fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.operators; + +import fr.jamailun.ultimatespellsystem.dsl2.nodes.ExpressionNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.variables.TypesContext; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenPosition; +import fr.jamailun.ultimatespellsystem.dsl2.visitor.ExpressionVisitor; +import lombok.Getter; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Arrays; +import java.util.function.Function; + +/** + * Mono-operator, on a single expression. + */ +@Getter +public abstract class MonoOperator extends ExpressionNode { + + protected final ExpressionNode child; + + protected MonoOperator(TokenPosition position, ExpressionNode child) { + super(position); + this.child = child; + } + + /** + * Get this instance type of operation. + * @return a non-null type of mono-operation. + */ + public abstract @NotNull MonoOpeType getType(); + + @Override + public void visit(@NotNull ExpressionVisitor visitor) { + visitor.handleMonoOperator(this); + } + + @Override + public final void validateTypes(@NotNull TypesContext context) { + child.validateTypes(context); + + validateTypes(child.getExpressionType()); + } + + /** + * Validate the static-type of the code usage. + * @param childType the type to test. + */ + public abstract void validateTypes(@NotNull Type childType); + + public enum MonoOpeType { + NOT(x -> x), + SIN(x -> Math.sin(x.doubleValue())), + COS(x -> Math.cos(x.doubleValue())), + TAN(x -> Math.tan(x.doubleValue())), + SQRT(x -> Math.sqrt(x.doubleValue())), + ABS(x -> x instanceof Integer || x instanceof Long || x instanceof Short || x instanceof Byte ? Math.abs(x.longValue()) : Math.abs(x.doubleValue())), + ; + public final Function function; + MonoOpeType(Function function) { + this.function = function; + } + public static @Nullable MonoOpeType find(@NotNull String value) { + return Arrays.stream(values()) + .filter(v -> v.name().equalsIgnoreCase(value)) + .findAny().orElse(null); + } + } + +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/MulDivOperator.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/MulDivOperator.java new file mode 100644 index 00000000..623ca981 --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/MulDivOperator.java @@ -0,0 +1,69 @@ +package fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.operators; + +import fr.jamailun.ultimatespellsystem.dsl2.errors.TypeException; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.ExpressionNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.variables.TypesContext; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.Token; +import org.jetbrains.annotations.NotNull; + +/** + * Multiplication or division. + */ +public class MulDivOperator extends BiOperator { + + private final BiOpeType type; + + /** + * New instance. + * @param operatorToken token to use. + * @param left first operand. + * @param right second operand + */ + public MulDivOperator(Token operatorToken, ExpressionNode left, ExpressionNode right) { + super(operatorToken.pos(), left, right); + type = switch (operatorToken.getType()) { + case OPE_MUL -> BiOpeType.MUL; + case OPE_DIV -> BiOpeType.DIV; + default -> throw new RuntimeException("Cannot create MulDivOperator with an operand: " + operatorToken + operatorToken.pos()); + }; + } + + @Override + public @NotNull BiOpeType getType() { + return type; + } + + @Override + public void validateTypes(@NotNull Type leftType, @NotNull Type rightType, @NotNull TypesContext context) { + // 1) Do not allow collections + if(leftType.isCollection() || rightType.isCollection()) { + throw new TypeException(this, "A "+type+" cannot handle collections."); + } + + // 2.a) Allow duration/duration + if(leftType.is(TypePrimitive.DURATION) && rightType.is(TypePrimitive.DURATION)) { + producedType = TypePrimitive.NUMBER.asType(); + return; + } + + // 2.b) Only allow number on the right. + if(! rightType.is(TypePrimitive.NUMBER)) { + throw new TypeException(this, "Right expression is of type " + rightType + " : must be a number for "+type+" operand."); + } + + // 3) Allow : (DURATION/LOCATION/NUMBER) with (NUMBER) + if(leftType.is(TypePrimitive.DURATION) || leftType.is(TypePrimitive.NUMBER)) { + producedType = leftType; + return; + } + + throw new TypeException(this, "Incompatibles types for an SUB : " + leftType + " and " + rightType); + } + + @Override + public String toString() { + return "(" + left + (type==BiOpeType.MUL?"*":"/") + right + ")"; + } +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/NotOperator.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/NotOperator.java new file mode 100644 index 00000000..327bbba1 --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/NotOperator.java @@ -0,0 +1,51 @@ +package fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.operators; + +import fr.jamailun.ultimatespellsystem.dsl2.errors.TypeException; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.ExpressionNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.Token; +import org.jetbrains.annotations.NotNull; + +/** + * A NOT Operator for a boolean child-expression. + */ +public class NotOperator extends MonoOperator { + + /** + * New instance. + * @param token token, for the position. + * @param expression expression to invert. + */ + public NotOperator(@NotNull Token token, ExpressionNode expression) { + super(token.pos(), expression); + } + + @Override + public @NotNull MonoOpeType getType() { + return MonoOpeType.NOT; + } + + @Override + public void validateTypes(@NotNull Type childType) { + // No collection + if(childType.isCollection()) { + throw new TypeException(this, "A NEGATION cannot handle collections."); + } + + // Only booleans + if(! childType.is(TypePrimitive.BOOLEAN)) { + throw new TypeException(this, "A NEGATION can only handle booleans."); + } + } + + @Override + public @NotNull Type getExpressionType() { + return TypePrimitive.BOOLEAN.asType(); + } + + @Override + public String toString() { + return "NOT(" + child + ")"; + } +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/Operator.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/Operator.java new file mode 100644 index 00000000..c5236a23 --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/Operator.java @@ -0,0 +1,40 @@ +package fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.operators; + +import fr.jamailun.ultimatespellsystem.dsl2.errors.TypeException; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.ExpressionNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenPosition; +import org.jetbrains.annotations.NotNull; + +/** + * Operator : application of something on another expression. + */ +public abstract class Operator extends ExpressionNode { + + /** + * Saved output type. Cache it here. + */ + protected Type producedType; + + /** + * New operator instance, at a position. + * @param position position to use. + */ + protected Operator(@NotNull TokenPosition position) { + super(position); + } + + /** + * Check the type can be used for math. + * @param a type to use. + */ + protected void assertNotMathIncompatible(@NotNull Type a) { + //TODO FIXME !! + throw new UnsupportedOperationException("todo"); + } + + @Override + public @NotNull Type getExpressionType() { + return producedType; + } +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/SubOperator.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/SubOperator.java new file mode 100644 index 00000000..5068535e --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/SubOperator.java @@ -0,0 +1,59 @@ +package fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.operators; + +import fr.jamailun.ultimatespellsystem.dsl2.errors.TypeException; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.ExpressionNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.variables.TypesContext; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenPosition; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * Subtraction operation between two expressions. + */ +public class SubOperator extends BiOperator { + /** + * New instance. + * @param pos token position. + * @param left first expression. + * @param right second expression. + */ + public SubOperator(TokenPosition pos, ExpressionNode left, ExpressionNode right) { + super(pos, left, right); + } + + @Override + public @NotNull BiOpeType getType() { + return BiOpeType.SUB; + } + + private final static List ALLOWED = List.of(TypePrimitive.NUMBER, TypePrimitive.DURATION, TypePrimitive.LOCATION); + + @Override + public void validateTypes(@NotNull Type leftType, @NotNull Type rightType, @NotNull TypesContext context) { + // No collections ! + if(leftType.isCollection() || rightType.isCollection()) { + throw new TypeException(this, "A NEGATION cannot handle collections."); + } + + if(!leftType.isOneOf(ALLOWED.toArray(new TypePrimitive[0]))) + throw new TypeException(this, "SUB cannot handle L=" + leftType); + if(!rightType.isOneOf(ALLOWED.toArray(new TypePrimitive[0]))) + throw new TypeException(this, "SUB cannot handle R=" + rightType); + + // Otherwise same type : always compatible + if(leftType.equals(rightType)) { + producedType = leftType; + return; + } + + throw new TypeException(this, "Incompatibles types for an SUB : " + leftType + " and " + rightType); + } + + @Override + public String toString() { + return "(" + left + "-" + right + ")"; + } +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/AffectationStatement.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/AffectationStatement.java new file mode 100644 index 00000000..4ea0627e --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/AffectationStatement.java @@ -0,0 +1,55 @@ +package fr.jamailun.ultimatespellsystem.dsl2.nodes.statements; + +import fr.jamailun.ultimatespellsystem.dsl2.nodes.ExpressionNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.StatementNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.variables.TypesContext; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.Token; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenStream; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenType; +import fr.jamailun.ultimatespellsystem.dsl2.visitor.StatementVisitor; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import org.jetbrains.annotations.NotNull; + +/** + * Set a variable value. + */ +@Getter +@RequiredArgsConstructor +public class AffectationStatement extends StatementNode { + + private final String varName; + private final ExpressionNode expression; + + @Override + public void validateTypes(@NotNull TypesContext context) { + //TODO + // expression.validateTypes(context); + } + + @Override + public void visit(@NotNull StatementVisitor visitor) { + //TODO + throw new UnsupportedOperationException("Not implemented yet"); + } + + @Override + public @NotNull String toString() { + return varName + " = " + expression; + } + + /** + * Parse a define statement. + * @param tokens streams of tokens. + * @return a new instance. + */ + public static @NotNull StatementNode parseNextDefine(@NotNull Token identifier, @NotNull TokenStream tokens) { + String varName = identifier.getContentString(); + ExpressionNode expression = ExpressionNode.readNextExpression(tokens); + + // optional ; + tokens.dropOptional(TokenType.SEMI_COLON); + + return new AffectationStatement(varName, expression); + } +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/BlockStatement.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/BlockStatement.java new file mode 100644 index 00000000..bed2e1a8 --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/BlockStatement.java @@ -0,0 +1,65 @@ +package fr.jamailun.ultimatespellsystem.dsl2.nodes.statements; + +import fr.jamailun.ultimatespellsystem.dsl2.nodes.StatementNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.variables.TypesContext; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.PreviousIndicator; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenStream; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenType; +import fr.jamailun.ultimatespellsystem.dsl2.visitor.StatementVisitor; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; +import java.util.StringJoiner; + +/** + * A block statement is a sequence of statements between brackets. + */ +@Getter +@RequiredArgsConstructor +public class BlockStatement extends StatementNode { + + protected final List children; + + @Override + public void validateTypes(@NotNull TypesContext context) { + TypesContext contextChild = context.childContext(); + for(StatementNode child : children) { + child.validateTypes(contextChild); + } + } + + @Override + public void visit(@NotNull StatementVisitor visitor) { + visitor.handleBlock(this); + } + + /** + * Parse a block statement. + * @param tokens streams of tokens. + * @return a new instance. + */ + @PreviousIndicator(expected = {TokenType.BRACES_OPEN}) + public static @NotNull BlockStatement parseNextBlock(@NotNull TokenStream tokens) { + List list = new ArrayList<>(); + + while(tokens.hasMore()) { + if(tokens.peek().getType() == TokenType.BRACES_CLOSE) { + break; + } + list.add(StatementNode.parseNextStatement(tokens)); + } + tokens.dropOrThrow(TokenType.BRACES_CLOSE); + + return new BlockStatement(list); + } + + @Override + public String toString() { + StringJoiner sj = new StringJoiner("; ", "{", "}"); + children.forEach(c -> sj.add(c.toString())); + return sj.toString(); + } +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/BreakContinueStatement.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/BreakContinueStatement.java new file mode 100644 index 00000000..981666e1 --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/BreakContinueStatement.java @@ -0,0 +1,47 @@ +package fr.jamailun.ultimatespellsystem.dsl2.nodes.statements; + +import fr.jamailun.ultimatespellsystem.dsl2.nodes.StatementNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.variables.TypesContext; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.PreviousIndicator; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenStream; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenType; +import fr.jamailun.ultimatespellsystem.dsl2.visitor.StatementVisitor; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import org.jetbrains.annotations.NotNull; + +/** + * Either a {@code break} or a {@code continue}. + */ +@RequiredArgsConstructor +@Getter +public class BreakContinueStatement extends StatementNode { + + private final boolean isContinue; + + @Override + public void visit(@NotNull StatementVisitor visitor) { + visitor.handleBreakContinue(this); + } + + @Override + public void validateTypes(@NotNull TypesContext context) { + // We don't have anything to do ! + } + + @Override + public String toString() { + return isContinue ? "continue" : "break"; + } + + /** + * Parse a break/continue statement. + * @param tokens streams of tokens. + * @return a new instance. + */ + @PreviousIndicator(expected = {TokenType.BREAK, TokenType.CONTINUE}) + public static @NotNull BreakContinueStatement parseNextBreakContinue(@NotNull TokenStream tokens, boolean isContinue) { + tokens.dropOrThrow(TokenType.SEMI_COLON); + return new BreakContinueStatement(isContinue); + } +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/DeclareNewVariable.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/DeclareNewVariable.java new file mode 100644 index 00000000..f7aca9a1 --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/DeclareNewVariable.java @@ -0,0 +1,58 @@ +package fr.jamailun.ultimatespellsystem.dsl2.nodes.statements; + +import fr.jamailun.ultimatespellsystem.dsl2.nodes.ExpressionNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.StatementNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.variables.TypesContext; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.Token; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenStream; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenType; +import fr.jamailun.ultimatespellsystem.dsl2.visitor.StatementVisitor; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import org.jetbrains.annotations.NotNull; + +/** + * Define statement will set a variable to something. + */ +@Getter +@RequiredArgsConstructor +public class DeclareNewVariable extends StatementNode { + + private final String varType; + private final String varName; + private final ExpressionNode expression; + + @Override + public void validateTypes(@NotNull TypesContext context) { + expression.validateTypes(context); + // Register variable + //TODO + context.registerVariable(varName, expression); + } + + @Override + public void visit(@NotNull StatementVisitor visitor) { + visitor.handleDefine(this); + } + + @Override + public String toString() { + return varType + " " + varName + " = " + expression; + } + + /** + * Parse a define statement. + * @param tokens streams of tokens. + * @return a new instance. + */ + public static @NotNull StatementNode parseNextDefine(@NotNull Token typeIdentifier, @NotNull Token varIdentifier, boolean hasValue, @NotNull TokenStream tokens) { + String varType = typeIdentifier.getContentString(); + String varName = varIdentifier.getContentString(); + ExpressionNode expression = hasValue ? ExpressionNode.readNextExpression(tokens) : null; + + // optional ; + tokens.dropOptional(TokenType.SEMI_COLON); + + return new DeclareNewVariable(varType, varName, expression); + } +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/FunctionDeclarationStatement.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/FunctionDeclarationStatement.java new file mode 100644 index 00000000..784cfcdb --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/FunctionDeclarationStatement.java @@ -0,0 +1,65 @@ +package fr.jamailun.ultimatespellsystem.dsl2.nodes.statements; + +import fr.jamailun.ultimatespellsystem.dsl2.nodes.StatementNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.variables.TypesContext; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.Token; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenStream; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenType; +import fr.jamailun.ultimatespellsystem.dsl2.visitor.StatementVisitor; +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +@Getter +@AllArgsConstructor +public class FunctionDeclarationStatement extends StatementNode { + + private final String functionReturnType; + private final String functionName; + private final List parameters; + private final List statements; + + @Override + public void visit(@NotNull StatementVisitor visitor) { + //TODO + throw new UnsupportedOperationException("Not implemented yet"); + } + + @Override + public void validateTypes(@NotNull TypesContext context) { + //TODO + throw new UnsupportedOperationException("Not implemented yet"); + } + + public static @NotNull FunctionDeclarationStatement parseNextFunction(@NotNull Token typeIdentifier, @NotNull Token nameIdentifier, @NotNull TokenStream tokens) { + String functionReturnType = typeIdentifier.getContentString(); + String functionName = nameIdentifier.getContentString(); + + // on a déjà retiré le '('. + + List parameters = new ArrayList<>(); + boolean first = true; + while(! tokens.dropOptional(TokenType.BRACES_CLOSE)) { + if(first) first = false; else tokens.dropOrThrow(TokenType.COMMA); + // Each parameter + Token identifierType = tokens.nextOrThrow(TokenType.IDENTIFIER); + Token identifierName = tokens.nextOrThrow(TokenType.IDENTIFIER); + parameters.add(new FunctionParameter(identifierType.getContentString(), identifierName.getContentString())); + } + + // On ne veut pas un 'block-statement' mais nécessairement des statements + tokens.dropOptional(TokenType.BRACKET_OPEN); + List statements = new ArrayList<>(); + while(! tokens.dropOptional(TokenType.BRACKET_CLOSE)) { + statements.add(StatementNode.parseNextStatement(tokens)); + tokens.dropOptional(TokenType.SEMI_COLON); + } + + return new FunctionDeclarationStatement(functionReturnType, functionName, parameters, statements); + } + + public record FunctionParameter(String type, String name) {} +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/IncrementStatement.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/IncrementStatement.java new file mode 100644 index 00000000..e1438b59 --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/IncrementStatement.java @@ -0,0 +1,59 @@ +package fr.jamailun.ultimatespellsystem.dsl2.nodes.statements; + +import fr.jamailun.ultimatespellsystem.dsl2.errors.SyntaxException; +import fr.jamailun.ultimatespellsystem.dsl2.errors.TypeException; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.StatementNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.variables.TypesContext; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.variables.VariableDefinition; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.*; +import fr.jamailun.ultimatespellsystem.dsl2.visitor.StatementVisitor; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import org.jetbrains.annotations.NotNull; + +/** + * Either {@code increment} or {@code decrement}. + */ +@Getter +@RequiredArgsConstructor +public class IncrementStatement extends StatementNode { + + private final TokenPosition tokenPosition; + private final String varName; + private final boolean positive; + + @Override + public void validateTypes(@NotNull TypesContext context) { + VariableDefinition variableDefinition = context.findVariable(varName); + if(variableDefinition == null) + throw new SyntaxException(tokenPosition, "Unknown variable to " + (positive?"increment":"decrement") + " : '" + varName + "'."); + + Type type = variableDefinition.getType(context); + if(!type.is(TypePrimitive.NUMBER)) + throw new TypeException(tokenPosition, "For " + (positive?"increment":"decrement") + " %"+varName+", expected NUMBER. Got type " + type + "."); + } + + @Override + public void visit(@NotNull StatementVisitor visitor) { + visitor.handleIncrement(this); + } + + /** + * Parse a increment/decrement statement. + * @param tokens streams of tokens. + * @return a new instance. + */ + @PreviousIndicator(expected = {TokenType.INCREMENT, TokenType.DECREMENT}) + public static @NotNull IncrementStatement parseIncrementOrDecrement(@NotNull TokenStream tokens, boolean increment) { + Token var = tokens.nextOrThrow(TokenType.IDENTIFIER); + tokens.dropOptional(TokenType.SEMI_COLON); + return new IncrementStatement(var.pos(), var.getContentString(), increment); + } + + @Override + public String toString() { + return (positive ?"++":"--") + "%" + varName; + } +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/ReturnStatement.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/ReturnStatement.java new file mode 100644 index 00000000..f5706640 --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/ReturnStatement.java @@ -0,0 +1,57 @@ +package fr.jamailun.ultimatespellsystem.dsl2.nodes.statements; + +import fr.jamailun.ultimatespellsystem.dsl2.nodes.ExpressionNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.StatementNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.CollectionFilter; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.variables.TypesContext; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.PreviousIndicator; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenStream; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenType; +import fr.jamailun.ultimatespellsystem.dsl2.visitor.StatementVisitor; +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * A {@code stop} statement will stop the spell execution. + */ +@AllArgsConstructor +@Getter +public class ReturnStatement extends StatementNode { + + private final @Nullable ExpressionNode exitCodeNode; + + @Override + public void validateTypes(@NotNull TypesContext context) { + if(exitCodeNode != null) + assertExpressionType(exitCodeNode, CollectionFilter.MONO_ELEMENT, context, TypePrimitive.NUMBER); + } + + @Override + public void visit(@NotNull StatementVisitor visitor) { + visitor.handleReturn(this); + } + + /** + * Parse a STOP statement. + * @param tokens streams of tokens. + * @return a new instance. + */ + @PreviousIndicator(expected = TokenType.RETURN) + public static @NotNull ReturnStatement parseReturn(@NotNull TokenStream tokens) { + if(tokens.dropOptional(TokenType.SEMI_COLON)) { + return new ReturnStatement(null); + } else { + ExpressionNode exitNode = ExpressionNode.readNextExpression(tokens); + tokens.dropOrThrow(TokenType.SEMI_COLON); + return new ReturnStatement(exitNode); + } + } + + @Override + public String toString() { + return "RETURN" + (exitCodeNode==null?"":"(" + exitCodeNode + ")"); + } +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/SimpleExpressionStatement.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/SimpleExpressionStatement.java new file mode 100644 index 00000000..feac0bdb --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/SimpleExpressionStatement.java @@ -0,0 +1,40 @@ +package fr.jamailun.ultimatespellsystem.dsl2.nodes.statements; + +import fr.jamailun.ultimatespellsystem.dsl2.nodes.ExpressionNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.StatementNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.variables.TypesContext; +import fr.jamailun.ultimatespellsystem.dsl2.visitor.StatementVisitor; +import lombok.Getter; +import org.jetbrains.annotations.NotNull; + +/** + * Wraps an {@link ExpressionNode} as a {@link StatementNode}. + */ +@Getter +public class SimpleExpressionStatement extends StatementNode { + + private final @NotNull ExpressionNode child; + + /** + * Create a new instance. + * @param child wrapped expression, as a statement. + */ + public SimpleExpressionStatement(@NotNull ExpressionNode child) { + this.child = child; + } + + @Override + public void visit(@NotNull StatementVisitor visitor) { + visitor.handleSimpleExpression(this); + } + + @Override + public void validateTypes(@NotNull TypesContext context) { + child.validateTypes(context); + } + + @Override + public String toString() { + return "{" + child + "}"; + } +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/blocks/BlockHolder.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/blocks/BlockHolder.java new file mode 100644 index 00000000..26b5c81a --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/blocks/BlockHolder.java @@ -0,0 +1,34 @@ +package fr.jamailun.ultimatespellsystem.dsl2.nodes.statements.blocks; + +import fr.jamailun.ultimatespellsystem.dsl2.nodes.StatementNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.statements.BlockStatement; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * Wraps another statement. + */ +public abstract class BlockHolder extends StatementNode { + + protected final StatementNode child; + + /** + * New instance. + * @param child child "block". + */ + protected BlockHolder(@NotNull StatementNode child) { + if(child instanceof BlockStatement || child instanceof BlockHolder) + this.child = child; + else + this.child = new BlockStatement(List.of(child)); + } + + /** + * Get the child of the block statement. + * @return the child statement, often a block. + */ + public final @NotNull StatementNode getChild() { + return child; + } +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/blocks/ForLoopStatement.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/blocks/ForLoopStatement.java new file mode 100644 index 00000000..2ada4c17 --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/blocks/ForLoopStatement.java @@ -0,0 +1,82 @@ +package fr.jamailun.ultimatespellsystem.dsl2.nodes.statements.blocks; + +import fr.jamailun.ultimatespellsystem.dsl2.nodes.ExpressionNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.StatementNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.CollectionFilter; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.variables.TypesContext; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.PreviousIndicator; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenStream; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenType; +import fr.jamailun.ultimatespellsystem.dsl2.visitor.StatementVisitor; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * A for loop. + */ +@Getter +@RequiredArgsConstructor +public class ForLoopStatement extends StatementNode { + + private final @Nullable StatementNode initialization; + private final ExpressionNode condition; + private final @Nullable StatementNode iteration; + private final StatementNode child; + + @Override + public void validateTypes(@NotNull TypesContext context) { + TypesContext childContext = context.childContext(); + if(initialization != null) initialization.validateTypes(childContext); + assertExpressionType(condition, CollectionFilter.MONO_ELEMENT, childContext, TypePrimitive.BOOLEAN); + if(iteration != null) iteration.validateTypes(childContext); + child.validateTypes(childContext); + } + + @Override + public void visit(@NotNull StatementVisitor visitor) { + visitor.handleForLoop(this); + } + + /** + * Parse a for-loop statement. + * @param tokens streams of tokens. + * @return a new instance. + */ + @PreviousIndicator(expected = TokenType.FOR) + public static @NotNull ForLoopStatement parseForLoop(@NotNull TokenStream tokens) { + tokens.dropOrThrow(TokenType.BRACKET_OPEN); + + // Optional init + StatementNode init; + if(tokens.peek().getType() == TokenType.SEMI_COLON) { + init = null; + tokens.drop(); + } else { + init = StatementNode.parseNextStatement(tokens); + } + + // Required condition + ExpressionNode condition = ExpressionNode.readNextExpression(tokens); + tokens.dropOrThrow(TokenType.SEMI_COLON); + + // Optional iteration + StatementNode iterator; + if(tokens.dropOptional(TokenType.BRACKET_CLOSE)) { + iterator = null; + } else { + iterator = StatementNode.parseNextStatement(tokens); + tokens.dropOrThrow(TokenType.BRACKET_CLOSE); + } + StatementNode child = StatementNode.parseNextStatement(tokens); + + return new ForLoopStatement(init, condition, iterator, child); + } + + @Override + public String toString() { + return "FOR(" + initialization + "; " + condition + "; " + iteration + "): " + child; + } +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/blocks/IfElseStatement.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/blocks/IfElseStatement.java new file mode 100644 index 00000000..636ea8e7 --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/blocks/IfElseStatement.java @@ -0,0 +1,78 @@ +package fr.jamailun.ultimatespellsystem.dsl2.nodes.statements.blocks; + +import fr.jamailun.ultimatespellsystem.dsl2.nodes.ExpressionNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.StatementNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.CollectionFilter; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.variables.TypesContext; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.PreviousIndicator; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenStream; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenType; +import fr.jamailun.ultimatespellsystem.dsl2.visitor.StatementVisitor; +import lombok.Getter; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Optional; + +/** + * {@code if} statement. Can be linked to a ELSE. + */ +public class IfElseStatement extends BlockHolder { + + @Getter private final ExpressionNode condition; + private final StatementNode optElse; + + public IfElseStatement(@NotNull ExpressionNode condition, @NotNull StatementNode child, @Nullable StatementNode elseStatement) { + super(child); + this.condition = condition; + this.optElse = elseStatement; + } + + @Override + public void validateTypes(@NotNull TypesContext context) { + assertExpressionType(condition, CollectionFilter.MONO_ELEMENT, context, TypePrimitive.BOOLEAN); + child.validateTypes(context.childContext()); + if(optElse != null) + optElse.validateTypes(context); + } + + public Optional getElse() { + return Optional.ofNullable(optElse); + } + + @Override + public void visit(@NotNull StatementVisitor visitor) { + visitor.handleIf(this); + } + + /** + * Parse a new if+else statement. + * @param tokens streams of tokens. + * @return a new instance. + */ + @PreviousIndicator(expected = TokenType.IF) + public static @NotNull IfElseStatement parseIfStatement(@NotNull TokenStream tokens) { + // Condition + tokens.dropOrThrow(TokenType.BRACKET_OPEN); + ExpressionNode condition = ExpressionNode.readNextExpression(tokens); + tokens.dropOrThrow(TokenType.BRACKET_CLOSE); + + // Content + StatementNode child = StatementNode.parseNextStatement(tokens); + + StatementNode elseStatement = null; + if(tokens.dropOptional(TokenType.ELSE)) { + elseStatement = StatementNode.parseNextStatement(tokens); + } + + // Return + return new IfElseStatement(condition, child, elseStatement); + } + + @Override + public String toString() { + return "IF(" + condition +") : " + child + + (optElse==null ? "" : "\n ELSE : " + optElse); + } +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/blocks/WhileLoopStatement.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/blocks/WhileLoopStatement.java new file mode 100644 index 00000000..ed1be4a8 --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/blocks/WhileLoopStatement.java @@ -0,0 +1,79 @@ +package fr.jamailun.ultimatespellsystem.dsl2.nodes.statements.blocks; + +import fr.jamailun.ultimatespellsystem.dsl2.nodes.ExpressionNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.StatementNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.CollectionFilter; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.variables.TypesContext; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.PreviousIndicator; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenStream; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenType; +import fr.jamailun.ultimatespellsystem.dsl2.visitor.StatementVisitor; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import org.jetbrains.annotations.NotNull; + +/** + * Classic while statement. + */ +@RequiredArgsConstructor +public class WhileLoopStatement extends StatementNode { + + private final ExpressionNode nodeCondition; + @Getter private final StatementNode child; + @Getter private final boolean whileFirst; + + @Override + public void validateTypes(@NotNull TypesContext context) { + TypesContext childContext = context.childContext(); + + assertExpressionType(nodeCondition, CollectionFilter.MONO_ELEMENT, childContext, TypePrimitive.BOOLEAN); + child.validateTypes(childContext); + } + + @Override + public void visit(@NotNull StatementVisitor visitor) { + visitor.handleWhileLoop(this); + } + + /** + * Parse a "while-loop" statement. Can be either a while/do or a do/while. + * @param tokens streams of tokens. + * @return a new instance. + */ + // WHILE() + // DO WHILE() + @PreviousIndicator(expected = {TokenType.WHILE, TokenType.DO}) + public static WhileLoopStatement parseWhileLoop(TokenStream tokens, boolean wasWhile) { + ExpressionNode condition = null; + + if(wasWhile) { + tokens.dropOrThrow(TokenType.BRACKET_OPEN); + condition = ExpressionNode.readNextExpression(tokens); + tokens.dropOrThrow(TokenType.BRACKET_CLOSE); + } + + StatementNode child = StatementNode.parseNextStatement(tokens); + + if( ! wasWhile) { + tokens.dropOrThrow(TokenType.WHILE); + tokens.dropOrThrow(TokenType.BRACKET_OPEN); + condition = ExpressionNode.readNextExpression(tokens); + tokens.dropOrThrow(TokenType.BRACKET_CLOSE); + tokens.dropOptional(TokenType.SEMI_COLON); + } + + return new WhileLoopStatement(condition, child, wasWhile); + } + + public ExpressionNode getCondition() { + return nodeCondition; + } + + @Override + public String toString() { + if(whileFirst) + return "WHILE(" + nodeCondition + ") DO " + child; + return "DO " + child + " WHILE(" + nodeCondition + ")"; + } +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/CollectionFilter.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/CollectionFilter.java new file mode 100644 index 00000000..f7b51a8b --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/CollectionFilter.java @@ -0,0 +1,38 @@ +package fr.jamailun.ultimatespellsystem.dsl2.nodes.type; + +import org.jetbrains.annotations.NotNull; + +/** + * Allow to check if a Type is a collection or not. + */ +public enum CollectionFilter { + + /** + * Only accepts mono-elements. + */ + MONO_ELEMENT, + + /** + * Only accept collections. + */ + LIST, + + /** + * Accepts both. + */ + ANY; + + /** + * Test if a type matches the filter. + * @param type the type to test. + * @return true if the type matches the filter. + */ + public boolean isValid(@NotNull Type type) { + return switch (this) { + case MONO_ELEMENT -> ! type.isCollection(); + case LIST -> type.isCollection(); + case ANY -> true; + }; + } + +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/Duration.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/Duration.java new file mode 100644 index 00000000..d36c9225 --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/Duration.java @@ -0,0 +1,136 @@ +package fr.jamailun.ultimatespellsystem.dsl2.nodes.type; + +import com.google.common.base.Preconditions; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; + +import java.time.temporal.ChronoUnit; +import java.util.Objects; +import java.util.concurrent.TimeUnit; + +/** + * Represents a duration. + * @param amount the quantity of time unit. + * @param timeUnit the unit to use. + */ +public record Duration(double amount, TimeUnit timeUnit) { + + /** + * Convert the duration to a raw seconds-count. + * @return an amount of seconds. + */ + public double toSeconds() { + double factor = switch (timeUnit) { + case NANOSECONDS -> 1E-9; + case MICROSECONDS -> 1E-6; + case MILLISECONDS -> 1E-3; + case SECONDS -> 1; + case MINUTES -> 60; + case HOURS -> 3600; + case DAYS -> 86400; + }; + return amount * factor; + } + + /** + * Adds this duration with another one. + * @param other the other duration. + * @return a new instance of duration. + */ + @Contract("_ -> new") + public @NotNull Duration add(Duration other) { + if(other.timeUnit == timeUnit) + return new Duration(amount + other.amount, timeUnit); + return new Duration(toSeconds() + other.toSeconds(), TimeUnit.SECONDS); + } + + /** + * Subtracts this duration with another one. + * @param other the other duration. + * @return a new instance of duration. + */ + @Contract("_ -> new") + public @NotNull Duration sub(@NotNull Duration other) { + return new Duration(Math.max(0, toSeconds() - other.toSeconds()), TimeUnit.SECONDS); + } + + /** + * Multiply this duration by a lambda + * @param lambda numerical value. + * @return a new duration. + */ + @Contract("_ -> new") + public @NotNull Duration mul(double lambda) { + return new Duration(toSeconds() * lambda, TimeUnit.SECONDS); + } + + /** + * Divide this duration by a lambda + * @param lambda numerical value. Cannot be 0. + * @return a new duration. + */ + @Contract("_ -> new") + public @NotNull Duration div(double lambda) { + Preconditions.checkState(lambda != 0, "Cannot divide by 0."); + return new Duration(toSeconds() / lambda, TimeUnit.SECONDS); + } + + /** + * Divide the duration by another one. Produces a number. + * @param duration duration to divide this instance with. + * @return output value of the duration. + */ + public double div(@NotNull Duration duration) { + return toSeconds() / duration.toSeconds(); + } + + + /** + * Convert the duration to a raw milliseconds-count. + * @return an amount of milliseconds. + */ + public long toMs() { + return (long) (toSeconds() * 1000); + } + + /** + * Convert the duration to a raw ticks-count. + * @return an amount of ticks. + */ + public long toTicks() { + return (long) (toSeconds() * 20); + } + + /** + * For debug purposes, get the unit as a nice string. + * @return a non-null string. + */ + @Contract(pure = true) + public @NotNull String niceUnit() { + String s = amount > 1 ? "s" : ""; + return switch (timeUnit) { + case NANOSECONDS -> "nanosecond" + s; + case MICROSECONDS -> "microsecond" + s; + case MILLISECONDS -> "millisecond" + s; + case SECONDS -> "second" + s; + case MINUTES -> "minute" + s; + case HOURS -> "hour" + s; + case DAYS -> "day" + s; + }; + } + + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) return false; + return toSeconds() == ((Duration)o).toSeconds(); + } + + @Override + public int hashCode() { + return Objects.hash(toSeconds()); + } + + public @NotNull java.time.Duration asJavaDuration() { + return java.time.Duration.of(toMs(), ChronoUnit.MILLIS); + } +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/SpellEntity.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/SpellEntity.java new file mode 100644 index 00000000..35a7e874 --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/SpellEntity.java @@ -0,0 +1,79 @@ +package fr.jamailun.ultimatespellsystem.dsl2.nodes.type; + +import net.kyori.adventure.text.Component; +import org.bukkit.Location; +import org.bukkit.entity.Entity; +import org.bukkit.potion.PotionEffect; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; + +import java.util.Optional; +import java.util.UUID; + +/** + * An entity-representation inside a spell. + */ +public interface SpellEntity { + + /** + * The Bukkit unique ID of the entity. + * @return a non-null value. + */ + @NotNull UUID getUniqueId(); + + /** + * Get the bukkit entity. + * @return a non-null optional. + */ + @Contract(pure = true) + @NotNull Optional getBukkitEntity(); + + /** + * Test is the entity exist within Bukkit. + * @return true if it's a Bukkit entity. + */ + default boolean isBukkit() { + return getBukkitEntity().isPresent(); + } + + /** + * Get the location of the entity. + * @return a non-null location. + */ + @NotNull Location getLocation(); + + /** + * Get the eye-location of the entity. + * @return a non-null location. + */ + @NotNull Location getEyeLocation(); + + /** + * Teleport the entity to another location. + * @param location the non-null location to use. + */ + void teleport(@NotNull Location location); + + /** + * Send a message. + * @param component the message to send. + */ + void sendMessage(@NotNull Component component); + + /** + * Remove the entity from the world. + */ + void remove(); + + /** + * Test ig the entity is valid, i.e. still exists and alive. + * @return true if the entity is alive and well. + */ + boolean isValid(); + + /** + * Add a potion effect. + * @param effect the effect to add. + */ + void addPotionEffect(@NotNull PotionEffect effect); +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/Type.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/Type.java new file mode 100644 index 00000000..558016a1 --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/Type.java @@ -0,0 +1,87 @@ +package fr.jamailun.ultimatespellsystem.dsl2.nodes.type; + +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Objects; +import java.util.Set; + +/** + * Represents the type of expression. + */ +public class Type { + + private final @Nullable TypePrimitive primitive; + private final @Nullable String objectClass; + private final int arrayLevel; + + public Type(@NotNull TypePrimitive primitive, int arrayLevel) { + this.primitive = primitive; + this.objectClass = null; + this.arrayLevel = arrayLevel; + } + + public Type(@NotNull String objectClass, int arrayLevel) { + this.primitive = null; + this.objectClass = objectClass; + this.arrayLevel = arrayLevel; + } + + private Type(@Nullable TypePrimitive primitive, @Nullable String objectClass, int arrayLevel) { + this.primitive = primitive; + this.objectClass = objectClass; + this.arrayLevel = arrayLevel; + } + + /** + * Check if this type is of a primitive. + * @param primitive the primitive to compare this type with. + * @return true if the primitives are equals. + */ + public boolean is(@NotNull TypePrimitive primitive) { + return this.primitive != null && this.primitive == primitive; + } + + public boolean isOneOf(@NotNull TypePrimitive... primitives) { + if(this.primitive == null) return false; + return Set.of(primitives).contains(primitive); + } + + public boolean is(@NotNull String objectClass) { + return this.objectClass != null && this.objectClass.equals(objectClass); + } + + public boolean isCollection() { + return arrayLevel > 0; + } + + @Contract(pure = true) + public @NotNull Type popArray() { + return new Type(primitive, objectClass, Math.max(0, arrayLevel - 1)); + } + + @Contract(pure = true) + public @NotNull Type pushArray() { + return new Type(primitive, objectClass, arrayLevel + 1); + } + + @Contract(pure = true) + @Override + public @NotNull String toString() { + String arraySuffix = "[]".repeat(arrayLevel); + return (primitive==null?objectClass: primitive.name()) + arraySuffix; + } + + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) return false; + Type type = (Type) o; + return arrayLevel == type.arrayLevel && primitive == type.primitive && Objects.equals(objectClass, type.objectClass); + } + + @Override + public int hashCode() { + return Objects.hash(primitive, objectClass, arrayLevel); + } +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/TypePrimitive.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/TypePrimitive.java new file mode 100644 index 00000000..62638ba3 --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/TypePrimitive.java @@ -0,0 +1,78 @@ +package fr.jamailun.ultimatespellsystem.dsl2.nodes.type; + +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Map; + +/** + * Enumeration of a possible types. + */ +public enum TypePrimitive { + + // Real Primitives + /** A String primitive. */ + STRING(String.class), + + /** A number primitive. */ + NUMBER(Number.class), + + /** A boolean primitive. */ + BOOLEAN(Boolean.class), + + /** A temporal duration. */ + DURATION(Duration.class), + + LOCATION, + + MAP(Map.class), + + /** A {@code null} value. */ + NULL; + + public final Class clazz; + + TypePrimitive() { + this(null); + } + TypePrimitive(Class clazz) { + this.clazz = clazz; + } + + /** + * Convert this enumeration element into a new Type instance. + * @return a new, non-null Type instance. + */ + public @NotNull Type asType() { + return new Type(this, 0); + } + + /** + * Convert this enumeration element into a new Type instance, possibly a collection. + * @param collection if true, the returned Type will be a collection. + * @return a new, non-null Type instance. + */ + @Contract("_ -> new") + public @NotNull Type asType(boolean collection) { + return new Type(this, collection ? 1 : 0); + } + + /** + * Parse a string to find the corresponding primitive. + * @param value the name of the primitive. + * @return null if no match. + */ + public static @Nullable TypePrimitive parsePrimitive(@NotNull String value) { + return switch (value.toLowerCase()) { + case "string" -> STRING; + case "number", "double", "float", "integer", "int", "short", "byte" -> NUMBER; + case "boolean", "bool" -> BOOLEAN; + case "duration", "time", "chrono" -> DURATION; + case "null" -> NULL; + case "map", "data", "properties", "properties-set", "properties_set" -> MAP; + default -> null; + }; + } + +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/variables/TypesContext.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/variables/TypesContext.java new file mode 100644 index 00000000..c66b746f --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/variables/TypesContext.java @@ -0,0 +1,89 @@ +package fr.jamailun.ultimatespellsystem.dsl2.nodes.type.variables; + +import fr.jamailun.ultimatespellsystem.dsl2.errors.SyntaxException; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.ExpressionNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenPosition; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.HashMap; +import java.util.Map; + +/** + * A context for type validation. + */ +public class TypesContext { + + private final Map vars = new HashMap<>(); + + /** + * Create a new context, and register the {@code %caster} variable. + */ + public TypesContext() { + //TODO +// promiseVariable("caster", TypePrimitive.ENTITY.asType()); + } + + /** + * Register a new variable. + * @param varName the name of the variable. + * @param variable the expression defining the variable. + */ + public void registerVariable(@NotNull String varName, @NotNull ExpressionNode variable) { + if("caster".equals(varName)) { + throw new SyntaxException(variable.firstTokenPosition(), "Cannot override variable '%" + varName + "'."); + } + + vars.putIfAbsent(varName, new VariableDefinition(varName)); + vars.get(varName).register(new VariableReference.Dynamic(variable)); + vars.get(varName).getType(this); + } + + /** + * Guarantee a variable will be set by a runtime implementation. + * @param name the name of the variable. + * @param type the type of the variable. + */ + public void promiseVariable(@NotNull String name, @NotNull Type type) { + vars.putIfAbsent(name, new VariableDefinition(name)); + vars.get(name).register(new VariableReference.Constant(type, TokenPosition.unknown())); + } + + /** + * Register a variable, with an already guaranteed type. + * @param varName the variable name. + * @param position the position of the declaration. + * @param type the type of variable. + */ + public void registerVariable(@NotNull String varName, @NotNull TokenPosition position, @NotNull Type type) { + if("caster".equals(varName)) { + throw new SyntaxException(position, "Cannot override variable '%" + varName + "'."); + } + + vars.putIfAbsent(varName, new VariableDefinition(varName)); + vars.get(varName).register(new VariableReference.Constant(type, position)); + } + + /** + * Lookup for a specific variable. + * @param varName the name of the variable to look for. + * @return {@code null} if nothing was found. + */ + public @Nullable VariableDefinition findVariable(@NotNull String varName) { + return vars.get(varName); + } + + /** + * Create a new context. This allows sub-scopes to be independents. + * @return a new instance of context, copying the current variables. + */ + @Contract(" -> new") + public @NotNull TypesContext childContext() { + TypesContext child = new TypesContext(); + child.vars.putAll(vars); + return child; + } + +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/variables/VariableDefinition.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/variables/VariableDefinition.java new file mode 100644 index 00000000..057540bb --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/variables/VariableDefinition.java @@ -0,0 +1,59 @@ +package fr.jamailun.ultimatespellsystem.dsl2.nodes.type.variables; + +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; +import lombok.RequiredArgsConstructor; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + * Definition of a variable. Internal representation. + */ +@RequiredArgsConstructor +public class VariableDefinition { + + private final List references = new ArrayList<>(); + private final String name; + + private transient Type computedType; + + /** + * Register a reference to this definition. + * @param reference non-null reference. + */ + public void register(@NotNull VariableReference reference) { + references.add(reference); + computedType = null; + } + + /** + * Get the representation type of this variable. + * @param context current context. + * @return a {@link TypePrimitive#NULL} type if unset. + */ + public @NotNull Type getType(@NotNull TypesContext context) { + if(computedType != null) return computedType; + + // We need ot compute the type + for(VariableReference reference : references) { + Type type = reference.getType(context); + if(type.is(TypePrimitive.NULL) && !type.isCollection()) { + // Nothing here + continue; + } + if(computedType == null || computedType.is(TypePrimitive.NULL)) { + computedType = type; + // We CAN overload a variable that as NULL. + } else if(!computedType.is(TypePrimitive.NULL) && ! computedType.equals(type)) { + throw reference.exception("Cannot change type of an already defined variable (%"+name+"). Previous type: " + computedType + ", new type: " + type + "."); + } + } + + // If type not set, then it's a NULL. + return Objects.requireNonNullElseGet(computedType, TypePrimitive.NULL::asType); + } + +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/variables/VariableReference.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/variables/VariableReference.java new file mode 100644 index 00000000..39627438 --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/variables/VariableReference.java @@ -0,0 +1,78 @@ +package fr.jamailun.ultimatespellsystem.dsl2.nodes.type.variables; + +import fr.jamailun.ultimatespellsystem.dsl2.errors.TypeException; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.ExpressionNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenPosition; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import org.jetbrains.annotations.NotNull; + +/** + * A reference to a variable.
+ * Used internally to have a pseudo-type inference for variables. + */ +public abstract class VariableReference { + + /** + * Get the type of the variable. + * @param context current context. + * @return a non-null type. NULL if unset. + */ + public abstract @NotNull Type getType(@NotNull TypesContext context); + + /** + * Create a new specific exception. + * @param message exception message. + * @return a new instance of an exception. + */ + abstract @NotNull TypeException exception(@NotNull String message); + + /** + * Constant variable value. + */ + @Getter + @RequiredArgsConstructor + public static class Constant extends VariableReference { + private final Type type; + private final TokenPosition position; + @Override + public @NotNull Type getType(@NotNull TypesContext context) { + return type; + } + @Override + @NotNull TypeException exception(@NotNull String message) { + return new TypeException(position, message); + } + @Override + public String toString() { + return "type(" + type + ")"; + } + } + + /** + * Dynamic reference. + */ + @RequiredArgsConstructor + public static class Dynamic extends VariableReference { + private final ExpressionNode node; + private boolean computed = false; + @Override + public @NotNull Type getType(@NotNull TypesContext context) { + if(!computed) { + computed = true; + node.validateTypes(context); + } + return node.getExpressionType(); + } + @Override + @NotNull TypeException exception(@NotNull String message) { + return new TypeException(node, message); + } + @Override + public String toString() { + return "type_ref(" + (computed ? node.getExpressionType() : "->"+node) + ")"; + } + } + +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/objects/CallbackEvent.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/objects/CallbackEvent.java new file mode 100644 index 00000000..cc482b7d --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/objects/CallbackEvent.java @@ -0,0 +1,58 @@ +package fr.jamailun.ultimatespellsystem.dsl2.objects; + +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenType; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * A type of callback event. + * @param name the non-null name, used in the DSL. Must not contain any space. + * @param argument optional argument value, able to be read in the callback scope. + */ +public record CallbackEvent(@NotNull String name, @Nullable CallbackArgument argument) { + + public CallbackEvent { + if(name.indexOf(' ') > -1) { + throw new RuntimeException("Invalid callback name. Cannot contain spaces."); + } + } + + /** + * Create a new callback event from arguments. + * @param name the non-null name of the callback. Must not contain any space. + * @param keyword the keyword to use for the argument. + * @param type the argument type of the argument. + * @return a new instance of a callback. + */ + @Contract("_,_,_ -> new") + public static @NotNull CallbackEvent of(@NotNull String name, @NotNull TokenType keyword, @NotNull TypePrimitive type) { + return new CallbackEvent(name, new CallbackArgument(keyword, type)); + } + + /** + * Create a new callback event without argument. + * @param name the non-null name of the callback. Must not contain any space. + * @return a new instance of a callback. + */ + @Contract("_ -> new") + public static @NotNull CallbackEvent of(@NotNull String name) { + return new CallbackEvent(name, null); + } + + /** + * An argument, able to be read in the callback scope. + * @param keyword keyword used by the argument. + * @param type type of the argument. + */ + public record CallbackArgument(@NotNull TokenType keyword, @NotNull TypePrimitive type) { + public CallbackArgument { + if(!keyword.letters) + throw new RuntimeException("Invalid keyword type. Should be a 'letters' keyword."); + if(type == TypePrimitive.NULL) + throw new RuntimeException("Invalid callback argument type. Cannot be null."); + } + } + +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/registries/CallbackEventRegistry.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/registries/CallbackEventRegistry.java new file mode 100644 index 00000000..623c146a --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/registries/CallbackEventRegistry.java @@ -0,0 +1,58 @@ +package fr.jamailun.ultimatespellsystem.dsl2.registries; + +import fr.jamailun.ultimatespellsystem.dsl2.objects.CallbackEvent; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.*; + +/** + * Register new callback handling. + * @see #register(CallbackEvent) + */ +public final class CallbackEventRegistry { + private CallbackEventRegistry() {} + + private static final Map CALLBACKS = new HashMap<>(); + + /** + * Register a callback. + * @param callback a valid callback. + */ + public static void register(@NotNull CallbackEvent callback) { + CALLBACKS.put(prepare(callback.name()), callback); + } + + /** + * Find a callback. + * @param callbackName name of the callback. + * @return null if callback name does not exist. + */ + public static @Nullable CallbackEvent get(@NotNull String callbackName) { + return CALLBACKS.get(prepare(callbackName)); + } + + /** + * Test if a callback has been registered. + * @param callbackName the callback name to test. + * @return true if callback exists. + */ + public static boolean exists(@NotNull String callbackName) { + return CALLBACKS.containsKey(prepare(callbackName)); + } + + /** + * Remove a callback name. + * @param callbackName callback name to remove. + */ + public static void unregister(@NotNull String callbackName) { + CALLBACKS.remove(prepare(callbackName)); + } + + @Contract(pure = true) + private static @NotNull String prepare(@NotNull String input) { + return input.toLowerCase(); + } + +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/registries/EntityTypeRegistry.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/registries/EntityTypeRegistry.java new file mode 100644 index 00000000..6f1680a4 --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/registries/EntityTypeRegistry.java @@ -0,0 +1,65 @@ +package fr.jamailun.ultimatespellsystem.dsl2.registries; + +import org.bukkit.entity.EntityType; +import org.jetbrains.annotations.NotNull; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +/** + * You may need to allow specific tokens as "EntityType". + * @see #allow(String) + */ +public final class EntityTypeRegistry { + private EntityTypeRegistry() {} + + private static final Set ALLOWED = new HashSet<>(); + + /** + * Allow a string to be allowed. + * @param entityType an Entity-Type string. + */ + public static void allow(@NotNull String entityType) { + ALLOWED.add(prepare(entityType)); + } + + /** + * Test if a string as been allowed. + * @param entityType the entity-type to test. + * @return true if the entity-type exists. + */ + public static boolean isAllowed(@NotNull String entityType) { + return ALLOWED.contains(prepare(entityType)); + } + + /** + * Disallow an entity type. + * @param entityType the type to disable. + */ + public static void disallow(@NotNull String entityType) { + ALLOWED.remove(prepare(entityType)); + } + + /** + * Prepare a string for a "clean" representation. + * @param string non-null string. + * @return a cleaned string. + */ + public static @NotNull String prepare(@NotNull String string) { + return string.toLowerCase().replace(' ', '_'); + } + + private static final Set FORBIDDEN = Set.of( + EntityType.PLAYER, EntityType.AREA_EFFECT_CLOUD, EntityType.MARKER, EntityType.LEASH_KNOT, EntityType.PAINTING, + EntityType.ITEM, EntityType.ITEM_FRAME, EntityType.ITEM_DISPLAY, EntityType.GLOW_ITEM_FRAME, EntityType.OMINOUS_ITEM_SPAWNER, + EntityType.FISHING_BOBBER, EntityType.TEXT_DISPLAY, EntityType.INTERACTION, EntityType.BLOCK_DISPLAY, EntityType.FIREWORK_ROCKET + ); + + static { + Arrays.stream(EntityType.values()) + .filter(e -> ! FORBIDDEN.contains(e)) + .forEach(e -> allow(e.name())); + } + +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/registries/FunctionDefinitionsRegistry.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/registries/FunctionDefinitionsRegistry.java new file mode 100644 index 00000000..1f9738fc --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/registries/FunctionDefinitionsRegistry.java @@ -0,0 +1,55 @@ +package fr.jamailun.ultimatespellsystem.dsl2.registries; + +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionDefinition; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.HashMap; +import java.util.Map; + +/** + * A registry for {@link FunctionDefinition}. + */ +public final class FunctionDefinitionsRegistry { + private FunctionDefinitionsRegistry() {} + + private final static Map REGISTRY = new HashMap<>(); + + /** + * Register a new function definition. + * @param functionDefinition the non-null function definition to register + */ + public static void register(@NotNull FunctionDefinition functionDefinition) { + REGISTRY.put(functionDefinition.id(), functionDefinition); + } + + /** + * Register a new function definition, with a specific ID. + * @param key key to register. + * @param functionDefinition the non-null function definition to register + */ + public static void register(@NotNull String key, @NotNull FunctionDefinition functionDefinition) { + REGISTRY.put(key, functionDefinition); + } + + /** + * Test if a function exist. + * @param functionId the function ID to test. + * @return true if a function with this ID has already been registered. + * @see FunctionDefinition#id() + */ + public static boolean exists(@NotNull String functionId) { + return REGISTRY.containsKey(functionId); + } + + /** + * Find a function definition. + * @param functionId the function ID to use. + * @return {@code null} if no function with this ID has been registered. + * @see FunctionDefinition#id() + */ + public static @Nullable FunctionDefinition find(@NotNull String functionId) { + return REGISTRY.get(functionId); + } + +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/registries/RegistryException.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/registries/RegistryException.java new file mode 100644 index 00000000..4c4b44b7 --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/registries/RegistryException.java @@ -0,0 +1,21 @@ +package fr.jamailun.ultimatespellsystem.dsl2.registries; + +import fr.jamailun.ultimatespellsystem.dsl2.errors.UssException; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenPosition; +import org.jetbrains.annotations.NotNull; + +/** + * An exception triggered when a specific label has not been registered. + */ +public class RegistryException extends UssException { + + /** + * New instance about an unknown label. + * @param position token position + * @param label label cause of the exception. + */ + public RegistryException(@NotNull TokenPosition position, @NotNull String label) { + super(position, "Unknown label '" + label + "'. Did you properly register the provider ?"); + } + +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/tokenization/CharStream.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/tokenization/CharStream.java new file mode 100644 index 00000000..44522347 --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/tokenization/CharStream.java @@ -0,0 +1,112 @@ +package fr.jamailun.ultimatespellsystem.dsl2.tokenization; + +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; + +import java.io.*; +import java.util.StringJoiner; + +/** + * A stream of {@link Character}. + */ +public class CharStream { + + private final char[] chars; + private int index = 0; + private final PositionProvider position = new PositionProvider(); + + public CharStream(char[] chars) { + this.chars = chars; + } + + /** + * Create a new character stream from a string. + * @param string the string to use. + * @return a new CharStream. + */ + @Contract("_ -> new") + public static @NotNull CharStream from(@NotNull String string) { + return new CharStream((string + "\n").toCharArray()); + } + + /** + * Create a new character stream from a file. + * @param file the file to use. + * @return a new CharStream. + */ + @Contract("_ -> new") + public static @NotNull CharStream from(@NotNull File file) { + if(!file.exists()) + throw new RuntimeException("File " + file + " does not exist."); + try(BufferedReader reader = new BufferedReader(new FileReader(file))) { + StringJoiner sj = new StringJoiner("\n"); + String line; + while ((line = reader.readLine()) != null) { + sj.add(line); + } + sj.add("\n"); + String fileContent = sj.toString(); + return from(fileContent); + } catch(IOException e) { + throw new RuntimeException("Cannot read file "+ file, e); + } + } + + /** + * Peek the next character. + * @return the character on current index. + */ + public char peek() { + return chars[index]; + } + + /** + * Get the current character, and move the index. + * @return the character on current index. + */ + public char next() { + char c = chars[index ++]; + position.column++; + if(c == '\n') { + position.column = 1; + position.line++; + } + return c; + } + + /** + * Drop the current character, by simply moving the index. + */ + public void drop() { + if(!hasMore()) + throw new RuntimeException("No more data."); + index++; + } + + /** + * Test if more character are remaining. + * @return {@code true} if more characters are remaining. + */ + public boolean hasMore() { + return index < chars.length - 1; + } + + private static class PositionProvider { + int column = 1; + int line = 1; + + @Contract(" -> new") + public @NotNull TokenPosition pos() { + return new TokenPosition(line, column); + } + } + + /** + * Get the current position of the token. + * @return the current position. + */ + public @NotNull TokenPosition pos() { + return position.pos(); + } + +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/tokenization/PreviousIndicator.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/tokenization/PreviousIndicator.java new file mode 100644 index 00000000..2fbd3ad1 --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/tokenization/PreviousIndicator.java @@ -0,0 +1,23 @@ +package fr.jamailun.ultimatespellsystem.dsl2.tokenization; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * This is declarative-only. No check will be done. + *
+ * Used to indicate to the developer what cas the expected previous token type. + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.SOURCE) +public @interface PreviousIndicator { + + /** + * Previous token. + * @return token types. + */ + TokenType[] expected(); + +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/tokenization/Token.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/tokenization/Token.java new file mode 100644 index 00000000..2f78378a --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/tokenization/Token.java @@ -0,0 +1,149 @@ +package fr.jamailun.ultimatespellsystem.dsl2.tokenization; + +import com.google.common.base.Preconditions; +import lombok.Getter; +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.TimeUnit; + +/** + * Internal representation of a token. + */ +public class Token { + + @Getter private final TokenType type; + private final TokenPosition position; + + private Double contentNumber; + private String contentString; + private TimeUnit contentTimeUnit; + private Boolean contentBoolean; + + /** + * New token. + * @param type type of the token. + * @param position position. + */ + public Token(@NotNull TokenType type, @NotNull TokenPosition position) { + this.type = type; + this.position = position; + } + + /** + * New token from a raw string value. + * @param string textual content. + * @param position token position. + * @return a new instance. + */ + public static @NotNull Token fromString(@NotNull String string, @NotNull TokenPosition position) { + Token token = new Token(TokenType.VALUE_STRING, position); + token.contentString = string; + return token; + } + + /** + * New token from a raw identifier. + * @param string textual content. + * @param position token position. + * @return a new instance. + */ + public static @NotNull Token fromIdentifier(@NotNull String string, @NotNull TokenPosition position) { + Token token = new Token(TokenType.IDENTIFIER, position); + token.contentString = string; + return token; + } + + /** + * New token from a raw boolean. + * @param value boolean content. + * @param position token position. + * @return a new instance. + */ + public static @NotNull Token fromBoolean(boolean value, @NotNull TokenPosition position) { + Token token = new Token(TokenType.VALUE_BOOLEAN, position); + token.contentBoolean = value; + return token; + } + + /** + * New token from a raw numerical value. + * @param number numerical content. + * @param position token position. + * @return a new instance. + */ + public static @NotNull Token fromNumber(double number, @NotNull TokenPosition position) { + Token token = new Token(TokenType.VALUE_NUMBER, position); + token.contentNumber = number; + return token; + } + + /** + * New token from a raw duration value. + * @param number numerical value. + * @param tu time-unit value. + * @param position token position. + * @return a new instance. + */ + public static @NotNull Token fromDuration(double number, @NotNull TimeUnit tu, @NotNull TokenPosition position) { + Token token = new Token(TokenType.VALUE_DURATION, position); + token.contentNumber = number; + token.contentTimeUnit = tu; + return token; + } + + /** + * Get the numerical content, if it exists. + * @return a numerical value. + */ + public @NotNull Double getContentNumber() { + Preconditions.checkState(type == TokenType.VALUE_NUMBER || type == TokenType.VALUE_DURATION, "Cannot get the TIME_UNIT content of type " + type); + return contentNumber; + } + + /** + * Get the time-unit content, if it exists. + * @return a time-unit value. + */ + public @NotNull TimeUnit getContentTimeUnit() { + Preconditions.checkState(type == TokenType.VALUE_DURATION, "Cannot get the TIME_UNIT content of type " + type); + return contentTimeUnit; + } + + /** + * Get the textual content, if it exists. + * @return a textual value. + */ + public @NotNull String getContentString() { + Preconditions.checkState(type == TokenType.VALUE_STRING || type == TokenType.IDENTIFIER, "Cannot get the STRING content of type " + type); + return contentString; + } + + /** + * Get the boolean content, if it exists. + * @return a boolean value. + */ + public boolean getContentBoolean() { + Preconditions.checkState(type == TokenType.VALUE_BOOLEAN, "Cannot get the BOOLEAN content of type " + type); + return contentBoolean; + } + + /** + * Get the token position. + * @return a non-null position instance. + */ + public @NotNull TokenPosition pos() { + return position; + } + + @Override + public String toString() { + return switch (type) { + case IDENTIFIER -> "[" + contentString + "]"; + case VALUE_STRING -> type + "(\"" + contentString + "\")"; + case VALUE_NUMBER -> type + "(" + contentNumber + ")"; + case VALUE_DURATION -> type + "(" + contentNumber + " " + contentTimeUnit + ")"; + case VALUE_BOOLEAN -> type + "(" + contentBoolean + ")"; + default -> type.name(); + }; + } +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/tokenization/TokenPosition.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/tokenization/TokenPosition.java new file mode 100644 index 00000000..49848bf1 --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/tokenization/TokenPosition.java @@ -0,0 +1,26 @@ +package fr.jamailun.ultimatespellsystem.dsl2.tokenization; + +import org.jetbrains.annotations.NotNull; + +/** + * Position in a source file / string. + * @param line the line of the element. + * @param col the column of the element. + */ +public record TokenPosition(int line, int col) { + @Override + public @NotNull String toString() { + if(line == -1 && col == -1) + return "(?:?)"; + return "("+line+":"+col+")"; + } + + private static final TokenPosition UNKNOWN = new TokenPosition(-1, -1); + /** + * Unknown position. + * @return an unknown position. + */ + public static @NotNull TokenPosition unknown() { + return UNKNOWN; + } +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/tokenization/TokenStream.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/tokenization/TokenStream.java new file mode 100644 index 00000000..1deb98de --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/tokenization/TokenStream.java @@ -0,0 +1,153 @@ +package fr.jamailun.ultimatespellsystem.dsl2.tokenization; + +import com.google.common.base.Preconditions; +import fr.jamailun.ultimatespellsystem.dsl2.errors.SyntaxException; +import org.jetbrains.annotations.NotNull; + +import java.util.List; +import java.util.Set; +import java.util.StringJoiner; + +/** + * A stream of {@link Token}. + */ +public class TokenStream { + + private final List tokens; + private int index = 0; + + /** + * Create a new instance from a tokens list. + * @param tokens a non-null list of tokens. + */ + public TokenStream(@NotNull List tokens) { + this.tokens = tokens; + } + + /** + * Read the next character, don't move cursor. + * @return a non-null token. + * @throws IllegalStateException if no more data exist. + */ + public @NotNull Token peek() { + Preconditions.checkState(hasMore(), "No more data."); + return tokens.get(index); + } + + /** + * Test if the next token matches a type. + * @param allowedTypes allowed types. + * @return true if the next token has a specific type. + */ + public boolean peekIs(@NotNull TokenType @NotNull ... allowedTypes) { + Preconditions.checkState(hasMore(), "No more data."); + Preconditions.checkArgument(allowedTypes.length > 0, "Must have at least 1 value."); + TokenType peeked = peek().getType(); + return Set.of(allowedTypes).contains(peeked); + } + + /** + * Read the next character, then move cursor to the next token. + * @return a non-null token. + * @throws IllegalStateException if no more data exist. + */ + public @NotNull Token next() { + Preconditions.checkState(hasMore(), "No more data."); + return tokens.get(index ++); + } + + /** + * Assert the next token is of a specific type, or throw. + * @param type expected type. + * @return a non-null token. + * @throws IllegalStateException if no more data exist. + * @throws SyntaxException if the next token does not match what was expected. + */ + public @NotNull Token nextOrThrow(@NotNull TokenType type) { + Token next = next(); + if(next.getType() != type) + throw new SyntaxException(next, type); + return next; + } + + public @NotNull Token nextOrThrow(@NotNull TokenType type, @NotNull String error) { + Token next = next(); + if(next.getType() != type) + throw new SyntaxException(next, error); + return next; + } + + /** + * Drop the current token, move the cursor. + * @throws IllegalStateException if no more data exist. + */ + public void drop() { + Preconditions.checkState(hasMore(), "No more data."); + index++; + } + + /** + * Assert the current token is of a specific type, then drop it. + * @param expectedType expected type for the current token. + * @throws IllegalStateException if no more data exist. + * @throws SyntaxException if the next token does not match what was expected. + */ + public void dropOrThrow(@NotNull TokenType expectedType) { + Token next = next(); + if(next.getType() != expectedType) + throw new SyntaxException(next, expectedType); + } + + public void dropOrThrow(@NotNull TokenType expectedType, @NotNull String error) { + Token next = next(); + if(next.getType() != expectedType) + throw new SyntaxException(next, error); + } + + /** + * Assert the current token is of a specific type, then drop it if it matches + * @param types expected types for the current token. + * @return true if the next token does match what was expected. Or if no more data exists. + */ + public boolean dropOptional(@NotNull TokenType... types) { + if(hasMore() && List.of(types).contains(peek().getType())) { + drop(); + return true; + } + return false; + } + + /** + * Make the cursor go back. + * @throws IllegalStateException if the cursor is not at the beginning. + */ + public void back() { + Preconditions.checkState(index > 0, "Index is at start, cannot go back."); + index--; + } + + /** + * Test if more data exists. + * @return true if more data can be read. + */ + public boolean hasMore() { + return index < tokens.size(); + } + + @Override + public @NotNull String toString() { + StringJoiner sj = new StringJoiner(", "); + for(int i = index; i < tokens.size(); i++) + sj.add(tokens.get(i).toString()); + return "TokenStream{index="+index+", TOKENS = [" + sj + "] }"; + } + + /** + * Get the current token position. + * @return the current position. + * @throws IllegalStateException if no more data can be read. + */ + public @NotNull TokenPosition position() { + return peek().pos(); + } +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/tokenization/TokenType.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/tokenization/TokenType.java new file mode 100644 index 00000000..4aa9ed13 --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/tokenization/TokenType.java @@ -0,0 +1,94 @@ +package fr.jamailun.ultimatespellsystem.dsl2.tokenization; + +/** + * Type of token. + */ +public enum TokenType { + + // == MONO-CHAR OPERATORS + + // BiOperators + OPE_ADD, // + + OPE_SUB, // - + OPE_MUL, // * + OPE_DIV, // / + OPE_MOD, // % + + // MonoOperators + OPE_NOT, // ! + INCREMENT, // ++ + DECREMENT, // -- + + // Others + COLON, // : + SEMI_COLON, // ; + COMMA, // , + DOT, // . + EQUAL, // = + BRACKET_OPEN, // ( + BRACKET_CLOSE, // ) + SQUARE_BRACKET_OPEN, // [ + SQUARE_BRACKET_CLOSE, // ] + BRACES_OPEN, // { + BRACES_CLOSE, // } + COMP_LT, // < + COMP_GT, // > + + // == BI-CHAR OPERATORS + + COMP_LE, // <= + COMP_GE, // >= + COMP_EQ, // == + COMP_NE, // != + OPE_AND, // '&&' + OPE_OR, // '||' + + // == KEYWORDS + CHAR_AT, // @ + + IF(true), + ELSE(true), + FOR(true), + WHILE(true), + DO(true), + BREAK(true), + CONTINUE(true), + RETURN(true), + + // == RAW VALUES + NULL(true), + VOID(true), + + // == N-CHARS OPERATORS + + IDENTIFIER, // any combination of character that is NOT a string + VALUE_STRING, // combination of characters between quotes + VALUE_NUMBER, + VALUE_DURATION, // number+ [s/ms/m/h/seconds] + VALUE_BOOLEAN, // true/false + + // == END OF FILE + EOF; + + public final boolean letters; + + TokenType() { + this(false); + } + TokenType(boolean letters) { + this.letters = letters; + } + + public Token toToken(TokenPosition position) { + return new Token(this, position); + } + + public boolean isRawValue() { + return this == IDENTIFIER || + this == VALUE_STRING || + this == VALUE_NUMBER || + this == VALUE_DURATION || + this == VALUE_BOOLEAN ; + } + +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/tokenization/Tokenizer.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/tokenization/Tokenizer.java new file mode 100644 index 00000000..8fe8b9ce --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/tokenization/Tokenizer.java @@ -0,0 +1,283 @@ +package fr.jamailun.ultimatespellsystem.dsl2.tokenization; + +import fr.jamailun.ultimatespellsystem.dsl2.errors.ParsingException; +import org.jetbrains.annotations.NotNull; + +import java.util.*; +import java.util.concurrent.TimeUnit; +import java.util.function.Predicate; +import java.util.regex.Pattern; + +/** + * Internal tokenizer. Transforms a string into a list of {@link Token tokens}. + */ +public final class Tokenizer { + + private final static Set OPERATOR_BI_START = Set.of('<', '>', '=', '!', '&', '|', '+', '-'); + private final static Map OPERATORS_MONO = new HashMap<>(); + private final static Map OPERATORS_BI = new HashMap<>(); + private final static Map KEYWORDS = new HashMap<>(); + private final static Map TIME_UNITS = new HashMap<>(); + static { + OPERATORS_MONO.put('/', TokenType.OPE_DIV); + OPERATORS_MONO.put('+', TokenType.OPE_ADD); + OPERATORS_MONO.put('-', TokenType.OPE_SUB); + OPERATORS_MONO.put('*', TokenType.OPE_MUL); + OPERATORS_MONO.put('=', TokenType.EQUAL); + OPERATORS_MONO.put('!', TokenType.OPE_NOT); + OPERATORS_MONO.put(':', TokenType.COLON); + OPERATORS_MONO.put(';', TokenType.SEMI_COLON); + OPERATORS_MONO.put(',', TokenType.COMMA); + OPERATORS_MONO.put('.', TokenType.DOT); + OPERATORS_MONO.put('(', TokenType.BRACKET_OPEN); + OPERATORS_MONO.put(')', TokenType.BRACKET_CLOSE); + OPERATORS_MONO.put('[', TokenType.SQUARE_BRACKET_OPEN); + OPERATORS_MONO.put(']', TokenType.SQUARE_BRACKET_CLOSE); + OPERATORS_MONO.put('{', TokenType.BRACES_OPEN); + OPERATORS_MONO.put('}', TokenType.BRACES_CLOSE); + OPERATORS_MONO.put('<', TokenType.COMP_LT); + OPERATORS_MONO.put('>', TokenType.COMP_GT); + OPERATORS_MONO.put('@', TokenType.CHAR_AT); + + OPERATORS_BI.put("<=", TokenType.COMP_LE); + OPERATORS_BI.put(">=", TokenType.COMP_GE); + OPERATORS_BI.put("==", TokenType.COMP_EQ); + OPERATORS_BI.put("!=", TokenType.COMP_NE); + OPERATORS_BI.put("&&", TokenType.OPE_AND); + OPERATORS_BI.put("||", TokenType.OPE_OR); + OPERATORS_BI.put("++", TokenType.INCREMENT); + OPERATORS_BI.put("--", TokenType.DECREMENT); + + // words + Arrays.stream(TokenType.values()) + .filter(t -> t.letters) + .forEach(t -> KEYWORDS.put(t.name().toLowerCase(), t)); + + // TimeUnits + putTimeUnit(TimeUnit.DAYS, "d", "D", "day", "days"); + putTimeUnit(TimeUnit.HOURS, "h", "H", "hour", "hours"); + putTimeUnit(TimeUnit.MINUTES, "m", "minute", "minutes"); + putTimeUnit(TimeUnit.SECONDS, "s", "sec", "secs", "second", "seconds"); + putTimeUnit(TimeUnit.MILLISECONDS, "ms", "milli", "millisecond", "milliseconds"); + } + + private final CharStream chars; + private final List tokens = new ArrayList<>(); + private boolean done = false; + + /** + * Tokenize a string. + * @param chars a stream of chars. + * @return a new token stream. + */ + public static @NotNull TokenStream tokenize(@NotNull CharStream chars) { + return new Tokenizer(chars).tokenize(); + } + + private final Predicate ALLOWED_WORD_START = Pattern.compile("[A-Za-z_]").asPredicate(); + private final Predicate ALLOWED_WORD_BODY = Pattern.compile("[A-Za-z_0-9]").asPredicate(); + + private Tokenizer(CharStream chars) { + this.chars = chars; + } + + private TokenStream tokenize() { + if(done) + return new TokenStream(tokens); + done = true; + + while(chars.hasMore()) { + char current = chars.next(); + + // Whitespace-trash + if(current == ' ' || current == '\t' || current == '\r' || current == '\n') + continue; + + // Comment + if(current == '#') { + skipUntilEOL(); + continue; + } + + // Basic symbols. + // All bi-operators start with one of the mono... let's use this fact. + // EDIT: just added AND and OR keywords start. + if(OPERATORS_MONO.containsKey(current) || OPERATOR_BI_START.contains(current)) { + if(chars.hasMore()) { + char next = chars.peek(); + + // Number ? + if(current == '.' && isDigit(next)) { + tokens.add(Token.fromNumber(getNumber(current), chars.pos())); + continue; + } + + // Bi-operator ? + String symbol = String.valueOf(current) + next; + if(OPERATORS_BI.containsKey(symbol)) { + addRaw(OPERATORS_BI.get(symbol)); + chars.drop(); + continue; + } + } + addRaw(OPERATORS_MONO.get(current)); + continue; + } + + // String + if(current == '"') { + addString(); + continue; + } + + if(ALLOWED_WORD_START.test(String.valueOf(current))) { + TokenPosition position = chars.pos(); + String word = getWord(current); + + if("true".equals(word) || "false".equals(word)) { + tokens.add(Token.fromBoolean(Boolean.parseBoolean(word), position)); + continue; + } + + if(KEYWORDS.containsKey(word)) { + tokens.add(new Token(KEYWORDS.get(word), position)); + continue; + } + + if(TIME_UNITS.containsKey(word)) { + if(tokens.isEmpty() || last().getType() != TokenType.VALUE_NUMBER ) { + throw new ParsingException(chars.pos(), "Unexpected time unit '"+word+"'."); + } + // Replace number by duration + double number = last().getContentNumber(); + TimeUnit unit = TIME_UNITS.get(word); + tokens.removeLast(); + tokens.add(Token.fromDuration(number, unit, position)); + continue; + } + + tokens.add(Token.fromIdentifier(word, position)); + + continue; + } + + if(isDigit(current)) { + tokens.add(Token.fromNumber(getNumber(current), chars.pos())); + continue; + } + + throw new ParsingException(chars.pos(), current, "Unknown character."); + } + + addRaw(TokenType.EOF); + return new TokenStream(tokens); + } + + private double getNumber(char first) { + StringBuilder sb = new StringBuilder(); + sb.append(first); // Can be a digit, a dot or a negative sign. + + boolean dot = first == '.'; + while(chars.hasMore()) { + char c = chars.peek(); + + // Dot + if(c == '.') { + if(dot) + throw new ParsingException(chars.pos(), c, "Cannot have multiple '.' in a number."); + dot = true; + sb.append('.'); + chars.drop(); + continue; + } + + // Number + if(isDigit(c)) { + sb.append(c); + chars.drop(); + continue; + } + + // EON + break; + } + return Double.parseDouble(sb.toString()); + } + + private void skipUntilEOL() { + while(chars.hasMore()) { + if(chars.next() == '\n') { + break; + } + } + } + + private String getWord(Character firstChar) { + StringBuilder content = new StringBuilder(); + if(firstChar != null) + content.append(firstChar); + + while(chars.hasMore()) { + if( ! ALLOWED_WORD_BODY.test(String.valueOf(chars.peek()))) { + // EOW + break; + } + content.append(chars.next()); + } + + return content.toString(); + } + + private void addString() { + StringBuilder sb = new StringBuilder(); + boolean escaped = false; + boolean closed = false; + while(chars.hasMore()) { + char c = chars.next(); + if(escaped) { + escaped = false; + sb.append(c); + continue; + } + if(c == '\\') { + escaped = true; + continue; + } + if(c == '"') { + // EOS + closed = true; + break; + } + if(c == '\n') { + // EOL ?? + throw new ParsingException(chars.pos(), "Unexpected carriage return in a string."); + } + + // Char + sb.append(c); + } + + if(!closed) + throw new ParsingException(chars.pos(), chars.peek(), "Cannot end file with a '\"' : expected a closing quote for the string."); + + tokens.add(Token.fromString(sb.toString(), chars.pos())); + } + + private static boolean isDigit(char c) { + return c >= '0' && c <= '9'; + } + + private void addRaw(TokenType type) { + tokens.add(type.toToken(chars.pos())); + } + + private static void putTimeUnit(TimeUnit unit, String... identifiers) { + for(String identifier : identifiers) + TIME_UNITS.put(identifier, unit); + } + + private Token last() { + return tokens.getLast(); + } + +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/validators/DslValidator.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/validators/DslValidator.java new file mode 100644 index 00000000..0c289c59 --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/validators/DslValidator.java @@ -0,0 +1,45 @@ +package fr.jamailun.ultimatespellsystem.dsl2.validators; + +import fr.jamailun.ultimatespellsystem.dsl2.nodes.StatementNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.variables.TypesContext; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * Validate the DSL tree. + */ +public final class DslValidator { + private DslValidator() {} + + /** + * Validate an AST. + * @param nodes the AST to validate. + */ + public static void validateDsl(@NotNull List nodes) { + validateType(nodes); + validateTree(nodes); + } + + /** + * Validate and propagate types. + * @param nodes the nodes to handle. + */ + public static void validateType(@NotNull List nodes) { + TypesContext context = new TypesContext(); + for (StatementNode node : nodes) { + node.validateTypes(context); + } + } + + /** + * Validate the tree structure. + * @param nodes the nodes to handle. + */ + public static void validateTree(@NotNull List nodes) { + StructureValidationVisitor visitor = new StructureValidationVisitor(); + for(StatementNode node : nodes) { + node.visit(visitor); + } + } +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/validators/StructureValidationVisitor.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/validators/StructureValidationVisitor.java new file mode 100644 index 00000000..ab0c1467 --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/validators/StructureValidationVisitor.java @@ -0,0 +1,86 @@ +package fr.jamailun.ultimatespellsystem.dsl2.validators; + +import fr.jamailun.ultimatespellsystem.dsl2.errors.TreeValidationException; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.StatementNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.statements.*; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.statements.blocks.ForLoopStatement; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.statements.blocks.IfElseStatement; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.statements.blocks.WhileLoopStatement; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenPosition; +import fr.jamailun.ultimatespellsystem.dsl2.visitor.StatementVisitor; +import org.jetbrains.annotations.NotNull; + +/** + * Structure validation. + */ +public class StructureValidationVisitor implements StatementVisitor { + private boolean stopMet = false; + private boolean breakMet = false; + private boolean metadataAllowed = true; + + private StructureValidationVisitor child() { + StructureValidationVisitor clone = new StructureValidationVisitor(); + clone.metadataAllowed = metadataAllowed; + clone.stopMet = stopMet; + clone.breakMet = breakMet; + return clone; + } + + /* @Override + public void handleMetadata(@NotNull MetadataStatement statement) { + if(!metadataAllowed) + throw new TreeValidationException(TokenPosition.unknown(), "Meta-data can only be the first statements."); + }*/ + + @Override + public void handleReturn(@NotNull ReturnStatement statement) { + handleMono(); + stopMet = true; + } + @Override + public void handleBreakContinue(@NotNull BreakContinueStatement statement) { + handleMono(); + breakMet = true; + } + + @Override + public void handleBlock(@NotNull BlockStatement statement) { + handleMono(); + StructureValidationVisitor child = child(); + statement.getChildren().forEach(n -> n.visit(child)); + } + + private void handleSub(@NotNull StatementNode child) { + child.visit(child()); + } + + private void handleMono() { + metadataAllowed = false; + if(stopMet) { + throw new TreeValidationException(TokenPosition.unknown(), "Cannot have a statement after a STOP."); + } + if(breakMet) { + throw new TreeValidationException(TokenPosition.unknown(), "Cannot have a statement in the block after a BREAK or a CONTINUE."); + } + } + + @Override + public void handleIf(@NotNull IfElseStatement statement) { + handleSub(statement.getChild()); + statement.getElse().ifPresent(this::handleSub); + } + @Override + public void handleForLoop(@NotNull ForLoopStatement statement) { + handleSub(statement.getChild()); + } + @Override + public void handleWhileLoop(@NotNull WhileLoopStatement statement) { + handleSub(statement.getChild()); + } + @Override + public void handleDefine(@NotNull DeclareNewVariable statement) {handleMono();} + @Override + public void handleIncrement(@NotNull IncrementStatement statement) {handleMono();} + @Override + public void handleSimpleExpression(@NotNull SimpleExpressionStatement statement) {handleMono();} +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/ExpressionVisitor.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/ExpressionVisitor.java new file mode 100644 index 00000000..a15539d1 --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/ExpressionVisitor.java @@ -0,0 +1,38 @@ +package fr.jamailun.ultimatespellsystem.dsl2.visitor; + +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.*; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionCallExpression; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.litteral.*; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.operators.BiOperator; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.operators.MonoOperator; +import org.jetbrains.annotations.NotNull; + +/** + * A visitor. Can interact with the node-tree. + */ +public interface ExpressionVisitor { + + // Literals + void handleNullLiteral(@NotNull NullExpression literal); + void handleBooleanLiteral(@NotNull BooleanExpression literal); + void handleNumberLiteral(@NotNull NumberExpression literal); + void handleStringLiteral(@NotNull StringExpression literal); + void handleMapLiteral(@NotNull MapLiteral literal); + void handleDurationLiteral(@NotNull DurationExpression literal); + void handleLocationLiteral(@NotNull LocationLiteral literal); + + // Operators-ish + void handleBiOperator(@NotNull BiOperator operator); + void handleMonoOperator(@NotNull MonoOperator operator); + void handleParenthesis(@NotNull ParenthesisExpression parenthesis); + void handleArrayGet(@NotNull ArrayGetterExpression arrayGetter); + void handleFieldGet(@NotNull FieldGetExpression fieldGetter); + + // Specifics + void handleArray(@NotNull ArrayExpression expression); + void handleVariable(@NotNull ReferenceExpression expression); + + // Functions + void handleFunction(@NotNull FunctionCallExpression expression); + +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/PrintingVisitor.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/PrintingVisitor.java new file mode 100644 index 00000000..10142ddd --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/PrintingVisitor.java @@ -0,0 +1,341 @@ +package fr.jamailun.ultimatespellsystem.dsl2.visitor; + +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.*; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionCallExpression; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.ExpressionNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.StatementNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.litteral.*; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.operators.BiOperator; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.operators.MonoOperator; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.statements.*; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.statements.blocks.ForLoopStatement; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.statements.blocks.IfElseStatement; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.statements.blocks.WhileLoopStatement; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Duration; +import org.jetbrains.annotations.NotNull; + +import java.text.DecimalFormat; +import java.util.List; + +/** + * Made to print content. + */ +public class PrintingVisitor implements StatementVisitor, ExpressionVisitor { + + private final static DecimalFormat formatNumber = new DecimalFormat("#.##"); + + private final int indentDelta; + private String indentBuffer; + private int currentIndent = 0; + private boolean dirty = true; + + private StringBuilder builder; + + private PrintingVisitor(int indent) { + this.indentDelta = indent; + } + + private @NotNull String visit(@NotNull List statements) { + builder = new StringBuilder(); + for(StatementNode statement : statements) { + statement.visit(this); + eol(); + } + return builder.toString(); + } + + /** + * Print multiple statements to sys-out, with an indentation of {@code 2}. + * @param statements the non-null statements to visit. + */ + public static void print(@NotNull List statements) { + print(statements, 2); + } + + /** + * Print multiple statements to sys-out. + * @param statements list of statements to print. + * @param indent specific indent to use. + */ + public static void print(@NotNull List statements, int indent) { + System.out.println(toString(statements, indent)); + } + + /** + * Print multiple statements to a String. + * @param statements list of statements to print. + * @return the print output. + */ + public static @NotNull String toString(@NotNull List statements) { + return toString(statements, 2); + } + + /** + * Print multiple statements to a String. + * @param statements list of statements to print. + * @param indent specific indent to use. + * @return the print output. + */ + public static @NotNull String toString(@NotNull List statements, int indent) { + return new PrintingVisitor(indent).visit(statements); + } + + private @NotNull String indent() { + if(dirty) { + indentBuffer = " ".repeat(currentIndent); + dirty = false; + } + return indentBuffer; + } + + private void right() { + currentIndent += indentDelta; + dirty = true; + } + + private void left() { + currentIndent -= indentDelta; + if(currentIndent < 0) { + currentIndent = 0; + } + dirty = true; + } + + private void eol() { + builder.append(";\n"); + } + + @Override + public void handleReturn(@NotNull ReturnStatement statement) { + builder.append(indent()).append("stop"); + } + + + + @Override + public void handleDefine(@NotNull DeclareNewVariable statement) { + builder.append(indent()) + .append("define %") + .append(statement.getVarName()) + .append(" = "); + statement.getExpression().visit(this); + } + + + @Override + public void handleBlock(@NotNull BlockStatement statement) { + builder.append("{\n"); + right(); + for(StatementNode child : statement.getChildren()) { + child.visit(this); + eol(); + } + left(); + builder.append(indent()).append("}"); + } + + @Override + public void handleIncrement(@NotNull IncrementStatement statement) { + builder.append(statement.isPositive() ? "++" : "--") + .append("%").append(statement.getVarName()); + } + + + @Override + public void handleSimpleExpression(@NotNull SimpleExpressionStatement statement) { + builder.append("{"); + statement.getChild().visit(this); + builder.append("}"); + } + + @Override + public void handleIf(@NotNull IfElseStatement statement) { + builder.append(indent()).append("IF("); + statement.getCondition().visit(this); + builder.append("):"); + right(); + statement.getChild().visit(this); + left(); + builder.append("\n"); + + statement.getElse().ifPresent(e -> { + builder.append(indent()).append("ELSE : "); + right(); + e.visit(this); + left(); + builder.append("\n"); + }); + } + + @Override + public void handleForLoop(@NotNull ForLoopStatement statement) { + builder.append(indent()) + .append("FOR("); + if(statement.getInitialization() != null) statement.getInitialization().visit(this); + statement.getCondition().visit(this); + builder.append(";"); + if(statement.getIteration() != null) statement.getIteration().visit(this); + builder.append("):"); + statement.getChild().visit(this); + } + + + @Override + public void handleWhileLoop(@NotNull WhileLoopStatement statement) { + if(statement.isWhileFirst()) { + builder.append("WHILE("); + statement.getCondition().visit(this); + builder.append(") "); + } else { + builder.append("DO "); + } + statement.getChild().visit(this); + if(!statement.isWhileFirst()) { + builder.append(" WHILE("); + statement.getCondition().visit(this); + builder.append(") "); + } + } + + @Override + public void handleBreakContinue(@NotNull BreakContinueStatement statement) { + builder.append(statement.isContinue() ? "CONTINUE" : "BREAK"); + } + + @Override + public void handleNullLiteral(@NotNull NullExpression literal) { + builder.append("NULL"); + } + + @Override + public void handleBooleanLiteral(@NotNull BooleanExpression literal) { + builder.append(literal.getRaw()); + } + + @Override + public void handleNumberLiteral(@NotNull NumberExpression literal) { + double num = literal.getRaw(); + builder.append(formatNumber.format(num)); + } + + @Override + public void handleStringLiteral(@NotNull StringExpression literal) { + builder.append("\"").append(literal.getRaw()).append("\""); + } + + @Override + public void handleMapLiteral(@NotNull MapLiteral literal) { + //TODO + } + + @Override + public void handleDurationLiteral(@NotNull DurationExpression literal) { + Duration duration = literal.getRaw(); + builder.append(formatNumber.format(duration.amount())) + .append(" ") + .append(duration.niceUnit()); + } + + @Override + public void handleLocationLiteral(@NotNull LocationLiteral literal) { + builder.append("Location("); + literal.getWorld().visit(this); builder.append(", "); + literal.getVectorX().visit(this); builder.append(", "); + literal.getVectorY().visit(this); builder.append(", "); + literal.getVectorZ().visit(this); + if(literal.asYawAndPitch()) { + builder.append(", "); + literal.getYaw().visit(this); + builder.append(", "); + literal.getPitch().visit(this); + } + builder.append(")"); + } + + @Override + public void handleBiOperator(@NotNull BiOperator operator) { + operator.getLeft().visit(this); + String ope = switch (operator.getType()) { + case ADD -> "+"; + case SUB -> "-"; + case MUL -> "*"; + case DIV -> "/"; + case EQUAL -> "=="; + case NOT_EQUAL -> "!="; + case GREATER_OR_EQ -> ">="; + case GREATER -> ">"; + case LESSER_OR_EQ -> "<="; + case LESSER -> "<"; + case AND -> "and"; + case OR -> "or"; + case LIST_ADD -> "append"; + case LIST_REM -> "remove"; + case LIST_CONTAINS -> "contains"; + case LIST_REM_INDEX -> "remove_idx"; + }; + builder.append(" ").append(ope).append(" "); + operator.getRight().visit(this); + } + + @Override + public void handleMonoOperator(@NotNull MonoOperator operator) { + String ope = operator.getType().name(); + builder.append(ope).append("("); + operator.getChild().visit(this); + builder.append(")"); + } + + @Override + public void handleParenthesis(@NotNull ParenthesisExpression parenthesis) { + builder.append("("); + parenthesis.getExpression().visit(this); + builder.append(")"); + } + + @Override + public void handleArrayGet(@NotNull ArrayGetterExpression arrayGetter) { + arrayGetter.getArray().visit(this); + builder.append("["); + arrayGetter.getIndex().visit(this); + builder.append("]"); + } + + @Override + public void handleFieldGet(@NotNull FieldGetExpression fieldGetter) { + fieldGetter.getLeftExpression().visit(this); + builder.append(".") + .append(fieldGetter.getFieldName()); + } + + @Override + public void handleFunction(@NotNull FunctionCallExpression expression) { + builder.append(":") + .append(expression.getFunction().id()) + .append("("); + boolean first = true; + for(ExpressionNode arg : expression.getArguments()) { + if(first) first = false; else builder.append(", "); + arg.visit(this); + } + builder.append(")"); + } + + @Override + public void handleArray(@NotNull ArrayExpression expression) { + builder.append("["); + boolean first = true; + for(ExpressionNode child : expression.getElements()) { + if(first) first = false; else builder.append(", "); + child.visit(this); + } + builder.append("]"); + } + + @Override + public void handleVariable(@NotNull ReferenceExpression expression) { + builder.append("VAR<") + .append(expression.getVariableName()) + .append(">"); + } + +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/StatementVisitor.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/StatementVisitor.java new file mode 100644 index 00000000..9f09ca34 --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/StatementVisitor.java @@ -0,0 +1,25 @@ +package fr.jamailun.ultimatespellsystem.dsl2.visitor; + +import fr.jamailun.ultimatespellsystem.dsl2.nodes.statements.*; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.statements.blocks.ForLoopStatement; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.statements.blocks.IfElseStatement; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.statements.blocks.WhileLoopStatement; +import org.jetbrains.annotations.NotNull; + +/** + * A visitor. Can interact with the node-tree. + */ +public interface StatementVisitor { + + void handleReturn(@NotNull ReturnStatement statement); + void handleDefine(@NotNull DeclareNewVariable statement); + void handleBlock(@NotNull BlockStatement statement); + void handleIncrement(@NotNull IncrementStatement statement); + void handleSimpleExpression(@NotNull SimpleExpressionStatement statement); + + void handleIf(@NotNull IfElseStatement statement); + void handleForLoop(@NotNull ForLoopStatement statement); + //void handleForeachLoop(@NotNull ForeachLoopStatement statement); + void handleWhileLoop(@NotNull WhileLoopStatement statement); + void handleBreakContinue(@NotNull BreakContinueStatement statement); +} diff --git a/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/CorrectParsingTests.java b/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/CorrectParsingTests.java new file mode 100644 index 00000000..5fe15b3e --- /dev/null +++ b/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/CorrectParsingTests.java @@ -0,0 +1,76 @@ +package fr.jamailun.ultimatespellsystem.dsl2; + +import fr.jamailun.ultimatespellsystem.dsl2.errors.UssException; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionDefinition; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionType; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; +import fr.jamailun.ultimatespellsystem.dsl2.registries.FunctionDefinitionsRegistry; +import org.jetbrains.annotations.NotNull; +import org.junit.jupiter.api.Test; + +import java.io.File; +import java.util.List; + +/** + * Multiple tests for valid USS files. + */ +public class CorrectParsingTests extends ParsingTest { + + @Test + void correctStatements() { + testFolder("corrects/statements"); + } + @Test + void correctBlocks() { + testFolder("corrects/blocks"); + } + @Test + void correctOperators() { + testFolder("corrects/operators"); + } + @Test + void correctMix() { + testFolder("corrects/mix"); + } + @Test + void correctMetadata() { + testFolder("corrects/metadata"); + } + + @Test + void correctWithCustom() { + // Register "custom_add" + FunctionDefinition definition = new FunctionDefinition( + "custom_add", + TypePrimitive.NUMBER.asType(), + List.of( + new FunctionArgument(FunctionType.accept(TypePrimitive.NUMBER), "a", false), + new FunctionArgument(FunctionType.accept(TypePrimitive.NUMBER), "b", false) + ) + ); + FunctionDefinitionsRegistry.register(definition); + + // Callback +// CallbackEventRegistry.register( +// CallbackEvent.of("landed", TokenType.AT, TypePrimitive.LOCATION) +// ); + + // Parse + testFolder("corrects_with_custom"); + } + + private void testFolder(@NotNull String folder) { + for(File file : listTests(folder)) { + try { + parseAndVerify(file); + addOk(); + } catch (UssException e) { + e.printStackTrace(); + addFails(file, toString(e)); + } + } + printResults(); + } + +} diff --git a/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/FailuresParsingTests.java b/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/FailuresParsingTests.java new file mode 100644 index 00000000..cc93edf5 --- /dev/null +++ b/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/FailuresParsingTests.java @@ -0,0 +1,59 @@ +package fr.jamailun.ultimatespellsystem.dsl2; + +import fr.jamailun.ultimatespellsystem.dsl2.errors.*; +import org.jetbrains.annotations.NotNull; +import org.junit.jupiter.api.Test; + +import java.io.File; + +/** + * Multiple tests for invalid USS files. + */ +public class FailuresParsingTests extends ParsingTest { + + @Test + void badParsing() { + badParsing("bad_parsing", ParsingException.class); + } + + @Test + void badSyntax() { + badParsing("bad_syntax", SyntaxException.class); + } + + @Test + void badType() { + badParsing("bad_type", TypeException.class); + } + + @Test + void badTreeValidation() { + badParsing("bad_tree", TreeValidationException.class); + } + + @Test + void badMix() { + badParsing("bad_mix", UssException.class); + } + + private void badParsing(@NotNull String folder, @NotNull Class clazz) { + String title = "[! EXPECTED "+clazz.getSimpleName()+"] "; + for(File file : listTests(folder)) { + try { + parseAndVerify(file); + addFails(file, title + "Got not error."); + } catch(Exception exception) { + if(clazz.isAssignableFrom(exception.getClass())) { + System.out.println("Error: " + exception); + addOk(); + } else { + System.err.println("GOT " + exception.getClass() + ", expected " + clazz); + exception.printStackTrace(); + addFails(file, title + "Got " + toString(exception)); + } + } + } + printResults(); + } + +} diff --git a/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/ParsingTest.java b/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/ParsingTest.java new file mode 100644 index 00000000..4a91b2e0 --- /dev/null +++ b/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/ParsingTest.java @@ -0,0 +1,97 @@ +package fr.jamailun.ultimatespellsystem.dsl2; + +import fr.jamailun.ultimatespellsystem.dsl2.errors.UssException; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.StatementNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.variables.TypesContext; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.CharStream; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenStream; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.Tokenizer; +import fr.jamailun.ultimatespellsystem.dsl2.validators.DslValidator; +import fr.jamailun.ultimatespellsystem.dsl2.visitor.PrintingVisitor; +import org.jetbrains.annotations.NotNull; +import org.junit.jupiter.api.Assertions; + +import java.io.File; +import java.util.*; +import java.util.stream.Stream; + +/** + * Test framework for parsing tests. + */ +abstract class ParsingTest { + + protected final File PARSINGS_FILE = new File("src/test/resources/parsing"); + + protected @NotNull List listTests(@NotNull String subFolder) { + File directory = new File(PARSINGS_FILE, subFolder); + Assertions.assertTrue(directory.exists() && directory.isDirectory(), "Directory '" + subFolder + "' does not exist."); + + File[] children = directory.listFiles(); + if(children == null) { + return Collections.emptyList(); + } + return Stream.of(children) + .filter(File::isFile) + .sorted(Comparator.comparing(File::getName)) + .toList(); + } + + protected @NotNull String toString(@NotNull Exception e) { + return e.getClass().getSimpleName() + " : " + e.getMessage(); + } + + protected int countOk = 0; + protected final Map failures = new HashMap<>(); + + protected void addOk() { + countOk++; + } + protected void addFails(@NotNull File test, @NotNull String error) { + failures.put(test, error); + } + + protected void parseAndVerify(@NotNull File file) throws UssException { + System.out.println("\n\n ================[ " + file.getName() + "]================\n"); + // Tokenize + TokenStream tokens = Tokenizer.tokenize(CharStream.from(file)); + System.out.println(tokens + "\n"); + + // Parse + List nodes = UltimateSpellSystemDSL.parse(tokens); + + System.out.println(" ----------------------- "); + + // validate + TypesContext context = new TypesContext(); + for (StatementNode node : nodes) { + node.validateTypes(context); + System.out.println("> " + node); + } + DslValidator.validateTree(nodes); + + // The visitor works as expected. + PrintingVisitor.print(nodes); + } + + public static final String RESET = "\033[0m"; // Text Reset + public static final String RED_BOLD = "\033[1;31m"; // RED + public static final String RED = "\033[0;31m"; // RED + public static final String GREEN_BOLD = "\033[1;32m"; // GREEN + public static final String WHITE_BOLD = "\033[1;37m"; // WHITE + + protected void printResults() { + String color = failures.isEmpty() ? GREEN_BOLD : RED_BOLD; + System.out.println("\n" + WHITE_BOLD + "==================== [" + color + " RESULTS " + WHITE_BOLD + "] ====================" + RESET + "\n"); + System.out.println(color + "Success : " + countOk + RESET); + System.out.println(color + "Failures : " + failures.size() + RESET); + if(!failures.isEmpty()) { + System.out.println(); + failures.forEach((k, v) -> System.out.println(RED_BOLD + " - " + k.getName() + " > " + RED + v)); + } + System.out.println("\n" + WHITE_BOLD + "=====================================================" + RESET + "\n"); + + if(!failures.isEmpty()) + System.exit(42); + } + +} diff --git a/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/DurationTests.java b/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/DurationTests.java new file mode 100644 index 00000000..b13a2a0b --- /dev/null +++ b/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/DurationTests.java @@ -0,0 +1,38 @@ +package fr.jamailun.ultimatespellsystem.dsl2.nodes.type; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.util.concurrent.TimeUnit; + +/** + * Tests for {@link Duration} class. + */ +class DurationTests { + + @Test + void testDurOpeDur() { + Duration a = new Duration(12, TimeUnit.HOURS); + Duration b = new Duration(60, TimeUnit.MINUTES); + Assertions.assertEquals(12, a.div(b)); + + Duration c = new Duration(1, TimeUnit.HOURS); + Duration d = new Duration(1, TimeUnit.SECONDS); + Assertions.assertEquals(new Duration(3601, TimeUnit.SECONDS), c.add(d)); + + Assertions.assertEquals(new Duration(2, TimeUnit.HOURS), c.add(c)); + } + + @Test + void testDurDivLambda() { + Duration a = new Duration(12, TimeUnit.HOURS); + Assertions.assertEquals(new Duration(120, TimeUnit.MINUTES), a.div(6)); + } + + @Test + void testDurMul() { + Duration a = new Duration(12, TimeUnit.MINUTES); + Assertions.assertEquals(new Duration(1, TimeUnit.HOURS), a.mul(5)); + } + +} diff --git a/dsl2/src/test/resources/demo.cpp b/dsl2/src/test/resources/demo.cpp new file mode 100644 index 00000000..5cfcca1d --- /dev/null +++ b/dsl2/src/test/resources/demo.cpp @@ -0,0 +1,11 @@ +function void foo(a, b) { + x = 42; + for(y = 0; y < 10; y++) { + x += y; + } + dur = 20s; + if(dur * 2 > 1min) { + x = x - 5; + } + caster.send_message("salut"); +} \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing/bad_mix/invalid_param_meta.uss b/dsl2/src/test/resources/parsing/bad_mix/invalid_param_meta.uss new file mode 100644 index 00000000..db31ab9e --- /dev/null +++ b/dsl2/src/test/resources/parsing/bad_mix/invalid_param_meta.uss @@ -0,0 +1,3 @@ +@param(12, ""); + +define %a = 2; diff --git a/dsl2/src/test/resources/parsing/bad_mix/unknown_function.uss b/dsl2/src/test/resources/parsing/bad_mix/unknown_function.uss new file mode 100644 index 00000000..055a585e --- /dev/null +++ b/dsl2/src/test/resources/parsing/bad_mix/unknown_function.uss @@ -0,0 +1 @@ +define %a = i_dont_exist("toto"); \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing/bad_parsing/bad_number.uss b/dsl2/src/test/resources/parsing/bad_parsing/bad_number.uss new file mode 100644 index 00000000..d1da7e46 --- /dev/null +++ b/dsl2/src/test/resources/parsing/bad_parsing/bad_number.uss @@ -0,0 +1 @@ +define %a = 5..1; \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing/bad_parsing/bad_string.uss b/dsl2/src/test/resources/parsing/bad_parsing/bad_string.uss new file mode 100644 index 00000000..b807acac --- /dev/null +++ b/dsl2/src/test/resources/parsing/bad_parsing/bad_string.uss @@ -0,0 +1,2 @@ +define %a = "a +b"; \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing/bad_syntax/bad_else.uss b/dsl2/src/test/resources/parsing/bad_syntax/bad_else.uss new file mode 100644 index 00000000..1efc7306 --- /dev/null +++ b/dsl2/src/test/resources/parsing/bad_syntax/bad_else.uss @@ -0,0 +1,3 @@ +if(1 == 1) stop; +else stop; +else stop; diff --git a/dsl2/src/test/resources/parsing/bad_syntax/bad_entity_type.uss b/dsl2/src/test/resources/parsing/bad_syntax/bad_entity_type.uss new file mode 100644 index 00000000..6af8ceec --- /dev/null +++ b/dsl2/src/test/resources/parsing/bad_syntax/bad_entity_type.uss @@ -0,0 +1,3 @@ +# Unknown subtype of send'. + +summon I_DONT_EXIST for 4s; diff --git a/dsl2/src/test/resources/parsing/bad_syntax/bad_send.uss b/dsl2/src/test/resources/parsing/bad_syntax/bad_send.uss new file mode 100644 index 00000000..e8e1f09f --- /dev/null +++ b/dsl2/src/test/resources/parsing/bad_syntax/bad_send.uss @@ -0,0 +1,3 @@ +# Unknown subtype of send'. + +send to %caster I_DONT_EXIST "I'm a failure"; diff --git a/dsl2/src/test/resources/parsing/bad_syntax/bad_var.uss b/dsl2/src/test/resources/parsing/bad_syntax/bad_var.uss new file mode 100644 index 00000000..7fa3c971 --- /dev/null +++ b/dsl2/src/test/resources/parsing/bad_syntax/bad_var.uss @@ -0,0 +1,2 @@ +define %correct = 12; +%correct; \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing/bad_syntax/redefine_caster.uss b/dsl2/src/test/resources/parsing/bad_syntax/redefine_caster.uss new file mode 100644 index 00000000..4ccdb855 --- /dev/null +++ b/dsl2/src/test/resources/parsing/bad_syntax/redefine_caster.uss @@ -0,0 +1 @@ +define %caster = 2; diff --git a/dsl2/src/test/resources/parsing/bad_tree/after_break.uss b/dsl2/src/test/resources/parsing/bad_tree/after_break.uss new file mode 100644 index 00000000..865eb84b --- /dev/null +++ b/dsl2/src/test/resources/parsing/bad_tree/after_break.uss @@ -0,0 +1,6 @@ +for(%i = 1; %i < 3; increment %i) { + if(%i == 2) { + break; + send to %caster message "oops"; + } +} \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing/bad_tree/after_meta_1.uss b/dsl2/src/test/resources/parsing/bad_tree/after_meta_1.uss new file mode 100644 index 00000000..f4b62256 --- /dev/null +++ b/dsl2/src/test/resources/parsing/bad_tree/after_meta_1.uss @@ -0,0 +1,5 @@ +@meta_flag +if(1==1){ + @meta_flag + send to %caster message "foo"; +} diff --git a/dsl2/src/test/resources/parsing/bad_tree/after_meta_2.uss b/dsl2/src/test/resources/parsing/bad_tree/after_meta_2.uss new file mode 100644 index 00000000..b62c339f --- /dev/null +++ b/dsl2/src/test/resources/parsing/bad_tree/after_meta_2.uss @@ -0,0 +1,5 @@ +@meta_flag +{ + send to %caster message "foo"; +} +@meta_flag diff --git a/dsl2/src/test/resources/parsing/bad_tree/after_stop_1.uss b/dsl2/src/test/resources/parsing/bad_tree/after_stop_1.uss new file mode 100644 index 00000000..139cee45 --- /dev/null +++ b/dsl2/src/test/resources/parsing/bad_tree/after_stop_1.uss @@ -0,0 +1,2 @@ +stop; +stop; \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing/bad_tree/after_stop_2.uss b/dsl2/src/test/resources/parsing/bad_tree/after_stop_2.uss new file mode 100644 index 00000000..0b7a38ba --- /dev/null +++ b/dsl2/src/test/resources/parsing/bad_tree/after_stop_2.uss @@ -0,0 +1,3 @@ +send to %caster message "a"; +stop; +send to %caster message "b"; \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing/bad_tree/after_stop_3.uss b/dsl2/src/test/resources/parsing/bad_tree/after_stop_3.uss new file mode 100644 index 00000000..9248fcef --- /dev/null +++ b/dsl2/src/test/resources/parsing/bad_tree/after_stop_3.uss @@ -0,0 +1,5 @@ +@meta_flag +stop; +{ + send to %caster message "foo"; +} \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing/bad_type/bad_collection_teleport.uss b/dsl2/src/test/resources/parsing/bad_type/bad_collection_teleport.uss new file mode 100644 index 00000000..1bcf6687 --- /dev/null +++ b/dsl2/src/test/resources/parsing/bad_type/bad_collection_teleport.uss @@ -0,0 +1,4 @@ + +define %coll = all entities within 10 around %caster; + +teleport %caster to %coll; diff --git a/dsl2/src/test/resources/parsing/bad_type/bad_list_append.uss b/dsl2/src/test/resources/parsing/bad_type/bad_list_append.uss new file mode 100644 index 00000000..60f785a2 --- /dev/null +++ b/dsl2/src/test/resources/parsing/bad_type/bad_list_append.uss @@ -0,0 +1,3 @@ +%l = [[]]; +%l :+ "a"; +%l :+ true; diff --git a/dsl2/src/test/resources/parsing/bad_type/bad_ope.uss b/dsl2/src/test/resources/parsing/bad_type/bad_ope.uss new file mode 100644 index 00000000..b7e3807c --- /dev/null +++ b/dsl2/src/test/resources/parsing/bad_type/bad_ope.uss @@ -0,0 +1,5 @@ +# Valid +define %x = 1 * 2; + +# Not valid +define %z = [[1]] * 2; \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing/bad_type/bad_ope_2.uss b/dsl2/src/test/resources/parsing/bad_type/bad_ope_2.uss new file mode 100644 index 00000000..2f815f23 --- /dev/null +++ b/dsl2/src/test/resources/parsing/bad_type/bad_ope_2.uss @@ -0,0 +1,6 @@ +# Valid +define %x = 1 + "1" +define %y = "1" + 1; + +# Not valid +define %z = 1 * "oops"; diff --git a/dsl2/src/test/resources/parsing/bad_type/bad_ope_3.uss b/dsl2/src/test/resources/parsing/bad_type/bad_ope_3.uss new file mode 100644 index 00000000..d6d21b41 --- /dev/null +++ b/dsl2/src/test/resources/parsing/bad_type/bad_ope_3.uss @@ -0,0 +1,7 @@ +# Valid +%a = true; +%b = !%a; + +# Invalid +%c = 14; +%d = !%c; diff --git a/dsl2/src/test/resources/parsing/bad_type/increment_type.uss b/dsl2/src/test/resources/parsing/bad_type/increment_type.uss new file mode 100644 index 00000000..f2f8f169 --- /dev/null +++ b/dsl2/src/test/resources/parsing/bad_type/increment_type.uss @@ -0,0 +1,2 @@ +define %i = "a"; +decrement %i; diff --git a/dsl2/src/test/resources/parsing/bad_type/redefine_difftype.uss b/dsl2/src/test/resources/parsing/bad_type/redefine_difftype.uss new file mode 100644 index 00000000..d13c23cf --- /dev/null +++ b/dsl2/src/test/resources/parsing/bad_type/redefine_difftype.uss @@ -0,0 +1,2 @@ +define %a = 1; +define %a = "toto"; \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing/bad_type/stop_type.uss b/dsl2/src/test/resources/parsing/bad_type/stop_type.uss new file mode 100644 index 00000000..f0623a9a --- /dev/null +++ b/dsl2/src/test/resources/parsing/bad_type/stop_type.uss @@ -0,0 +1 @@ +stop "non"; \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing/corrects/blocks/for.uss b/dsl2/src/test/resources/parsing/corrects/blocks/for.uss new file mode 100644 index 00000000..abc070ed --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/blocks/for.uss @@ -0,0 +1,14 @@ +for(define %i = 0; %i < 5; increment %i) { + send to %caster message "i=%i"; +} + +%x = 12; +for(; %x < 5; decrement %x) { + send to %caster message "x=%x"; +} + +%z = 8; +for(; %x > 5; ) { + decrement %z; + send to %caster message "z=%z"; +} \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing/corrects/blocks/for_break.uss b/dsl2/src/test/resources/parsing/corrects/blocks/for_break.uss new file mode 100644 index 00000000..0c24ebbd --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/blocks/for_break.uss @@ -0,0 +1,5 @@ +for(define %i = 0; %i < 5; increment %i) { + send to %caster message "[%i]"; + if(%i > 3) + break; +} \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing/corrects/blocks/foreach.uss b/dsl2/src/test/resources/parsing/corrects/blocks/foreach.uss new file mode 100644 index 00000000..d0356410 --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/blocks/foreach.uss @@ -0,0 +1,6 @@ +define %around = (all PLAYER within 50 around %caster); + +foreach(%p : %around) { + send to %caster message "Found " + %p; +} +send to %caster message "All = %around"; \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing/corrects/blocks/ifelse_p1.uss b/dsl2/src/test/resources/parsing/corrects/blocks/ifelse_p1.uss new file mode 100644 index 00000000..f6e36220 --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/blocks/ifelse_p1.uss @@ -0,0 +1,7 @@ +define %a = null; +if(%caster == %caster) + define %a = "a"; +else + define %a = "b"; + +send to %caster message %a; \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing/corrects/blocks/ifelse_p2.uss b/dsl2/src/test/resources/parsing/corrects/blocks/ifelse_p2.uss new file mode 100644 index 00000000..e2c674a3 --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/blocks/ifelse_p2.uss @@ -0,0 +1,20 @@ +define %a = 2; +define %even = null; + +if(%a == 0) { + define %even = true; +} else if(%a == 1) { + define %even = false; +} else if(%a == 2) { + define %even = true; +} else if(%a == 3) { + define %even = false; +} else if(%a == 4) { + define %even = true; +} else if(%a == 5) { + define %even = false; +} else { + send to %caster message "trop duuur !"; + stop; +} +send to %caster message "even ? %even"; diff --git a/dsl2/src/test/resources/parsing/corrects/blocks/repeat.uss b/dsl2/src/test/resources/parsing/corrects/blocks/repeat.uss new file mode 100644 index 00000000..d69744ce --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/blocks/repeat.uss @@ -0,0 +1,13 @@ +repeat after 1s 5 times every 2 seconds: { + send to %caster message "boum 1."; +} + +repeat 2 times every 5 seconds: { + send to %caster message "boum 2."; +} + +define %count = 1 + 1; +define %delay = 3sec; +repeat %count times every %delay: { + send to %caster message "boum 3."; +} diff --git a/dsl2/src/test/resources/parsing/corrects/blocks/repeat_2.uss b/dsl2/src/test/resources/parsing/corrects/blocks/repeat_2.uss new file mode 100644 index 00000000..39727800 --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/blocks/repeat_2.uss @@ -0,0 +1,9 @@ +repeat after 1s every 2 seconds for 2 m: { + send to %caster message "boum 1."; +} + +%dur = 1 minute; +%freq = 15s; +repeat every %freq for %dur: { + send %caster message "test"; +} diff --git a/dsl2/src/test/resources/parsing/corrects/blocks/run_later.uss b/dsl2/src/test/resources/parsing/corrects/blocks/run_later.uss new file mode 100644 index 00000000..37ec5afc --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/blocks/run_later.uss @@ -0,0 +1,9 @@ +send to %caster message "Timer: &a1 minute."; +run after 1 minute: { + send to %caster message "Timer is over."; +} + +define %delay = 3sec; +run after %delay: { + send to %caster message "post 3 secs."; +} diff --git a/dsl2/src/test/resources/parsing/corrects/blocks/while.uss b/dsl2/src/test/resources/parsing/corrects/blocks/while.uss new file mode 100644 index 00000000..6bebbaee --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/blocks/while.uss @@ -0,0 +1,15 @@ +define %i = 0; + +while(%i < 10) { + send to %caster message "&a+&f > i=%i"; + increment %i; + if(%i > 100) + continue; +} + +do { + send to %caster message "&c-&f > i=%i"; + decrement %i; +} while(%i > 0); + +send to %caster message "done"; diff --git a/dsl2/src/test/resources/parsing/corrects/metadata/param_metadata.uss b/dsl2/src/test/resources/parsing/corrects/metadata/param_metadata.uss new file mode 100644 index 00000000..e637dc2b --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/metadata/param_metadata.uss @@ -0,0 +1,3 @@ +@param(test, int) + +define %foo = 3 + %test; diff --git a/dsl2/src/test/resources/parsing/corrects/mix/cercle.uss b/dsl2/src/test/resources/parsing/corrects/mix/cercle.uss new file mode 100644 index 00000000..dd98fbe4 --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/mix/cercle.uss @@ -0,0 +1,12 @@ +define %pos = position of %caster; + +define %pos = %pos + [[0,-1,0]]; +for(define %x = -5; %x <= 5; increment %x) { + for(define %z = -5; %z <= 5; increment %z) { + define %temp = %pos + [[%x, 0, %z]]; + play block at %pos with: {{ + type: MAGMA_BLOCK, + duration: 3 secs + }} + } +} \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing/corrects/mix/collections.uss b/dsl2/src/test/resources/parsing/corrects/mix/collections.uss new file mode 100644 index 00000000..e1e4bb58 --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/mix/collections.uss @@ -0,0 +1,8 @@ +define %msgs = [["a", "b", "c"]]; +send to %caster message %msgs; + +send to %caster message "1st is '" + %msgs[0] + "'"; + +for(define %i = 0; %i < sizeof(%msgs); increment %i) { + send to %caster message "&e MSG[%i] = '%a" + %msgs[%i] + "&e'"; +} diff --git a/dsl2/src/test/resources/parsing/corrects/mix/empty.uss b/dsl2/src/test/resources/parsing/corrects/mix/empty.uss new file mode 100644 index 00000000..e69de29b diff --git a/dsl2/src/test/resources/parsing/corrects/mix/implicit_define.uss b/dsl2/src/test/resources/parsing/corrects/mix/implicit_define.uss new file mode 100644 index 00000000..965dd96e --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/mix/implicit_define.uss @@ -0,0 +1,2 @@ +define %a = 1; +%a = 2; \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing/corrects/mix/metadata.uss b/dsl2/src/test/resources/parsing/corrects/mix/metadata.uss new file mode 100644 index 00000000..20c60e4d --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/mix/metadata.uss @@ -0,0 +1,5 @@ +@name("a nice spell") +@color("&b") +@param("a", int) + +send to %caster message ""; diff --git a/dsl2/src/test/resources/parsing/corrects/mix/null_recovery.uss b/dsl2/src/test/resources/parsing/corrects/mix/null_recovery.uss new file mode 100644 index 00000000..7c825e60 --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/mix/null_recovery.uss @@ -0,0 +1,6 @@ +%a = 1; +%a = null; +%a = 1 + +send to %caster message "a = " + %a; + diff --git a/dsl2/src/test/resources/parsing/corrects/mix/null_set.uss b/dsl2/src/test/resources/parsing/corrects/mix/null_set.uss new file mode 100644 index 00000000..f6e78789 --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/mix/null_set.uss @@ -0,0 +1,7 @@ +define %a = 1; +define %b = null; + +if(%b == null) + define %b = 2; + +define %c = %a + %b; diff --git a/dsl2/src/test/resources/parsing/corrects/mix/particle_shape.uss b/dsl2/src/test/resources/parsing/corrects/mix/particle_shape.uss new file mode 100644 index 00000000..e27159a3 --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/mix/particle_shape.uss @@ -0,0 +1,8 @@ +define %pos = position of %caster; +play particle at %pos with: {{ + type: FIRE, + shape: {{ + type: "circle", + radius: 6.5 + }} +}} \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing/corrects/mix/test_allof.uss b/dsl2/src/test/resources/parsing/corrects/mix/test_allof.uss new file mode 100644 index 00000000..cc68297c --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/mix/test_allof.uss @@ -0,0 +1,6 @@ +define %coll = all entities within 10 around %caster; + +send to %coll message "paf"; + +teleport %coll to %caster; + diff --git a/dsl2/src/test/resources/parsing/corrects/mix/test_basic.uss b/dsl2/src/test/resources/parsing/corrects/mix/test_basic.uss new file mode 100644 index 00000000..3aacf6fa --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/mix/test_basic.uss @@ -0,0 +1,4 @@ +send to %caster message "&eT'es trop fort."; +send to %caster effect SPEED 2 for 4s; # valid + +define %truc = -12; diff --git a/dsl2/src/test/resources/parsing/corrects/mix/test_complex_tp.uss b/dsl2/src/test/resources/parsing/corrects/mix/test_complex_tp.uss new file mode 100644 index 00000000..33add40c --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/mix/test_complex_tp.uss @@ -0,0 +1,27 @@ +# -- config test # -- config +define %delay = 2 seconds; +define %output = @("world", -50, 100, 50); + +# If monsters around, cancel +if(sizeof(all monsters within 5 around %caster) != 0) { + send to %caster message "&cDes monstres sont trop proches de toi."; + stop; +} + +# Intro +send to %caster message "&bTéléportation vers le &2Stronghold&b..."; +play sound at %caster with: {{ + type: BLOCK_BEACON_ACTIVATE, + pitch: 0.8 +}}; +send to %caster effect slowness 10 for %delay; +send to %caster effect resistance 10 for %delay; + +# Teleport after 5 seconds (sound effect + resistance for falling-damage) +run after %delay: { + teleport %caster to %output; + send to %caster effect resistance 5 for 2s; + play sound at %caster with: {{ + type: ITEM_CHORUS_FRUIT_TELEPORT + }}; +} \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing/corrects/mix/test_location_literal.uss b/dsl2/src/test/resources/parsing/corrects/mix/test_location_literal.uss new file mode 100644 index 00000000..5275ac29 --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/mix/test_location_literal.uss @@ -0,0 +1,2 @@ +define %a = @("world", 1, 2, 3); +define %b = @("world", 1, -2, 3.5, 5, 5); diff --git a/dsl2/src/test/resources/parsing/corrects/mix/test_null.uss b/dsl2/src/test/resources/parsing/corrects/mix/test_null.uss new file mode 100644 index 00000000..7a7a8b28 --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/mix/test_null.uss @@ -0,0 +1,5 @@ +define %i = null; + +if(%i == null) { + send to %caster message "a"; +} \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing/corrects/mix/test_teleport.uss b/dsl2/src/test/resources/parsing/corrects/mix/test_teleport.uss new file mode 100644 index 00000000..6f912ddd --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/mix/test_teleport.uss @@ -0,0 +1,6 @@ +summon EntityType.PIG as %pig for 4s; + +run after 3900ms: { + send to %caster message "&e&owhoooooooosh"; + teleport %caster to %pig; +} \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing/corrects/operators/bool_operators.uss b/dsl2/src/test/resources/parsing/corrects/operators/bool_operators.uss new file mode 100644 index 00000000..74f8342f --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/operators/bool_operators.uss @@ -0,0 +1,2 @@ +%a = 7; +%b = (false || 1 == 1 && (4 >= 2) && !(%a > 10)); \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing/corrects/operators/conditions.uss b/dsl2/src/test/resources/parsing/corrects/operators/conditions.uss new file mode 100644 index 00000000..3735c21a --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/operators/conditions.uss @@ -0,0 +1,13 @@ +define %a = 55; +define %b = 56; + +# Nice separation with parenthesis +if((%a == 1) || (%a == 2)) + send to %caster message "A"; + +# No separation +if(%a == 3 || %b == 4) + send to %caster message "A"; + +#if(%a == 33 || true) +# send to %caster message "B"; diff --git a/dsl2/src/test/resources/parsing/corrects/operators/list_append.uss b/dsl2/src/test/resources/parsing/corrects/operators/list_append.uss new file mode 100644 index 00000000..f47893a1 --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/operators/list_append.uss @@ -0,0 +1,16 @@ +# Type not set (i.e. NULL) +%l = [[]]; + +# Append a value to the list. +%l :+ 1; +%l :+ 2; + +# because its an expression... +(%l :+ 12) :+ 27; + +# ":?" == contains +%bool = %l :? 1; # true +%num = sizeof(%l); # 4 + +# ":-" == remove (value) +%l :- 1; diff --git a/dsl2/src/test/resources/parsing/corrects/operators/math.uss b/dsl2/src/test/resources/parsing/corrects/operators/math.uss new file mode 100644 index 00000000..de5882e8 --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/operators/math.uss @@ -0,0 +1,3 @@ +define %c = cos(3.14); +define %s = cos(3.14); +define %t = tan(3.14); diff --git a/dsl2/src/test/resources/parsing/corrects/operators/operator_priority.uss b/dsl2/src/test/resources/parsing/corrects/operators/operator_priority.uss new file mode 100644 index 00000000..ec147fc4 --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/operators/operator_priority.uss @@ -0,0 +1,11 @@ +define %a = 2; +define %b = 3; +define %c = 5; + +define %zz1 = %a + %b + %c; # (a+(b+c)) + +define %zz2 = %a + %b * %c; # (a+(b*c)) + +define %zz3 = %a / %b - %c; # ((a/b)-c) + +define %zz4 = %a / %b - %c; # ((a/b)-c) diff --git a/dsl2/src/test/resources/parsing/corrects/operators/parenthesis.uss b/dsl2/src/test/resources/parsing/corrects/operators/parenthesis.uss new file mode 100644 index 00000000..926375be --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/operators/parenthesis.uss @@ -0,0 +1,6 @@ +define %a = 1; +define %b = 2; +define %c = 3; +define %d = 5; + +define %pp1 = %a - (%b + %c) * %d; # (a+(b+c)) diff --git a/dsl2/src/test/resources/parsing/corrects/operators/type_operators.uss b/dsl2/src/test/resources/parsing/corrects/operators/type_operators.uss new file mode 100644 index 00000000..52e7645f --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/operators/type_operators.uss @@ -0,0 +1,5 @@ +%a = "1" + 1; +%a = 1 + "1"; + +%dur = 2 minutes * 2; +%n = 2 minutes / 2 minutes; diff --git a/dsl2/src/test/resources/parsing/corrects/statements/define.uss b/dsl2/src/test/resources/parsing/corrects/statements/define.uss new file mode 100644 index 00000000..177aef2e --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/statements/define.uss @@ -0,0 +1,12 @@ +# Some declarations +define %as_str = "a"; +define %b = 1; +define %a = 1 + 21 / 3; +define %cc = %a - (%a + %b); + +# Broken-lines : code still valid +define + %z + = 6 + / 2 + ; diff --git a/dsl2/src/test/resources/parsing/corrects/statements/give.uss b/dsl2/src/test/resources/parsing/corrects/statements/give.uss new file mode 100644 index 00000000..add81e9a --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/statements/give.uss @@ -0,0 +1,10 @@ +give EMERALD to %caster; +give 2 EMERALD to %caster; + +give 3 STONE_AXE to %caster with: {{ + name: "nice &6axe", + lore: [[ + "line 1", + "line 2 !" + ]] +}}; diff --git a/dsl2/src/test/resources/parsing/corrects/statements/increment.uss b/dsl2/src/test/resources/parsing/corrects/statements/increment.uss new file mode 100644 index 00000000..56090ecd --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/statements/increment.uss @@ -0,0 +1,3 @@ +define %i = 0; +increment %i; +decrement %i; diff --git a/dsl2/src/test/resources/parsing/corrects/statements/play.uss b/dsl2/src/test/resources/parsing/corrects/statements/play.uss new file mode 100644 index 00000000..63ffedb3 --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/statements/play.uss @@ -0,0 +1,17 @@ +# Play at '%caster' location + +play PARTICLE at %caster with: {{ + type: lava, + count: 12 +}}; + +play "sound" at %caster with: {{ + type: ENTITY_POLAR_BEAR_WARNING, + volume: 1.1, + pitch: 0.8 +}}; + +play BLOCK at %caster with: {{ + type: MAGMA_BLOCK, + duration: 2 seconds +}}; diff --git a/dsl2/src/test/resources/parsing/corrects/statements/send.uss b/dsl2/src/test/resources/parsing/corrects/statements/send.uss new file mode 100644 index 00000000..5a10c889 --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/statements/send.uss @@ -0,0 +1,22 @@ +# --- Message + +send to %caster message "Simple message"; + +define %msg = "&cRed message !"; +send to %caster message %msg; + +send to %caster message [["message 1", "message 2", "message 3"]]; + +# --- Effect + +send to %caster effect LEVITATION 2 for 3 seconds; +send to %caster effect POISON for 4 seconds; + +define %dur = 1 minute; +define %pow = 2 + 2; +send to %caster effect "strength" %pow for %dur; + +# --- Attributes + +send to %caster attribute 2 ARMOR for 5 s; +send to %caster attribute %pow "MAX_HEALTH" ADD_NUMBER for %dur; diff --git a/dsl2/src/test/resources/parsing/corrects/statements/send_nbt.uss b/dsl2/src/test/resources/parsing/corrects/statements/send_nbt.uss new file mode 100644 index 00000000..2eed25bc --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/statements/send_nbt.uss @@ -0,0 +1 @@ +send %caster nbt "test" = 12 for 12s; \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing/corrects/statements/stop_1.uss b/dsl2/src/test/resources/parsing/corrects/statements/stop_1.uss new file mode 100644 index 00000000..28faeb67 --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/statements/stop_1.uss @@ -0,0 +1,2 @@ +# Exit with code +stop 3.14; diff --git a/dsl2/src/test/resources/parsing/corrects/statements/stop_2.uss b/dsl2/src/test/resources/parsing/corrects/statements/stop_2.uss new file mode 100644 index 00000000..32eff907 --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/statements/stop_2.uss @@ -0,0 +1,2 @@ +# Exit normally +stop; diff --git a/dsl2/src/test/resources/parsing/corrects/statements/stop_3.uss b/dsl2/src/test/resources/parsing/corrects/statements/stop_3.uss new file mode 100644 index 00000000..99d552aa --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/statements/stop_3.uss @@ -0,0 +1,3 @@ +# Exit with code +define %code = 90/8; +stop %code; diff --git a/dsl2/src/test/resources/parsing/corrects/statements/summon.uss b/dsl2/src/test/resources/parsing/corrects/statements/summon.uss new file mode 100644 index 00000000..b8a219d2 --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/statements/summon.uss @@ -0,0 +1,9 @@ +summon IRON_GOLEM at %caster as %ent for 5 minutes with: {{ + name: "Michel" +}}; + +summon DOLPHIN at %caster for 3 seconds with: {{}}; + +define %type = ZOMBIE; +define %dur = 3 days; +summon %type at %caster for %dur; diff --git a/dsl2/src/test/resources/parsing/corrects/statements/teleport.uss b/dsl2/src/test/resources/parsing/corrects/statements/teleport.uss new file mode 100644 index 00000000..bac5a143 --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/statements/teleport.uss @@ -0,0 +1,4 @@ +teleport %caster to %caster; + +teleport all monsters within 50 around %caster to %caster + [[0,10,0]]; +# same as teleport (all monsters within 50) around %caster to (%caster + [[0,10,0]]); diff --git a/dsl2/src/test/resources/parsing/corrects_with_custom/callback.uss b/dsl2/src/test/resources/parsing/corrects_with_custom/callback.uss new file mode 100644 index 00000000..65c9f487 --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects_with_custom/callback.uss @@ -0,0 +1,6 @@ +summon arrow at %caster as %ar for 5s; + +callback %ar LANDED at %pos: { + send %caster message "landed at %pos."; + teleport %caster to %pos; +} diff --git a/dsl2/src/test/resources/parsing/corrects_with_custom/custom.uss b/dsl2/src/test/resources/parsing/corrects_with_custom/custom.uss new file mode 100644 index 00000000..603239cf --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects_with_custom/custom.uss @@ -0,0 +1,4 @@ +define %a = 1; +define %b = 2; + +define %res = custom_add(%a, %b); diff --git a/pom.xml b/pom.xml index 1d4aff4a..7c2669af 100644 --- a/pom.xml +++ b/pom.xml @@ -14,6 +14,7 @@ dsl + dsl2 api plugin From 1ee1a037fb2217c0f588a3eb5d392648f5c18910 Mon Sep 17 00:00:00 2001 From: "timothe.rosaz" Date: Wed, 22 Oct 2025 08:29:53 +0200 Subject: [PATCH 02/38] Tokenizer test --- .../dsl2/tokenization/Token.java | 17 +++ .../dsl2/tokenization/TokenType.java | 1 + .../dsl2/CorrectParsingTests.java | 5 +- .../dsl2/tokenization/TokenizerTest.java | 139 ++++++++++++++++++ 4 files changed, 159 insertions(+), 3 deletions(-) create mode 100644 dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/tokenization/TokenizerTest.java diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/tokenization/Token.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/tokenization/Token.java index 2f78378a..d09743e6 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/tokenization/Token.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/tokenization/Token.java @@ -4,6 +4,7 @@ import lombok.Getter; import org.jetbrains.annotations.NotNull; +import java.util.Objects; import java.util.concurrent.TimeUnit; /** @@ -146,4 +147,20 @@ public String toString() { default -> type.name(); }; } + + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) return false; + Token token = (Token) o; + return type == token.type + && Objects.equals(contentNumber, token.contentNumber) + && Objects.equals(contentString, token.contentString) + && contentTimeUnit == token.contentTimeUnit + && Objects.equals(contentBoolean, token.contentBoolean); + } + + @Override + public int hashCode() { + return Objects.hash(type, contentNumber, contentString, contentTimeUnit, contentBoolean); + } } diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/tokenization/TokenType.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/tokenization/TokenType.java index 4aa9ed13..9ff926ec 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/tokenization/TokenType.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/tokenization/TokenType.java @@ -54,6 +54,7 @@ public enum TokenType { BREAK(true), CONTINUE(true), RETURN(true), + VAR(true), // == RAW VALUES NULL(true), diff --git a/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/CorrectParsingTests.java b/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/CorrectParsingTests.java index 5fe15b3e..4186a40c 100644 --- a/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/CorrectParsingTests.java +++ b/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/CorrectParsingTests.java @@ -3,7 +3,6 @@ import fr.jamailun.ultimatespellsystem.dsl2.errors.UssException; import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionDefinition; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionType; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; import fr.jamailun.ultimatespellsystem.dsl2.registries.FunctionDefinitionsRegistry; import org.jetbrains.annotations.NotNull; @@ -45,8 +44,8 @@ void correctWithCustom() { "custom_add", TypePrimitive.NUMBER.asType(), List.of( - new FunctionArgument(FunctionType.accept(TypePrimitive.NUMBER), "a", false), - new FunctionArgument(FunctionType.accept(TypePrimitive.NUMBER), "b", false) +// new FunctionArgument(FunctionType.accept(TypePrimitive.NUMBER), "a", false), +// new FunctionArgument(FunctionType.accept(TypePrimitive.NUMBER), "b", false) ) ); FunctionDefinitionsRegistry.register(definition); diff --git a/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/tokenization/TokenizerTest.java b/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/tokenization/TokenizerTest.java new file mode 100644 index 00000000..f479a08e --- /dev/null +++ b/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/tokenization/TokenizerTest.java @@ -0,0 +1,139 @@ +package fr.jamailun.ultimatespellsystem.dsl2.tokenization; + +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Duration; +import org.jetbrains.annotations.NotNull; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; + +class TokenizerTest { + + @Test + void basic() { + String input = "var toto = 123"; + assertTokenize( + input, + List.of( + symbol(TokenType.VAR), + identifier("toto"), + symbol(TokenType.EQUAL), + number(123) + ) + ); + } + + @Test + void comparison() { + String input = """ + if(test() == true || false) { + dur = 3s * dt; + e = "\\\\"; + } + """; + assertTokenize( + input, + List.of( + symbol(TokenType.IF), + symbol(TokenType.BRACKET_OPEN), + identifier("test"), + symbol(TokenType.BRACKET_OPEN), + symbol(TokenType.BRACKET_CLOSE), + symbol(TokenType.COMP_EQ), + bool(true), + symbol(TokenType.OPE_OR), + bool(false), + symbol(TokenType.BRACKET_CLOSE), + symbol(TokenType.BRACES_OPEN), + identifier("dur"), + symbol(TokenType.EQUAL), + duration(new Duration(3, TimeUnit.SECONDS)), + symbol(TokenType.OPE_MUL), + identifier("dt"), + symbol(TokenType.SEMI_COLON), + identifier("e"), + symbol(TokenType.EQUAL), + string("\\"), + symbol(TokenType.SEMI_COLON), + symbol(TokenType.BRACES_CLOSE) + ) + ); + } + + @Test + void basicOperator() { + String input = "z = (-1 + 3) * x"; + assertTokenize( + input, + List.of( + identifier("z"), + symbol(TokenType.EQUAL), + symbol(TokenType.BRACKET_OPEN), + symbol(TokenType.OPE_SUB), + number(1), + symbol(TokenType.OPE_ADD), + number(3), + symbol(TokenType.BRACKET_CLOSE), + symbol(TokenType.OPE_MUL), + identifier("x") + ) + ); + } + + @Test + void basicString() { + String input = "str = \"val\\\"ue\";"; + assertTokenize( + input, + List.of( + identifier("str"), + symbol(TokenType.EQUAL), + string("val\"ue"), + symbol(TokenType.SEMI_COLON) + ) + ); + } + + // ---------------------------------- + + private static @NotNull List tokenize(@NotNull String input) { + var output = Tokenizer.tokenize(CharStream.from(input)); + List tokens = new ArrayList<>(); + while(output.hasMore()) { + tokens.add(output.next()); + } + return tokens; + } + + private static void assertTokenize(String input, @NotNull List tokens) { + List outputTokens = tokenize(input); + List expectedTokens = new ArrayList<>(tokens); + expectedTokens.add(symbol(TokenType.EOF)); + Assertions.assertEquals(expectedTokens.size(), outputTokens.size(), "Tokens are not the same length. E=" +expectedTokens+", O="+outputTokens); + for(int i = 0; i < expectedTokens.size(); i++) { + Assertions.assertEquals(expectedTokens.get(i), outputTokens.get(i), "Token of index " + i + " was NOT equal."); + } + } + + private static Token bool(boolean v) { + return Token.fromBoolean(v, TokenPosition.unknown()); + } + private static Token string(String v) { + return Token.fromString(v, TokenPosition.unknown()); + } + private static Token number(double v) { + return Token.fromNumber(v, TokenPosition.unknown()); + } + private static Token duration(Duration v) { + return Token.fromDuration(v.amount(), v.timeUnit(), TokenPosition.unknown()); + } + private static Token identifier(String v) { + return Token.fromIdentifier(v, TokenPosition.unknown()); + } + private static Token symbol(TokenType v) { + return new Token(v, TokenPosition.unknown()); + } + +} From 405c78efc4ba358d5f1f442b7d588db685fdc205 Mon Sep 17 00:00:00 2001 From: "timothe.rosaz" Date: Wed, 22 Oct 2025 17:08:13 +0200 Subject: [PATCH 03/38] Basic logic --- .../dsl2/nodes/ExpressionNode.java | 2 +- .../dsl2/nodes/StatementNode.java | 76 +++++++++---------- .../statements/AffectationStatement.java | 10 +-- .../nodes/statements/DeclareNewVariable.java | 6 ++ .../dsl2/CorrectParsingTests.java | 5 +- .../parsing/corrects/basics/basic.uss | 1 + 6 files changed, 50 insertions(+), 50 deletions(-) create mode 100644 dsl2/src/test/resources/parsing/corrects/basics/basic.uss diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/ExpressionNode.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/ExpressionNode.java index 60f33685..f64bae56 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/ExpressionNode.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/ExpressionNode.java @@ -120,7 +120,7 @@ private static ExpressionNode readNextExpression(TokenStream tokens, MathParsing } - private static ExpressionNode parseIdentifierExpression(Token first, TokenStream tokens) { + public static ExpressionNode parseIdentifierExpression(Token first, TokenStream tokens) { ExpressionNode left = new ReferenceExpression(first); return parseIdentifierExpression(left, tokens); } diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/StatementNode.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/StatementNode.java index e605f10d..eac88b68 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/StatementNode.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/StatementNode.java @@ -1,5 +1,6 @@ package fr.jamailun.ultimatespellsystem.dsl2.nodes; +import fr.jamailun.ultimatespellsystem.dsl2.errors.ParsingException; import fr.jamailun.ultimatespellsystem.dsl2.errors.SyntaxException; import fr.jamailun.ultimatespellsystem.dsl2.errors.UssException; import fr.jamailun.ultimatespellsystem.dsl2.nodes.statements.*; @@ -8,8 +9,10 @@ import fr.jamailun.ultimatespellsystem.dsl2.nodes.statements.blocks.WhileLoopStatement; import fr.jamailun.ultimatespellsystem.dsl2.tokenization.Token; import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenStream; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenType; import fr.jamailun.ultimatespellsystem.dsl2.visitor.StatementVisitor; import org.jetbrains.annotations.NotNull; + /** * A statement is an instruction in the code. It can use other statements, or {@link ExpressionNode expressions}.
* Can be visited by a {@link StatementVisitor}. @@ -17,64 +20,58 @@ */ public abstract class StatementNode extends Node { - /** * Make this statement be visited. * @param visitor the visitor to use. */ public abstract void visit(@NotNull StatementVisitor visitor); -/* + private static @NotNull StatementNode parseFromIdentifier(@NotNull Token first, @NotNull TokenStream tokens) { if(!tokens.hasMore()) throw new ParsingException(tokens.position(), "Unexpected end of tokens after identifier."); - // Pas d'identifier après. Donc c'est une expression simple. - // Genre 'IDENTIFIER.' ou 'IDENTIFIER[' - if(!tokens.peekIs(TokenType.IDENTIFIER, TokenType.EQUAL)) { - //TODO - ExpressionNode expressionNode = ExpressionNode.readNextExpression(tokens, true); - return new SimpleExpressionStatement(expressionNode); - } - - // Cas simple : égal - if(tokens.dropOptional(TokenType.EQUAL)) { - //FIXME ne pas passer un token mais une expression (wra sous forme de variable) - return AffectationStatement.parseNextDefine(first, tokens); - } + // Si c'est encore un IDENTIFIER : c'est soit une déclaration de variable ou de fonction. + if(tokens.peekIs(TokenType.IDENTIFIER)) { + Token second = tokens.next(); // identifier - // "IDENTIFIER.IDENTIFIER" ... tout ça c'est le cas complexe. On estime qu'on veut une expression. + // "A B =" : variable declaration + if(tokens.dropOptional(TokenType.EQUAL)) { + ExpressionNode definition = ExpressionNode.readNextExpression(tokens); + StatementNode output = new DeclareNewVariable(first, second, definition); + tokens.dropOrThrow(TokenType.SEMI_COLON, "Expected a SEMI COLON."); + return output; + } + // "A B(..." : function declaration + if(tokens.dropOptional(TokenType.BRACKET_OPEN)) { + StatementNode output = FunctionDeclarationStatement.parseNextFunction(first, second, tokens); + tokens.dropOrThrow(TokenType.SEMI_COLON, "Expected a SEMI COLON."); + return output; + } - Token second = tokens.next(); - if(second.getType() != TokenType.IDENTIFIER) { - throw new SyntaxException(second, "Expected an identifier after '" + first.getContentString() + "'."); + // Illegal ? + throw new SyntaxException(tokens.position(), "Unexpected token after 'IDENTIFIER IDENTIFIER' : " + tokens.peek()); } - // "IDENTIFIER = ..." :: C'est une affectation - if(tokens.dropOptional(TokenType.EQUAL)) { - return AffectationStatement.parseNextDefine(first, tokens); - } + //TODO Incrment / decrement ! - // "IDENTIFIER IDENTIFIER" on peut soit déclarer une variable, soit une fonction - Token second = tokens.next(); - if(second.getType() != TokenType.IDENTIFIER) { - throw new SyntaxException(second, "Expected an identifier after '" + first.getContentString() + "'."); - } + // On essaye de wrapper le token en expression ("a" ou "a.b().c") pour voir si on a un EQUAL ensuite. + ExpressionNode wrapped = ExpressionNode.parseIdentifierExpression(first, tokens); - // Point-virgule : variable déclarée sans valeur - // "TYPE IDENTIFIER ;" + // Point virgule ? On wrap juste tout ça. if(tokens.dropOptional(TokenType.SEMI_COLON)) { - return DeclareNewVariable.parseNextDefine(first, second, false, tokens); + //TODO interdire les "faux-statements" qui n'ont aucun effet ? Ou faire ça dans AST complet. + return new SimpleExpressionStatement(wrapped); } - // "TYPE IDENTIFIER = ..." + + // EQUAL ? On désigne le tout comme une affectation if(tokens.dropOptional(TokenType.EQUAL)) { - return DeclareNewVariable.parseNextDefine(first, second, true, tokens); + return AffectationStatement.parseNextDefine(wrapped, tokens); } - // Ici, on attend donc une déclaration de fonction - return FunctionDeclarationStatement.parseNextFunction(first, second, tokens); + throw new SyntaxException(tokens.position(), "Unexpected token after IDENTIFIER: " + tokens.peek()); } -*/ + /** * Read a new statement from the tokens stream. * @param tokens the stream of tokens. @@ -87,12 +84,7 @@ public abstract class StatementNode extends Node { // Empty statement case SEMI_COLON -> parseNextStatement(tokens); - case IDENTIFIER -> { - tokens.back(); - ExpressionNode expression = ExpressionNode.readNextExpression(tokens); - // TODO convert me into affectation :) - yield new SimpleExpressionStatement(expression); - } + case IDENTIFIER -> parseFromIdentifier(token, tokens); // Metadata //TODO case CHAR_AT -> MetadataStatement.parseMetadata(tokens); diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/AffectationStatement.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/AffectationStatement.java index 4ea0627e..62a54525 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/AffectationStatement.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/AffectationStatement.java @@ -3,7 +3,6 @@ import fr.jamailun.ultimatespellsystem.dsl2.nodes.ExpressionNode; import fr.jamailun.ultimatespellsystem.dsl2.nodes.StatementNode; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.variables.TypesContext; -import fr.jamailun.ultimatespellsystem.dsl2.tokenization.Token; import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenStream; import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenType; import fr.jamailun.ultimatespellsystem.dsl2.visitor.StatementVisitor; @@ -18,7 +17,7 @@ @RequiredArgsConstructor public class AffectationStatement extends StatementNode { - private final String varName; + private final ExpressionNode valueHolder; private final ExpressionNode expression; @Override @@ -35,7 +34,7 @@ public void visit(@NotNull StatementVisitor visitor) { @Override public @NotNull String toString() { - return varName + " = " + expression; + return valueHolder + " = " + expression; } /** @@ -43,13 +42,12 @@ public void visit(@NotNull StatementVisitor visitor) { * @param tokens streams of tokens. * @return a new instance. */ - public static @NotNull StatementNode parseNextDefine(@NotNull Token identifier, @NotNull TokenStream tokens) { - String varName = identifier.getContentString(); + public static @NotNull StatementNode parseNextDefine(@NotNull ExpressionNode affected, @NotNull TokenStream tokens) { ExpressionNode expression = ExpressionNode.readNextExpression(tokens); // optional ; tokens.dropOptional(TokenType.SEMI_COLON); - return new AffectationStatement(varName, expression); + return new AffectationStatement(affected, expression); } } diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/DeclareNewVariable.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/DeclareNewVariable.java index f7aca9a1..0768898c 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/DeclareNewVariable.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/DeclareNewVariable.java @@ -22,6 +22,12 @@ public class DeclareNewVariable extends StatementNode { private final String varName; private final ExpressionNode expression; + public DeclareNewVariable(@NotNull Token varType, @NotNull Token varName, @NotNull ExpressionNode expression) { + this.varType = varType.getContentString(); + this.varName = varName.getContentString(); + this.expression = expression; + } + @Override public void validateTypes(@NotNull TypesContext context) { expression.validateTypes(context); diff --git a/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/CorrectParsingTests.java b/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/CorrectParsingTests.java index 4186a40c..a17959ff 100644 --- a/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/CorrectParsingTests.java +++ b/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/CorrectParsingTests.java @@ -1,7 +1,6 @@ package fr.jamailun.ultimatespellsystem.dsl2; import fr.jamailun.ultimatespellsystem.dsl2.errors.UssException; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionDefinition; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; import fr.jamailun.ultimatespellsystem.dsl2.registries.FunctionDefinitionsRegistry; @@ -16,6 +15,10 @@ */ public class CorrectParsingTests extends ParsingTest { + @Test + void correctBasics() { + testFolder("corrects/basics"); + } @Test void correctStatements() { testFolder("corrects/statements"); diff --git a/dsl2/src/test/resources/parsing/corrects/basics/basic.uss b/dsl2/src/test/resources/parsing/corrects/basics/basic.uss new file mode 100644 index 00000000..f5df61d0 --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/basics/basic.uss @@ -0,0 +1 @@ +int foo = 3; From 6addd1e2746bfce7cc3103b723b7dcaba16c7821 Mon Sep 17 00:00:00 2001 From: "timothe.rosaz" Date: Wed, 22 Oct 2025 17:32:56 +0200 Subject: [PATCH 04/38] Function declaration --- .../dsl2/nodes/StatementNode.java | 11 +++-- .../statements/AffectationStatement.java | 3 +- ....java => DeclareNewVariableStatement.java} | 24 ++++++----- .../FunctionDeclarationStatement.java | 23 +++++++---- .../nodes/statements/IncrementStatement.java | 3 +- .../StructureValidationVisitor.java | 13 +++++- .../dsl2/visitor/PrintingVisitor.java | 40 ++++++++++++++++--- .../dsl2/visitor/StatementVisitor.java | 5 ++- .../corrects/basics/affect_reaffect.uss | 2 + .../{basic.uss => basic_affectation.uss} | 0 .../parsing/corrects/basics/declarations.uss | 3 ++ 11 files changed, 94 insertions(+), 33 deletions(-) rename dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/{DeclareNewVariable.java => DeclareNewVariableStatement.java} (72%) create mode 100644 dsl2/src/test/resources/parsing/corrects/basics/affect_reaffect.uss rename dsl2/src/test/resources/parsing/corrects/basics/{basic.uss => basic_affectation.uss} (100%) create mode 100644 dsl2/src/test/resources/parsing/corrects/basics/declarations.uss diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/StatementNode.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/StatementNode.java index eac88b68..0a991137 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/StatementNode.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/StatementNode.java @@ -37,16 +37,19 @@ public abstract class StatementNode extends Node { // "A B =" : variable declaration if(tokens.dropOptional(TokenType.EQUAL)) { ExpressionNode definition = ExpressionNode.readNextExpression(tokens); - StatementNode output = new DeclareNewVariable(first, second, definition); + StatementNode output = new DeclareNewVariableStatement(first, second, definition); tokens.dropOrThrow(TokenType.SEMI_COLON, "Expected a SEMI COLON."); return output; } // "A B(..." : function declaration if(tokens.dropOptional(TokenType.BRACKET_OPEN)) { - StatementNode output = FunctionDeclarationStatement.parseNextFunction(first, second, tokens); - tokens.dropOrThrow(TokenType.SEMI_COLON, "Expected a SEMI COLON."); - return output; + return FunctionDeclarationStatement.parseNextFunction(first, second, tokens); + } + + if (tokens.dropOptional(TokenType.SEMI_COLON)) { + return new DeclareNewVariableStatement(first, second, null); + // le semi-colon a déjà été retiré :) } // Illegal ? diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/AffectationStatement.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/AffectationStatement.java index 62a54525..6e46d843 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/AffectationStatement.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/AffectationStatement.java @@ -28,8 +28,7 @@ public void validateTypes(@NotNull TypesContext context) { @Override public void visit(@NotNull StatementVisitor visitor) { - //TODO - throw new UnsupportedOperationException("Not implemented yet"); + visitor.handleAffectVariable(this); } @Override diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/DeclareNewVariable.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/DeclareNewVariableStatement.java similarity index 72% rename from dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/DeclareNewVariable.java rename to dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/DeclareNewVariableStatement.java index 0768898c..6827d794 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/DeclareNewVariable.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/DeclareNewVariableStatement.java @@ -10,19 +10,20 @@ import lombok.Getter; import lombok.RequiredArgsConstructor; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * Define statement will set a variable to something. */ @Getter @RequiredArgsConstructor -public class DeclareNewVariable extends StatementNode { +public class DeclareNewVariableStatement extends StatementNode { - private final String varType; - private final String varName; - private final ExpressionNode expression; + private final @NotNull String varType; + private final @NotNull String varName; + private final @Nullable ExpressionNode expression; - public DeclareNewVariable(@NotNull Token varType, @NotNull Token varName, @NotNull ExpressionNode expression) { + public DeclareNewVariableStatement(@NotNull Token varType, @NotNull Token varName, @Nullable ExpressionNode expression) { this.varType = varType.getContentString(); this.varName = varName.getContentString(); this.expression = expression; @@ -30,15 +31,16 @@ public DeclareNewVariable(@NotNull Token varType, @NotNull Token varName, @NotNu @Override public void validateTypes(@NotNull TypesContext context) { - expression.validateTypes(context); - // Register variable - //TODO - context.registerVariable(varName, expression); + if(expression != null) { + expression.validateTypes(context); + //TODO + context.registerVariable(varName, expression); + } } @Override public void visit(@NotNull StatementVisitor visitor) { - visitor.handleDefine(this); + visitor.handleDeclareVariable(this); } @Override @@ -59,6 +61,6 @@ public String toString() { // optional ; tokens.dropOptional(TokenType.SEMI_COLON); - return new DeclareNewVariable(varType, varName, expression); + return new DeclareNewVariableStatement(varType, varName, expression); } } diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/FunctionDeclarationStatement.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/FunctionDeclarationStatement.java index 784cfcdb..9e631d74 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/FunctionDeclarationStatement.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/FunctionDeclarationStatement.java @@ -24,14 +24,12 @@ public class FunctionDeclarationStatement extends StatementNode { @Override public void visit(@NotNull StatementVisitor visitor) { - //TODO - throw new UnsupportedOperationException("Not implemented yet"); + visitor.handleFunctionDeclaration(this); } @Override public void validateTypes(@NotNull TypesContext context) { - //TODO - throw new UnsupportedOperationException("Not implemented yet"); + //TODO !! } public static @NotNull FunctionDeclarationStatement parseNextFunction(@NotNull Token typeIdentifier, @NotNull Token nameIdentifier, @NotNull TokenStream tokens) { @@ -42,8 +40,8 @@ public void validateTypes(@NotNull TypesContext context) { List parameters = new ArrayList<>(); boolean first = true; - while(! tokens.dropOptional(TokenType.BRACES_CLOSE)) { - if(first) first = false; else tokens.dropOrThrow(TokenType.COMMA); + while(! tokens.dropOptional(TokenType.BRACKET_CLOSE)) { + if(first) first = false; else tokens.dropOrThrow(TokenType.COMMA, "Arguments need to be separated by a comma."); // Each parameter Token identifierType = tokens.nextOrThrow(TokenType.IDENTIFIER); Token identifierName = tokens.nextOrThrow(TokenType.IDENTIFIER); @@ -51,9 +49,9 @@ public void validateTypes(@NotNull TypesContext context) { } // On ne veut pas un 'block-statement' mais nécessairement des statements - tokens.dropOptional(TokenType.BRACKET_OPEN); + tokens.dropOrThrow(TokenType.BRACES_OPEN, "A function need to have statements !"); List statements = new ArrayList<>(); - while(! tokens.dropOptional(TokenType.BRACKET_CLOSE)) { + while(! tokens.dropOptional(TokenType.BRACES_CLOSE)) { statements.add(StatementNode.parseNextStatement(tokens)); tokens.dropOptional(TokenType.SEMI_COLON); } @@ -62,4 +60,13 @@ public void validateTypes(@NotNull TypesContext context) { } public record FunctionParameter(String type, String name) {} + + @Override + public String toString() { + return "FUNCTION " + functionReturnType + " " + functionName + "(" + + parameters.toString() + + ") {" + + statements.toString() + + "}"; + } } diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/IncrementStatement.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/IncrementStatement.java index e1438b59..3f63e3e2 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/IncrementStatement.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/IncrementStatement.java @@ -23,6 +23,7 @@ public class IncrementStatement extends StatementNode { private final TokenPosition tokenPosition; private final String varName; private final boolean positive; + private final boolean afterVar; @Override public void validateTypes(@NotNull TypesContext context) { @@ -49,7 +50,7 @@ public void visit(@NotNull StatementVisitor visitor) { public static @NotNull IncrementStatement parseIncrementOrDecrement(@NotNull TokenStream tokens, boolean increment) { Token var = tokens.nextOrThrow(TokenType.IDENTIFIER); tokens.dropOptional(TokenType.SEMI_COLON); - return new IncrementStatement(var.pos(), var.getContentString(), increment); + return new IncrementStatement(var.pos(), var.getContentString(), increment, false); } @Override diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/validators/StructureValidationVisitor.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/validators/StructureValidationVisitor.java index ab0c1467..e4275806 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/validators/StructureValidationVisitor.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/validators/StructureValidationVisitor.java @@ -78,7 +78,18 @@ public void handleWhileLoop(@NotNull WhileLoopStatement statement) { handleSub(statement.getChild()); } @Override - public void handleDefine(@NotNull DeclareNewVariable statement) {handleMono();} + public void handleDeclareVariable(@NotNull DeclareNewVariableStatement statement) {handleMono();} + + @Override + public void handleAffectVariable(@NotNull AffectationStatement statement) { + handleMono(); + } + + @Override + public void handleFunctionDeclaration(@NotNull FunctionDeclarationStatement statement) { + //TODO ?? + } + @Override public void handleIncrement(@NotNull IncrementStatement statement) {handleMono();} @Override diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/PrintingVisitor.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/PrintingVisitor.java index 10142ddd..ca3f8f23 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/PrintingVisitor.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/PrintingVisitor.java @@ -110,17 +110,47 @@ public void handleReturn(@NotNull ReturnStatement statement) { builder.append(indent()).append("stop"); } - - @Override - public void handleDefine(@NotNull DeclareNewVariable statement) { + public void handleDeclareVariable(@NotNull DeclareNewVariableStatement statement) { builder.append(indent()) .append("define %") - .append(statement.getVarName()) - .append(" = "); + .append(statement.getVarName()); + + if(statement.getExpression() != null) { + builder.append(" = "); + statement.getExpression().visit(this); + } + } + + @Override + public void handleAffectVariable(@NotNull AffectationStatement statement) { + statement.getValueHolder().visit(this); + builder.append(" := "); statement.getExpression().visit(this); } + @Override + public void handleFunctionDeclaration(@NotNull FunctionDeclarationStatement statement) { + builder.append("FUNCTION ") + .append(statement.getFunctionReturnType()) + .append(" ") + .append(statement.getFunctionName()) + .append("("); + boolean first = true; + for(var arg : statement.getParameters()) { + if(first) first = false; else builder.append(", "); + builder.append(arg); + } + builder.append(") {\n"); + right(); + for(var st : statement.getStatements()) { + st.visit(this); + eol(); + } + left(); + builder.append("}"); + } + @Override public void handleBlock(@NotNull BlockStatement statement) { diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/StatementVisitor.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/StatementVisitor.java index 9f09ca34..f32ecc76 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/StatementVisitor.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/StatementVisitor.java @@ -11,8 +11,11 @@ */ public interface StatementVisitor { + void handleDeclareVariable(@NotNull DeclareNewVariableStatement statement); + void handleAffectVariable(@NotNull AffectationStatement statement); + void handleFunctionDeclaration(@NotNull FunctionDeclarationStatement statement); + void handleReturn(@NotNull ReturnStatement statement); - void handleDefine(@NotNull DeclareNewVariable statement); void handleBlock(@NotNull BlockStatement statement); void handleIncrement(@NotNull IncrementStatement statement); void handleSimpleExpression(@NotNull SimpleExpressionStatement statement); diff --git a/dsl2/src/test/resources/parsing/corrects/basics/affect_reaffect.uss b/dsl2/src/test/resources/parsing/corrects/basics/affect_reaffect.uss new file mode 100644 index 00000000..bc7a208a --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/basics/affect_reaffect.uss @@ -0,0 +1,2 @@ +int foo = 3; +foo = 4; diff --git a/dsl2/src/test/resources/parsing/corrects/basics/basic.uss b/dsl2/src/test/resources/parsing/corrects/basics/basic_affectation.uss similarity index 100% rename from dsl2/src/test/resources/parsing/corrects/basics/basic.uss rename to dsl2/src/test/resources/parsing/corrects/basics/basic_affectation.uss diff --git a/dsl2/src/test/resources/parsing/corrects/basics/declarations.uss b/dsl2/src/test/resources/parsing/corrects/basics/declarations.uss new file mode 100644 index 00000000..ecb4f595 --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/basics/declarations.uss @@ -0,0 +1,3 @@ +int some_method() { + int some_var; +} \ No newline at end of file From 849ad0d7b30e478449bb8118010af4428bd5c9a8 Mon Sep 17 00:00:00 2001 From: "timothe.rosaz" Date: Wed, 22 Oct 2025 17:43:25 +0200 Subject: [PATCH 05/38] Variable declaration with VAR --- .../dsl2/nodes/StatementNode.java | 10 +++++++ .../DeclareNewVariableStatement.java | 28 ++++--------------- .../dsl2/visitor/PrintingVisitor.java | 3 +- .../corrects/basics/basic_affectation.uss | 3 ++ .../parsing/corrects/basics/field_access.uss | 1 + 5 files changed, 22 insertions(+), 23 deletions(-) create mode 100644 dsl2/src/test/resources/parsing/corrects/basics/field_access.uss diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/StatementNode.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/StatementNode.java index 0a991137..bbcc2987 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/StatementNode.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/StatementNode.java @@ -87,6 +87,16 @@ public abstract class StatementNode extends Node { // Empty statement case SEMI_COLON -> parseNextStatement(tokens); + case VAR -> { + Token varName = tokens.nextOrThrow(TokenType.IDENTIFIER, "Expect an IDENTIFIER after a VAR."); + ExpressionNode expression = null; + if(tokens.dropOptional(TokenType.EQUAL)) { + expression = ExpressionNode.readNextExpression(tokens); + } + StatementNode output = new DeclareNewVariableStatement(null, varName, expression); + tokens.dropOrThrow(TokenType.SEMI_COLON, "Expected a semi-colon, after a variable declaration."); + yield output; + } case IDENTIFIER -> parseFromIdentifier(token, tokens); // Metadata diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/DeclareNewVariableStatement.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/DeclareNewVariableStatement.java index 6827d794..597d2cba 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/DeclareNewVariableStatement.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/DeclareNewVariableStatement.java @@ -4,14 +4,14 @@ import fr.jamailun.ultimatespellsystem.dsl2.nodes.StatementNode; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.variables.TypesContext; import fr.jamailun.ultimatespellsystem.dsl2.tokenization.Token; -import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenStream; -import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenType; import fr.jamailun.ultimatespellsystem.dsl2.visitor.StatementVisitor; import lombok.Getter; import lombok.RequiredArgsConstructor; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Objects; + /** * Define statement will set a variable to something. */ @@ -19,12 +19,12 @@ @RequiredArgsConstructor public class DeclareNewVariableStatement extends StatementNode { - private final @NotNull String varType; + private final @Nullable String varType; private final @NotNull String varName; private final @Nullable ExpressionNode expression; - public DeclareNewVariableStatement(@NotNull Token varType, @NotNull Token varName, @Nullable ExpressionNode expression) { - this.varType = varType.getContentString(); + public DeclareNewVariableStatement(@Nullable Token varType, @NotNull Token varName, @Nullable ExpressionNode expression) { + this.varType = varType == null ? null : varType.getContentString(); this.varName = varName.getContentString(); this.expression = expression; } @@ -45,22 +45,6 @@ public void visit(@NotNull StatementVisitor visitor) { @Override public String toString() { - return varType + " " + varName + " = " + expression; - } - - /** - * Parse a define statement. - * @param tokens streams of tokens. - * @return a new instance. - */ - public static @NotNull StatementNode parseNextDefine(@NotNull Token typeIdentifier, @NotNull Token varIdentifier, boolean hasValue, @NotNull TokenStream tokens) { - String varType = typeIdentifier.getContentString(); - String varName = varIdentifier.getContentString(); - ExpressionNode expression = hasValue ? ExpressionNode.readNextExpression(tokens) : null; - - // optional ; - tokens.dropOptional(TokenType.SEMI_COLON); - - return new DeclareNewVariableStatement(varType, varName, expression); + return Objects.requireNonNullElse(varType, "VAR") + " " + varName + (expression == null ? "" : " = " + expression); } } diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/PrintingVisitor.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/PrintingVisitor.java index ca3f8f23..76cbc1e1 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/PrintingVisitor.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/PrintingVisitor.java @@ -113,7 +113,8 @@ public void handleReturn(@NotNull ReturnStatement statement) { @Override public void handleDeclareVariable(@NotNull DeclareNewVariableStatement statement) { builder.append(indent()) - .append("define %") + .append(statement.getVarType() == null ? "VAR" : statement.getVarType()) + .append(" ") .append(statement.getVarName()); if(statement.getExpression() != null) { diff --git a/dsl2/src/test/resources/parsing/corrects/basics/basic_affectation.uss b/dsl2/src/test/resources/parsing/corrects/basics/basic_affectation.uss index f5df61d0..a81404c5 100644 --- a/dsl2/src/test/resources/parsing/corrects/basics/basic_affectation.uss +++ b/dsl2/src/test/resources/parsing/corrects/basics/basic_affectation.uss @@ -1 +1,4 @@ int foo = 3; + +var bar = "oui"; + diff --git a/dsl2/src/test/resources/parsing/corrects/basics/field_access.uss b/dsl2/src/test/resources/parsing/corrects/basics/field_access.uss new file mode 100644 index 00000000..560080e4 --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/basics/field_access.uss @@ -0,0 +1 @@ +string str = "aaaa"; From 5037d3fe059c5658e60cde31ea95799fb5b8fe97 Mon Sep 17 00:00:00 2001 From: "timothe.rosaz" Date: Wed, 22 Oct 2025 19:01:25 +0200 Subject: [PATCH 06/38] Function call is parsed --- .../ultimatespellsystem/dsl2/nodes/ExpressionNode.java | 4 ++-- .../dsl2/nodes/expressions/FunctionCallExpression.java | 7 ++++++- .../expressions/functions/FunctionCallExpression.java | 2 +- .../dsl2/visitor/ExpressionVisitor.java | 5 +---- .../dsl2/visitor/PrintingVisitor.java | 10 ++++------ .../ultimatespellsystem/dsl2/CorrectParsingTests.java | 2 ++ .../resources/parsing/corrects/basics/field_access.uss | 2 +- 7 files changed, 17 insertions(+), 15 deletions(-) diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/ExpressionNode.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/ExpressionNode.java index f64bae56..6333ddc0 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/ExpressionNode.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/ExpressionNode.java @@ -136,7 +136,7 @@ public static ExpressionNode parseIdentifierExpression(Token first, TokenStream // Parenthèse ? // a.IDENTIFIER(...) - if(tokens.dropOptional(TokenType.BRACES_OPEN)) { + if(tokens.dropOptional(TokenType.BRACKET_OPEN)) { List arguments = parseArgumentsParameter(tokens); String fctName = identifier.getContentString(); ExpressionNode fctCall = new FunctionCallExpression(left, fctName, arguments); @@ -171,7 +171,7 @@ public static ExpressionNode parseIdentifierExpression(Token first, TokenStream public static List parseArgumentsParameter(@NotNull TokenStream tokens) { List list = new ArrayList<>(); boolean first = true; - while(!tokens.dropOptional(TokenType.BRACES_CLOSE)) { + while(!tokens.dropOptional(TokenType.BRACKET_CLOSE)) { if(first) first = false; else tokens.dropOrThrow(TokenType.COMMA, "A COMMA is required between parameters."); ExpressionNode expression = ExpressionNode.readNextExpression(tokens); list.add(expression); diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/FunctionCallExpression.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/FunctionCallExpression.java index 08707923..0c453e29 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/FunctionCallExpression.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/FunctionCallExpression.java @@ -40,6 +40,11 @@ public void validateTypes(@NotNull TypesContext context) { @Override public void visit(@NotNull ExpressionVisitor visitor) { - throw new UnsupportedOperationException("Not supported yet."); + visitor.handleFunctionCall(this); + } + + @Override + public String toString() { + return caller + "." + functionName + "(" + arguments + ")"; } } diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/functions/FunctionCallExpression.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/functions/FunctionCallExpression.java index be09d288..995aeb26 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/functions/FunctionCallExpression.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/functions/FunctionCallExpression.java @@ -44,7 +44,7 @@ public void validateTypes(@NotNull TypesContext contextRaw) { @Override public void visit(@NotNull ExpressionVisitor visitor) { - visitor.handleFunction(this); + throw new UnsupportedOperationException("plus maintenant"); } @Override diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/ExpressionVisitor.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/ExpressionVisitor.java index a15539d1..5cd82394 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/ExpressionVisitor.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/ExpressionVisitor.java @@ -1,7 +1,6 @@ package fr.jamailun.ultimatespellsystem.dsl2.visitor; import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.*; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionCallExpression; import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.litteral.*; import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.operators.BiOperator; import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.operators.MonoOperator; @@ -27,12 +26,10 @@ public interface ExpressionVisitor { void handleParenthesis(@NotNull ParenthesisExpression parenthesis); void handleArrayGet(@NotNull ArrayGetterExpression arrayGetter); void handleFieldGet(@NotNull FieldGetExpression fieldGetter); + void handleFunctionCall(@NotNull FunctionCallExpression functionCall); // Specifics void handleArray(@NotNull ArrayExpression expression); void handleVariable(@NotNull ReferenceExpression expression); - // Functions - void handleFunction(@NotNull FunctionCallExpression expression); - } diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/PrintingVisitor.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/PrintingVisitor.java index 76cbc1e1..65a572b1 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/PrintingVisitor.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/PrintingVisitor.java @@ -1,7 +1,6 @@ package fr.jamailun.ultimatespellsystem.dsl2.visitor; import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.*; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionCallExpression; import fr.jamailun.ultimatespellsystem.dsl2.nodes.ExpressionNode; import fr.jamailun.ultimatespellsystem.dsl2.nodes.StatementNode; import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.litteral.*; @@ -339,12 +338,11 @@ public void handleFieldGet(@NotNull FieldGetExpression fieldGetter) { } @Override - public void handleFunction(@NotNull FunctionCallExpression expression) { - builder.append(":") - .append(expression.getFunction().id()) - .append("("); + public void handleFunctionCall(@NotNull FunctionCallExpression functionCall) { + functionCall.getCaller().visit(this); + builder.append(".").append(functionCall.getFunctionName()).append("("); boolean first = true; - for(ExpressionNode arg : expression.getArguments()) { + for(ExpressionNode arg : functionCall.getArguments()) { if(first) first = false; else builder.append(", "); arg.visit(this); } diff --git a/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/CorrectParsingTests.java b/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/CorrectParsingTests.java index a17959ff..8262937a 100644 --- a/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/CorrectParsingTests.java +++ b/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/CorrectParsingTests.java @@ -19,10 +19,12 @@ public class CorrectParsingTests extends ParsingTest { void correctBasics() { testFolder("corrects/basics"); } + @Test void correctStatements() { testFolder("corrects/statements"); } + @Test void correctBlocks() { testFolder("corrects/blocks"); diff --git a/dsl2/src/test/resources/parsing/corrects/basics/field_access.uss b/dsl2/src/test/resources/parsing/corrects/basics/field_access.uss index 560080e4..14c198ca 100644 --- a/dsl2/src/test/resources/parsing/corrects/basics/field_access.uss +++ b/dsl2/src/test/resources/parsing/corrects/basics/field_access.uss @@ -1 +1 @@ -string str = "aaaa"; +console.log("test"); From ffb0c9228777bd7a3547460ac0bcb2e09ddb7f1f Mon Sep 17 00:00:00 2001 From: "timothe.rosaz" Date: Wed, 22 Oct 2025 19:12:04 +0200 Subject: [PATCH 07/38] blocks tests are passing --- dsl2/src/test/resources/parsing/corrects/basics/block.uss | 6 ++++++ .../test/resources/parsing/corrects/basics/block_if.uss | 4 ++++ .../resources/parsing/corrects/basics/block_if_else.uss | 6 ++++++ .../resources/parsing/corrects/basics/block_if_elseif.uss | 8 ++++++++ .../resources/parsing/corrects/basics/loop_do_while_.uss | 4 ++++ .../test/resources/parsing/corrects/basics/loop_for.uss | 3 +++ .../test/resources/parsing/corrects/basics/loop_while.uss | 4 ++++ 7 files changed, 35 insertions(+) create mode 100644 dsl2/src/test/resources/parsing/corrects/basics/block.uss create mode 100644 dsl2/src/test/resources/parsing/corrects/basics/block_if.uss create mode 100644 dsl2/src/test/resources/parsing/corrects/basics/block_if_else.uss create mode 100644 dsl2/src/test/resources/parsing/corrects/basics/block_if_elseif.uss create mode 100644 dsl2/src/test/resources/parsing/corrects/basics/loop_do_while_.uss create mode 100644 dsl2/src/test/resources/parsing/corrects/basics/loop_for.uss create mode 100644 dsl2/src/test/resources/parsing/corrects/basics/loop_while.uss diff --git a/dsl2/src/test/resources/parsing/corrects/basics/block.uss b/dsl2/src/test/resources/parsing/corrects/basics/block.uss new file mode 100644 index 00000000..5e394d31 --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/basics/block.uss @@ -0,0 +1,6 @@ +{ + int j = 3; + { + int i = 0; + } +} \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing/corrects/basics/block_if.uss b/dsl2/src/test/resources/parsing/corrects/basics/block_if.uss new file mode 100644 index 00000000..8be32932 --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/basics/block_if.uss @@ -0,0 +1,4 @@ +bool a = false; +if(a == true || false) { + console.log("ok"); +} \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing/corrects/basics/block_if_else.uss b/dsl2/src/test/resources/parsing/corrects/basics/block_if_else.uss new file mode 100644 index 00000000..b05fe097 --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/basics/block_if_else.uss @@ -0,0 +1,6 @@ +bool a = false; +if(a == true || false) { + console.log("ok"); +} else { + console.log("non"); +} \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing/corrects/basics/block_if_elseif.uss b/dsl2/src/test/resources/parsing/corrects/basics/block_if_elseif.uss new file mode 100644 index 00000000..a00ea6ad --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/basics/block_if_elseif.uss @@ -0,0 +1,8 @@ +bool a = false; +if(a) { + console.log("ok"); +} else if(!a) { + console.log("non"); +} else { + console.log("??"); +} \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing/corrects/basics/loop_do_while_.uss b/dsl2/src/test/resources/parsing/corrects/basics/loop_do_while_.uss new file mode 100644 index 00000000..c4340313 --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/basics/loop_do_while_.uss @@ -0,0 +1,4 @@ +int i = 5; +do { + i = i - 1; +} while(i > 0); \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing/corrects/basics/loop_for.uss b/dsl2/src/test/resources/parsing/corrects/basics/loop_for.uss new file mode 100644 index 00000000..edc7d32d --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/basics/loop_for.uss @@ -0,0 +1,3 @@ +for(int i = 0; i < 5; ++i) { + caster.send("i = " + i); +} diff --git a/dsl2/src/test/resources/parsing/corrects/basics/loop_while.uss b/dsl2/src/test/resources/parsing/corrects/basics/loop_while.uss new file mode 100644 index 00000000..4c8021e9 --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/basics/loop_while.uss @@ -0,0 +1,4 @@ +int i = 5; +while(i > 0) { + i = i - 1; +} \ No newline at end of file From 802e5037f291e600f5bc52adb5494c6d8ee587b4 Mon Sep 17 00:00:00 2001 From: "timothe.rosaz" Date: Thu, 23 Oct 2025 08:28:24 +0200 Subject: [PATCH 08/38] cleaned up tests --- .../dsl2/CorrectParsingTests.java | 47 ++----------------- dsl2/src/test/resources/demo.cpp | 11 ----- .../do_while_.uss} | 0 .../{basics/loop_for.uss => loops/for.uss} | 0 .../parsing/corrects/loops/for_break.uss | 4 ++ .../parsing/corrects/loops/for_break_ctn.uss | 5 ++ .../loop_while.uss => loops/while.uss} | 0 .../bad_mix/invalid_param_meta.uss | 0 .../bad_mix/unknown_function.uss | 0 .../bad_parsing/bad_number.uss | 0 .../bad_parsing/bad_string.uss | 0 .../bad_syntax/bad_else.uss | 0 .../bad_syntax/bad_entity_type.uss | 0 .../bad_syntax/bad_send.uss | 0 .../bad_syntax/bad_var.uss | 0 .../bad_syntax/redefine_caster.uss | 0 .../bad_tree/after_break.uss | 0 .../bad_tree/after_meta_1.uss | 0 .../bad_tree/after_meta_2.uss | 0 .../bad_tree/after_stop_1.uss | 0 .../bad_tree/after_stop_2.uss | 0 .../bad_tree/after_stop_3.uss | 0 .../bad_type/bad_collection_teleport.uss | 0 .../bad_type/bad_list_append.uss | 0 .../bad_type/bad_ope.uss | 0 .../bad_type/bad_ope_2.uss | 0 .../bad_type/bad_ope_3.uss | 0 .../bad_type/increment_type.uss | 0 .../bad_type/redefine_difftype.uss | 0 .../bad_type/stop_type.uss | 0 .../corrects/blocks/for.uss | 0 .../corrects/blocks/for_break.uss | 0 .../corrects/blocks/foreach.uss | 0 .../corrects/blocks/ifelse_p1.uss | 0 .../corrects/blocks/ifelse_p2.uss | 0 .../corrects/blocks/repeat.uss | 0 .../corrects/blocks/repeat_2.uss | 0 .../corrects/blocks/run_later.uss | 0 .../corrects/blocks/while.uss | 0 .../corrects/metadata/param_metadata.uss | 0 .../corrects/mix/cercle.uss | 0 .../corrects/mix/collections.uss | 0 .../corrects/mix/empty.uss | 0 .../corrects/mix/implicit_define.uss | 0 .../corrects/mix/metadata.uss | 0 .../corrects/mix/null_recovery.uss | 0 .../corrects/mix/null_set.uss | 0 .../corrects/mix/particle_shape.uss | 0 .../corrects/mix/test_allof.uss | 0 .../corrects/mix/test_basic.uss | 0 .../corrects/mix/test_complex_tp.uss | 0 .../corrects/mix/test_location_literal.uss | 0 .../corrects/mix/test_null.uss | 0 .../corrects/mix/test_teleport.uss | 0 .../corrects/operators/bool_operators.uss | 0 .../corrects/operators/conditions.uss | 0 .../corrects/operators/list_append.uss | 0 .../corrects/operators/math.uss | 0 .../corrects/operators/operator_priority.uss | 0 .../corrects/operators/parenthesis.uss | 0 .../corrects/operators/type_operators.uss | 0 .../corrects/statements/define.uss | 0 .../corrects/statements/give.uss | 0 .../corrects/statements/increment.uss | 0 .../corrects/statements/play.uss | 0 .../corrects/statements/send.uss | 0 .../corrects/statements/send_nbt.uss | 0 .../corrects/statements/stop_1.uss | 0 .../corrects/statements/stop_2.uss | 0 .../corrects/statements/stop_3.uss | 0 .../corrects/statements/summon.uss | 0 .../corrects/statements/teleport.uss | 0 .../corrects_with_custom/callback.uss | 0 .../corrects_with_custom/custom.uss | 0 74 files changed, 12 insertions(+), 55 deletions(-) delete mode 100644 dsl2/src/test/resources/demo.cpp rename dsl2/src/test/resources/parsing/corrects/{basics/loop_do_while_.uss => loops/do_while_.uss} (100%) rename dsl2/src/test/resources/parsing/corrects/{basics/loop_for.uss => loops/for.uss} (100%) create mode 100644 dsl2/src/test/resources/parsing/corrects/loops/for_break.uss create mode 100644 dsl2/src/test/resources/parsing/corrects/loops/for_break_ctn.uss rename dsl2/src/test/resources/parsing/corrects/{basics/loop_while.uss => loops/while.uss} (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/bad_mix/invalid_param_meta.uss (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/bad_mix/unknown_function.uss (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/bad_parsing/bad_number.uss (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/bad_parsing/bad_string.uss (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/bad_syntax/bad_else.uss (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/bad_syntax/bad_entity_type.uss (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/bad_syntax/bad_send.uss (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/bad_syntax/bad_var.uss (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/bad_syntax/redefine_caster.uss (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/bad_tree/after_break.uss (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/bad_tree/after_meta_1.uss (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/bad_tree/after_meta_2.uss (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/bad_tree/after_stop_1.uss (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/bad_tree/after_stop_2.uss (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/bad_tree/after_stop_3.uss (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/bad_type/bad_collection_teleport.uss (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/bad_type/bad_list_append.uss (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/bad_type/bad_ope.uss (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/bad_type/bad_ope_2.uss (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/bad_type/bad_ope_3.uss (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/bad_type/increment_type.uss (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/bad_type/redefine_difftype.uss (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/bad_type/stop_type.uss (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/corrects/blocks/for.uss (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/corrects/blocks/for_break.uss (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/corrects/blocks/foreach.uss (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/corrects/blocks/ifelse_p1.uss (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/corrects/blocks/ifelse_p2.uss (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/corrects/blocks/repeat.uss (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/corrects/blocks/repeat_2.uss (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/corrects/blocks/run_later.uss (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/corrects/blocks/while.uss (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/corrects/metadata/param_metadata.uss (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/corrects/mix/cercle.uss (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/corrects/mix/collections.uss (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/corrects/mix/empty.uss (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/corrects/mix/implicit_define.uss (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/corrects/mix/metadata.uss (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/corrects/mix/null_recovery.uss (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/corrects/mix/null_set.uss (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/corrects/mix/particle_shape.uss (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/corrects/mix/test_allof.uss (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/corrects/mix/test_basic.uss (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/corrects/mix/test_complex_tp.uss (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/corrects/mix/test_location_literal.uss (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/corrects/mix/test_null.uss (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/corrects/mix/test_teleport.uss (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/corrects/operators/bool_operators.uss (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/corrects/operators/conditions.uss (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/corrects/operators/list_append.uss (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/corrects/operators/math.uss (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/corrects/operators/operator_priority.uss (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/corrects/operators/parenthesis.uss (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/corrects/operators/type_operators.uss (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/corrects/statements/define.uss (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/corrects/statements/give.uss (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/corrects/statements/increment.uss (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/corrects/statements/play.uss (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/corrects/statements/send.uss (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/corrects/statements/send_nbt.uss (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/corrects/statements/stop_1.uss (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/corrects/statements/stop_2.uss (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/corrects/statements/stop_3.uss (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/corrects/statements/summon.uss (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/corrects/statements/teleport.uss (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/corrects_with_custom/callback.uss (100%) rename dsl2/src/test/resources/{parsing => parsing_old}/corrects_with_custom/custom.uss (100%) diff --git a/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/CorrectParsingTests.java b/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/CorrectParsingTests.java index 8262937a..3da0081d 100644 --- a/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/CorrectParsingTests.java +++ b/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/CorrectParsingTests.java @@ -1,14 +1,10 @@ package fr.jamailun.ultimatespellsystem.dsl2; import fr.jamailun.ultimatespellsystem.dsl2.errors.UssException; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionDefinition; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; -import fr.jamailun.ultimatespellsystem.dsl2.registries.FunctionDefinitionsRegistry; import org.jetbrains.annotations.NotNull; import org.junit.jupiter.api.Test; import java.io.File; -import java.util.List; /** * Multiple tests for valid USS files. @@ -21,48 +17,11 @@ void correctBasics() { } @Test - void correctStatements() { - testFolder("corrects/statements"); + void correctLoops() { + testFolder("corrects/loops"); } - @Test - void correctBlocks() { - testFolder("corrects/blocks"); - } - @Test - void correctOperators() { - testFolder("corrects/operators"); - } - @Test - void correctMix() { - testFolder("corrects/mix"); - } - @Test - void correctMetadata() { - testFolder("corrects/metadata"); - } - - @Test - void correctWithCustom() { - // Register "custom_add" - FunctionDefinition definition = new FunctionDefinition( - "custom_add", - TypePrimitive.NUMBER.asType(), - List.of( -// new FunctionArgument(FunctionType.accept(TypePrimitive.NUMBER), "a", false), -// new FunctionArgument(FunctionType.accept(TypePrimitive.NUMBER), "b", false) - ) - ); - FunctionDefinitionsRegistry.register(definition); - - // Callback -// CallbackEventRegistry.register( -// CallbackEvent.of("landed", TokenType.AT, TypePrimitive.LOCATION) -// ); - - // Parse - testFolder("corrects_with_custom"); - } + // -- private void testFolder(@NotNull String folder) { for(File file : listTests(folder)) { diff --git a/dsl2/src/test/resources/demo.cpp b/dsl2/src/test/resources/demo.cpp deleted file mode 100644 index 5cfcca1d..00000000 --- a/dsl2/src/test/resources/demo.cpp +++ /dev/null @@ -1,11 +0,0 @@ -function void foo(a, b) { - x = 42; - for(y = 0; y < 10; y++) { - x += y; - } - dur = 20s; - if(dur * 2 > 1min) { - x = x - 5; - } - caster.send_message("salut"); -} \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing/corrects/basics/loop_do_while_.uss b/dsl2/src/test/resources/parsing/corrects/loops/do_while_.uss similarity index 100% rename from dsl2/src/test/resources/parsing/corrects/basics/loop_do_while_.uss rename to dsl2/src/test/resources/parsing/corrects/loops/do_while_.uss diff --git a/dsl2/src/test/resources/parsing/corrects/basics/loop_for.uss b/dsl2/src/test/resources/parsing/corrects/loops/for.uss similarity index 100% rename from dsl2/src/test/resources/parsing/corrects/basics/loop_for.uss rename to dsl2/src/test/resources/parsing/corrects/loops/for.uss diff --git a/dsl2/src/test/resources/parsing/corrects/loops/for_break.uss b/dsl2/src/test/resources/parsing/corrects/loops/for_break.uss new file mode 100644 index 00000000..87cfc13a --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/loops/for_break.uss @@ -0,0 +1,4 @@ +for(int i = 0; i < 5; ++i) { + caster.send("i = " + i); + break; +} diff --git a/dsl2/src/test/resources/parsing/corrects/loops/for_break_ctn.uss b/dsl2/src/test/resources/parsing/corrects/loops/for_break_ctn.uss new file mode 100644 index 00000000..d7edc072 --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/loops/for_break_ctn.uss @@ -0,0 +1,5 @@ +for(int i = 0; i < 5; ++i) { + caster.send("i = " + i); + if(i >= 3) continue; + break; +} diff --git a/dsl2/src/test/resources/parsing/corrects/basics/loop_while.uss b/dsl2/src/test/resources/parsing/corrects/loops/while.uss similarity index 100% rename from dsl2/src/test/resources/parsing/corrects/basics/loop_while.uss rename to dsl2/src/test/resources/parsing/corrects/loops/while.uss diff --git a/dsl2/src/test/resources/parsing/bad_mix/invalid_param_meta.uss b/dsl2/src/test/resources/parsing_old/bad_mix/invalid_param_meta.uss similarity index 100% rename from dsl2/src/test/resources/parsing/bad_mix/invalid_param_meta.uss rename to dsl2/src/test/resources/parsing_old/bad_mix/invalid_param_meta.uss diff --git a/dsl2/src/test/resources/parsing/bad_mix/unknown_function.uss b/dsl2/src/test/resources/parsing_old/bad_mix/unknown_function.uss similarity index 100% rename from dsl2/src/test/resources/parsing/bad_mix/unknown_function.uss rename to dsl2/src/test/resources/parsing_old/bad_mix/unknown_function.uss diff --git a/dsl2/src/test/resources/parsing/bad_parsing/bad_number.uss b/dsl2/src/test/resources/parsing_old/bad_parsing/bad_number.uss similarity index 100% rename from dsl2/src/test/resources/parsing/bad_parsing/bad_number.uss rename to dsl2/src/test/resources/parsing_old/bad_parsing/bad_number.uss diff --git a/dsl2/src/test/resources/parsing/bad_parsing/bad_string.uss b/dsl2/src/test/resources/parsing_old/bad_parsing/bad_string.uss similarity index 100% rename from dsl2/src/test/resources/parsing/bad_parsing/bad_string.uss rename to dsl2/src/test/resources/parsing_old/bad_parsing/bad_string.uss diff --git a/dsl2/src/test/resources/parsing/bad_syntax/bad_else.uss b/dsl2/src/test/resources/parsing_old/bad_syntax/bad_else.uss similarity index 100% rename from dsl2/src/test/resources/parsing/bad_syntax/bad_else.uss rename to dsl2/src/test/resources/parsing_old/bad_syntax/bad_else.uss diff --git a/dsl2/src/test/resources/parsing/bad_syntax/bad_entity_type.uss b/dsl2/src/test/resources/parsing_old/bad_syntax/bad_entity_type.uss similarity index 100% rename from dsl2/src/test/resources/parsing/bad_syntax/bad_entity_type.uss rename to dsl2/src/test/resources/parsing_old/bad_syntax/bad_entity_type.uss diff --git a/dsl2/src/test/resources/parsing/bad_syntax/bad_send.uss b/dsl2/src/test/resources/parsing_old/bad_syntax/bad_send.uss similarity index 100% rename from dsl2/src/test/resources/parsing/bad_syntax/bad_send.uss rename to dsl2/src/test/resources/parsing_old/bad_syntax/bad_send.uss diff --git a/dsl2/src/test/resources/parsing/bad_syntax/bad_var.uss b/dsl2/src/test/resources/parsing_old/bad_syntax/bad_var.uss similarity index 100% rename from dsl2/src/test/resources/parsing/bad_syntax/bad_var.uss rename to dsl2/src/test/resources/parsing_old/bad_syntax/bad_var.uss diff --git a/dsl2/src/test/resources/parsing/bad_syntax/redefine_caster.uss b/dsl2/src/test/resources/parsing_old/bad_syntax/redefine_caster.uss similarity index 100% rename from dsl2/src/test/resources/parsing/bad_syntax/redefine_caster.uss rename to dsl2/src/test/resources/parsing_old/bad_syntax/redefine_caster.uss diff --git a/dsl2/src/test/resources/parsing/bad_tree/after_break.uss b/dsl2/src/test/resources/parsing_old/bad_tree/after_break.uss similarity index 100% rename from dsl2/src/test/resources/parsing/bad_tree/after_break.uss rename to dsl2/src/test/resources/parsing_old/bad_tree/after_break.uss diff --git a/dsl2/src/test/resources/parsing/bad_tree/after_meta_1.uss b/dsl2/src/test/resources/parsing_old/bad_tree/after_meta_1.uss similarity index 100% rename from dsl2/src/test/resources/parsing/bad_tree/after_meta_1.uss rename to dsl2/src/test/resources/parsing_old/bad_tree/after_meta_1.uss diff --git a/dsl2/src/test/resources/parsing/bad_tree/after_meta_2.uss b/dsl2/src/test/resources/parsing_old/bad_tree/after_meta_2.uss similarity index 100% rename from dsl2/src/test/resources/parsing/bad_tree/after_meta_2.uss rename to dsl2/src/test/resources/parsing_old/bad_tree/after_meta_2.uss diff --git a/dsl2/src/test/resources/parsing/bad_tree/after_stop_1.uss b/dsl2/src/test/resources/parsing_old/bad_tree/after_stop_1.uss similarity index 100% rename from dsl2/src/test/resources/parsing/bad_tree/after_stop_1.uss rename to dsl2/src/test/resources/parsing_old/bad_tree/after_stop_1.uss diff --git a/dsl2/src/test/resources/parsing/bad_tree/after_stop_2.uss b/dsl2/src/test/resources/parsing_old/bad_tree/after_stop_2.uss similarity index 100% rename from dsl2/src/test/resources/parsing/bad_tree/after_stop_2.uss rename to dsl2/src/test/resources/parsing_old/bad_tree/after_stop_2.uss diff --git a/dsl2/src/test/resources/parsing/bad_tree/after_stop_3.uss b/dsl2/src/test/resources/parsing_old/bad_tree/after_stop_3.uss similarity index 100% rename from dsl2/src/test/resources/parsing/bad_tree/after_stop_3.uss rename to dsl2/src/test/resources/parsing_old/bad_tree/after_stop_3.uss diff --git a/dsl2/src/test/resources/parsing/bad_type/bad_collection_teleport.uss b/dsl2/src/test/resources/parsing_old/bad_type/bad_collection_teleport.uss similarity index 100% rename from dsl2/src/test/resources/parsing/bad_type/bad_collection_teleport.uss rename to dsl2/src/test/resources/parsing_old/bad_type/bad_collection_teleport.uss diff --git a/dsl2/src/test/resources/parsing/bad_type/bad_list_append.uss b/dsl2/src/test/resources/parsing_old/bad_type/bad_list_append.uss similarity index 100% rename from dsl2/src/test/resources/parsing/bad_type/bad_list_append.uss rename to dsl2/src/test/resources/parsing_old/bad_type/bad_list_append.uss diff --git a/dsl2/src/test/resources/parsing/bad_type/bad_ope.uss b/dsl2/src/test/resources/parsing_old/bad_type/bad_ope.uss similarity index 100% rename from dsl2/src/test/resources/parsing/bad_type/bad_ope.uss rename to dsl2/src/test/resources/parsing_old/bad_type/bad_ope.uss diff --git a/dsl2/src/test/resources/parsing/bad_type/bad_ope_2.uss b/dsl2/src/test/resources/parsing_old/bad_type/bad_ope_2.uss similarity index 100% rename from dsl2/src/test/resources/parsing/bad_type/bad_ope_2.uss rename to dsl2/src/test/resources/parsing_old/bad_type/bad_ope_2.uss diff --git a/dsl2/src/test/resources/parsing/bad_type/bad_ope_3.uss b/dsl2/src/test/resources/parsing_old/bad_type/bad_ope_3.uss similarity index 100% rename from dsl2/src/test/resources/parsing/bad_type/bad_ope_3.uss rename to dsl2/src/test/resources/parsing_old/bad_type/bad_ope_3.uss diff --git a/dsl2/src/test/resources/parsing/bad_type/increment_type.uss b/dsl2/src/test/resources/parsing_old/bad_type/increment_type.uss similarity index 100% rename from dsl2/src/test/resources/parsing/bad_type/increment_type.uss rename to dsl2/src/test/resources/parsing_old/bad_type/increment_type.uss diff --git a/dsl2/src/test/resources/parsing/bad_type/redefine_difftype.uss b/dsl2/src/test/resources/parsing_old/bad_type/redefine_difftype.uss similarity index 100% rename from dsl2/src/test/resources/parsing/bad_type/redefine_difftype.uss rename to dsl2/src/test/resources/parsing_old/bad_type/redefine_difftype.uss diff --git a/dsl2/src/test/resources/parsing/bad_type/stop_type.uss b/dsl2/src/test/resources/parsing_old/bad_type/stop_type.uss similarity index 100% rename from dsl2/src/test/resources/parsing/bad_type/stop_type.uss rename to dsl2/src/test/resources/parsing_old/bad_type/stop_type.uss diff --git a/dsl2/src/test/resources/parsing/corrects/blocks/for.uss b/dsl2/src/test/resources/parsing_old/corrects/blocks/for.uss similarity index 100% rename from dsl2/src/test/resources/parsing/corrects/blocks/for.uss rename to dsl2/src/test/resources/parsing_old/corrects/blocks/for.uss diff --git a/dsl2/src/test/resources/parsing/corrects/blocks/for_break.uss b/dsl2/src/test/resources/parsing_old/corrects/blocks/for_break.uss similarity index 100% rename from dsl2/src/test/resources/parsing/corrects/blocks/for_break.uss rename to dsl2/src/test/resources/parsing_old/corrects/blocks/for_break.uss diff --git a/dsl2/src/test/resources/parsing/corrects/blocks/foreach.uss b/dsl2/src/test/resources/parsing_old/corrects/blocks/foreach.uss similarity index 100% rename from dsl2/src/test/resources/parsing/corrects/blocks/foreach.uss rename to dsl2/src/test/resources/parsing_old/corrects/blocks/foreach.uss diff --git a/dsl2/src/test/resources/parsing/corrects/blocks/ifelse_p1.uss b/dsl2/src/test/resources/parsing_old/corrects/blocks/ifelse_p1.uss similarity index 100% rename from dsl2/src/test/resources/parsing/corrects/blocks/ifelse_p1.uss rename to dsl2/src/test/resources/parsing_old/corrects/blocks/ifelse_p1.uss diff --git a/dsl2/src/test/resources/parsing/corrects/blocks/ifelse_p2.uss b/dsl2/src/test/resources/parsing_old/corrects/blocks/ifelse_p2.uss similarity index 100% rename from dsl2/src/test/resources/parsing/corrects/blocks/ifelse_p2.uss rename to dsl2/src/test/resources/parsing_old/corrects/blocks/ifelse_p2.uss diff --git a/dsl2/src/test/resources/parsing/corrects/blocks/repeat.uss b/dsl2/src/test/resources/parsing_old/corrects/blocks/repeat.uss similarity index 100% rename from dsl2/src/test/resources/parsing/corrects/blocks/repeat.uss rename to dsl2/src/test/resources/parsing_old/corrects/blocks/repeat.uss diff --git a/dsl2/src/test/resources/parsing/corrects/blocks/repeat_2.uss b/dsl2/src/test/resources/parsing_old/corrects/blocks/repeat_2.uss similarity index 100% rename from dsl2/src/test/resources/parsing/corrects/blocks/repeat_2.uss rename to dsl2/src/test/resources/parsing_old/corrects/blocks/repeat_2.uss diff --git a/dsl2/src/test/resources/parsing/corrects/blocks/run_later.uss b/dsl2/src/test/resources/parsing_old/corrects/blocks/run_later.uss similarity index 100% rename from dsl2/src/test/resources/parsing/corrects/blocks/run_later.uss rename to dsl2/src/test/resources/parsing_old/corrects/blocks/run_later.uss diff --git a/dsl2/src/test/resources/parsing/corrects/blocks/while.uss b/dsl2/src/test/resources/parsing_old/corrects/blocks/while.uss similarity index 100% rename from dsl2/src/test/resources/parsing/corrects/blocks/while.uss rename to dsl2/src/test/resources/parsing_old/corrects/blocks/while.uss diff --git a/dsl2/src/test/resources/parsing/corrects/metadata/param_metadata.uss b/dsl2/src/test/resources/parsing_old/corrects/metadata/param_metadata.uss similarity index 100% rename from dsl2/src/test/resources/parsing/corrects/metadata/param_metadata.uss rename to dsl2/src/test/resources/parsing_old/corrects/metadata/param_metadata.uss diff --git a/dsl2/src/test/resources/parsing/corrects/mix/cercle.uss b/dsl2/src/test/resources/parsing_old/corrects/mix/cercle.uss similarity index 100% rename from dsl2/src/test/resources/parsing/corrects/mix/cercle.uss rename to dsl2/src/test/resources/parsing_old/corrects/mix/cercle.uss diff --git a/dsl2/src/test/resources/parsing/corrects/mix/collections.uss b/dsl2/src/test/resources/parsing_old/corrects/mix/collections.uss similarity index 100% rename from dsl2/src/test/resources/parsing/corrects/mix/collections.uss rename to dsl2/src/test/resources/parsing_old/corrects/mix/collections.uss diff --git a/dsl2/src/test/resources/parsing/corrects/mix/empty.uss b/dsl2/src/test/resources/parsing_old/corrects/mix/empty.uss similarity index 100% rename from dsl2/src/test/resources/parsing/corrects/mix/empty.uss rename to dsl2/src/test/resources/parsing_old/corrects/mix/empty.uss diff --git a/dsl2/src/test/resources/parsing/corrects/mix/implicit_define.uss b/dsl2/src/test/resources/parsing_old/corrects/mix/implicit_define.uss similarity index 100% rename from dsl2/src/test/resources/parsing/corrects/mix/implicit_define.uss rename to dsl2/src/test/resources/parsing_old/corrects/mix/implicit_define.uss diff --git a/dsl2/src/test/resources/parsing/corrects/mix/metadata.uss b/dsl2/src/test/resources/parsing_old/corrects/mix/metadata.uss similarity index 100% rename from dsl2/src/test/resources/parsing/corrects/mix/metadata.uss rename to dsl2/src/test/resources/parsing_old/corrects/mix/metadata.uss diff --git a/dsl2/src/test/resources/parsing/corrects/mix/null_recovery.uss b/dsl2/src/test/resources/parsing_old/corrects/mix/null_recovery.uss similarity index 100% rename from dsl2/src/test/resources/parsing/corrects/mix/null_recovery.uss rename to dsl2/src/test/resources/parsing_old/corrects/mix/null_recovery.uss diff --git a/dsl2/src/test/resources/parsing/corrects/mix/null_set.uss b/dsl2/src/test/resources/parsing_old/corrects/mix/null_set.uss similarity index 100% rename from dsl2/src/test/resources/parsing/corrects/mix/null_set.uss rename to dsl2/src/test/resources/parsing_old/corrects/mix/null_set.uss diff --git a/dsl2/src/test/resources/parsing/corrects/mix/particle_shape.uss b/dsl2/src/test/resources/parsing_old/corrects/mix/particle_shape.uss similarity index 100% rename from dsl2/src/test/resources/parsing/corrects/mix/particle_shape.uss rename to dsl2/src/test/resources/parsing_old/corrects/mix/particle_shape.uss diff --git a/dsl2/src/test/resources/parsing/corrects/mix/test_allof.uss b/dsl2/src/test/resources/parsing_old/corrects/mix/test_allof.uss similarity index 100% rename from dsl2/src/test/resources/parsing/corrects/mix/test_allof.uss rename to dsl2/src/test/resources/parsing_old/corrects/mix/test_allof.uss diff --git a/dsl2/src/test/resources/parsing/corrects/mix/test_basic.uss b/dsl2/src/test/resources/parsing_old/corrects/mix/test_basic.uss similarity index 100% rename from dsl2/src/test/resources/parsing/corrects/mix/test_basic.uss rename to dsl2/src/test/resources/parsing_old/corrects/mix/test_basic.uss diff --git a/dsl2/src/test/resources/parsing/corrects/mix/test_complex_tp.uss b/dsl2/src/test/resources/parsing_old/corrects/mix/test_complex_tp.uss similarity index 100% rename from dsl2/src/test/resources/parsing/corrects/mix/test_complex_tp.uss rename to dsl2/src/test/resources/parsing_old/corrects/mix/test_complex_tp.uss diff --git a/dsl2/src/test/resources/parsing/corrects/mix/test_location_literal.uss b/dsl2/src/test/resources/parsing_old/corrects/mix/test_location_literal.uss similarity index 100% rename from dsl2/src/test/resources/parsing/corrects/mix/test_location_literal.uss rename to dsl2/src/test/resources/parsing_old/corrects/mix/test_location_literal.uss diff --git a/dsl2/src/test/resources/parsing/corrects/mix/test_null.uss b/dsl2/src/test/resources/parsing_old/corrects/mix/test_null.uss similarity index 100% rename from dsl2/src/test/resources/parsing/corrects/mix/test_null.uss rename to dsl2/src/test/resources/parsing_old/corrects/mix/test_null.uss diff --git a/dsl2/src/test/resources/parsing/corrects/mix/test_teleport.uss b/dsl2/src/test/resources/parsing_old/corrects/mix/test_teleport.uss similarity index 100% rename from dsl2/src/test/resources/parsing/corrects/mix/test_teleport.uss rename to dsl2/src/test/resources/parsing_old/corrects/mix/test_teleport.uss diff --git a/dsl2/src/test/resources/parsing/corrects/operators/bool_operators.uss b/dsl2/src/test/resources/parsing_old/corrects/operators/bool_operators.uss similarity index 100% rename from dsl2/src/test/resources/parsing/corrects/operators/bool_operators.uss rename to dsl2/src/test/resources/parsing_old/corrects/operators/bool_operators.uss diff --git a/dsl2/src/test/resources/parsing/corrects/operators/conditions.uss b/dsl2/src/test/resources/parsing_old/corrects/operators/conditions.uss similarity index 100% rename from dsl2/src/test/resources/parsing/corrects/operators/conditions.uss rename to dsl2/src/test/resources/parsing_old/corrects/operators/conditions.uss diff --git a/dsl2/src/test/resources/parsing/corrects/operators/list_append.uss b/dsl2/src/test/resources/parsing_old/corrects/operators/list_append.uss similarity index 100% rename from dsl2/src/test/resources/parsing/corrects/operators/list_append.uss rename to dsl2/src/test/resources/parsing_old/corrects/operators/list_append.uss diff --git a/dsl2/src/test/resources/parsing/corrects/operators/math.uss b/dsl2/src/test/resources/parsing_old/corrects/operators/math.uss similarity index 100% rename from dsl2/src/test/resources/parsing/corrects/operators/math.uss rename to dsl2/src/test/resources/parsing_old/corrects/operators/math.uss diff --git a/dsl2/src/test/resources/parsing/corrects/operators/operator_priority.uss b/dsl2/src/test/resources/parsing_old/corrects/operators/operator_priority.uss similarity index 100% rename from dsl2/src/test/resources/parsing/corrects/operators/operator_priority.uss rename to dsl2/src/test/resources/parsing_old/corrects/operators/operator_priority.uss diff --git a/dsl2/src/test/resources/parsing/corrects/operators/parenthesis.uss b/dsl2/src/test/resources/parsing_old/corrects/operators/parenthesis.uss similarity index 100% rename from dsl2/src/test/resources/parsing/corrects/operators/parenthesis.uss rename to dsl2/src/test/resources/parsing_old/corrects/operators/parenthesis.uss diff --git a/dsl2/src/test/resources/parsing/corrects/operators/type_operators.uss b/dsl2/src/test/resources/parsing_old/corrects/operators/type_operators.uss similarity index 100% rename from dsl2/src/test/resources/parsing/corrects/operators/type_operators.uss rename to dsl2/src/test/resources/parsing_old/corrects/operators/type_operators.uss diff --git a/dsl2/src/test/resources/parsing/corrects/statements/define.uss b/dsl2/src/test/resources/parsing_old/corrects/statements/define.uss similarity index 100% rename from dsl2/src/test/resources/parsing/corrects/statements/define.uss rename to dsl2/src/test/resources/parsing_old/corrects/statements/define.uss diff --git a/dsl2/src/test/resources/parsing/corrects/statements/give.uss b/dsl2/src/test/resources/parsing_old/corrects/statements/give.uss similarity index 100% rename from dsl2/src/test/resources/parsing/corrects/statements/give.uss rename to dsl2/src/test/resources/parsing_old/corrects/statements/give.uss diff --git a/dsl2/src/test/resources/parsing/corrects/statements/increment.uss b/dsl2/src/test/resources/parsing_old/corrects/statements/increment.uss similarity index 100% rename from dsl2/src/test/resources/parsing/corrects/statements/increment.uss rename to dsl2/src/test/resources/parsing_old/corrects/statements/increment.uss diff --git a/dsl2/src/test/resources/parsing/corrects/statements/play.uss b/dsl2/src/test/resources/parsing_old/corrects/statements/play.uss similarity index 100% rename from dsl2/src/test/resources/parsing/corrects/statements/play.uss rename to dsl2/src/test/resources/parsing_old/corrects/statements/play.uss diff --git a/dsl2/src/test/resources/parsing/corrects/statements/send.uss b/dsl2/src/test/resources/parsing_old/corrects/statements/send.uss similarity index 100% rename from dsl2/src/test/resources/parsing/corrects/statements/send.uss rename to dsl2/src/test/resources/parsing_old/corrects/statements/send.uss diff --git a/dsl2/src/test/resources/parsing/corrects/statements/send_nbt.uss b/dsl2/src/test/resources/parsing_old/corrects/statements/send_nbt.uss similarity index 100% rename from dsl2/src/test/resources/parsing/corrects/statements/send_nbt.uss rename to dsl2/src/test/resources/parsing_old/corrects/statements/send_nbt.uss diff --git a/dsl2/src/test/resources/parsing/corrects/statements/stop_1.uss b/dsl2/src/test/resources/parsing_old/corrects/statements/stop_1.uss similarity index 100% rename from dsl2/src/test/resources/parsing/corrects/statements/stop_1.uss rename to dsl2/src/test/resources/parsing_old/corrects/statements/stop_1.uss diff --git a/dsl2/src/test/resources/parsing/corrects/statements/stop_2.uss b/dsl2/src/test/resources/parsing_old/corrects/statements/stop_2.uss similarity index 100% rename from dsl2/src/test/resources/parsing/corrects/statements/stop_2.uss rename to dsl2/src/test/resources/parsing_old/corrects/statements/stop_2.uss diff --git a/dsl2/src/test/resources/parsing/corrects/statements/stop_3.uss b/dsl2/src/test/resources/parsing_old/corrects/statements/stop_3.uss similarity index 100% rename from dsl2/src/test/resources/parsing/corrects/statements/stop_3.uss rename to dsl2/src/test/resources/parsing_old/corrects/statements/stop_3.uss diff --git a/dsl2/src/test/resources/parsing/corrects/statements/summon.uss b/dsl2/src/test/resources/parsing_old/corrects/statements/summon.uss similarity index 100% rename from dsl2/src/test/resources/parsing/corrects/statements/summon.uss rename to dsl2/src/test/resources/parsing_old/corrects/statements/summon.uss diff --git a/dsl2/src/test/resources/parsing/corrects/statements/teleport.uss b/dsl2/src/test/resources/parsing_old/corrects/statements/teleport.uss similarity index 100% rename from dsl2/src/test/resources/parsing/corrects/statements/teleport.uss rename to dsl2/src/test/resources/parsing_old/corrects/statements/teleport.uss diff --git a/dsl2/src/test/resources/parsing/corrects_with_custom/callback.uss b/dsl2/src/test/resources/parsing_old/corrects_with_custom/callback.uss similarity index 100% rename from dsl2/src/test/resources/parsing/corrects_with_custom/callback.uss rename to dsl2/src/test/resources/parsing_old/corrects_with_custom/callback.uss diff --git a/dsl2/src/test/resources/parsing/corrects_with_custom/custom.uss b/dsl2/src/test/resources/parsing_old/corrects_with_custom/custom.uss similarity index 100% rename from dsl2/src/test/resources/parsing/corrects_with_custom/custom.uss rename to dsl2/src/test/resources/parsing_old/corrects_with_custom/custom.uss From 7a474b14593eb58954e3efc7d37a8090140564dd Mon Sep 17 00:00:00 2001 From: "timothe.rosaz" Date: Thu, 23 Oct 2025 13:11:48 +0200 Subject: [PATCH 09/38] map and array literal parsing --- .../dsl2/nodes/ExpressionNode.java | 2 +- .../ArrayLiteral.java} | 18 +++++++----------- .../expressions/litteral/LocationLiteral.java | 2 +- .../nodes/expressions/litteral/MapLiteral.java | 5 ++--- .../expressions/litteral/NullExpression.java | 2 +- .../dsl2/visitor/ExpressionVisitor.java | 2 +- .../dsl2/visitor/PrintingVisitor.java | 15 +++++++++++++-- .../dsl2/CorrectParsingTests.java | 5 +++++ .../parsing/corrects/literals/array_empty.uss | 1 + .../parsing/corrects/literals/array_small.uss | 3 +++ .../parsing/corrects/literals/array_xl.uss | 5 +++++ .../parsing/corrects/literals/map_empty.uss | 1 + .../parsing/corrects/literals/map_small.uss | 4 ++++ .../parsing/corrects/literals/map_xl.uss | 7 +++++++ 14 files changed, 52 insertions(+), 20 deletions(-) rename dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/{ArrayExpression.java => litteral/ArrayLiteral.java} (80%) create mode 100644 dsl2/src/test/resources/parsing/corrects/literals/array_empty.uss create mode 100644 dsl2/src/test/resources/parsing/corrects/literals/array_small.uss create mode 100644 dsl2/src/test/resources/parsing/corrects/literals/array_xl.uss create mode 100644 dsl2/src/test/resources/parsing/corrects/literals/map_empty.uss create mode 100644 dsl2/src/test/resources/parsing/corrects/literals/map_small.uss create mode 100644 dsl2/src/test/resources/parsing/corrects/literals/map_xl.uss diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/ExpressionNode.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/ExpressionNode.java index 6333ddc0..2dfde460 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/ExpressionNode.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/ExpressionNode.java @@ -110,7 +110,7 @@ private static ExpressionNode readNextExpression(TokenStream tokens, MathParsing // Openers: '{', '[', '(' case BRACES_OPEN -> MapLiteral.parseMap(tokens); - case SQUARE_BRACKET_OPEN -> ArrayExpression.parseRawArray(tokens); + case SQUARE_BRACKET_OPEN -> ArrayLiteral.readNextArrayLiteral(tokens); case BRACKET_OPEN -> ParenthesisExpression.parseParenthesis(tokens); diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/ArrayExpression.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/ArrayLiteral.java similarity index 80% rename from dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/ArrayExpression.java rename to dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/ArrayLiteral.java index 30571655..de85dfdb 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/ArrayExpression.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/ArrayLiteral.java @@ -1,4 +1,4 @@ -package fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions; +package fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.litteral; import fr.jamailun.ultimatespellsystem.dsl2.errors.TypeException; import fr.jamailun.ultimatespellsystem.dsl2.nodes.ExpressionNode; @@ -16,7 +16,7 @@ /** * Raw array value. */ -public class ArrayExpression extends ExpressionNode { +public class ArrayLiteral extends ExpressionNode { @Getter private final List elements; @@ -24,7 +24,7 @@ public class ArrayExpression extends ExpressionNode { private Type selfType; private Type elementsType; - protected ArrayExpression(TokenPosition position, List elements) { + protected ArrayLiteral(TokenPosition position, List elements) { super(position); this.elements = elements; } @@ -68,23 +68,19 @@ public void validateTypes(@NotNull TypesContext contextParent) { } @PreviousIndicator(expected = TokenType.SQUARE_BRACKET_OPEN) - public static ArrayExpression parseRawArray(@NotNull TokenStream tokens) { + public static ArrayLiteral readNextArrayLiteral(@NotNull TokenStream tokens) { TokenPosition pos = tokens.position(); List nodes = new ArrayList<>(); boolean first = true; - while(tokens.hasMore()) { - Token peek = tokens.peek(); - if(peek.getType() == TokenType.SQUARE_BRACKET_CLOSE) - break; + while(!tokens.dropOptional(TokenType.SQUARE_BRACKET_CLOSE)) { if( ! first) { - tokens.dropOrThrow(TokenType.COMMA); + tokens.dropOrThrow(TokenType.COMMA, "Elements in array must be separated by a comma."); } first = false; ExpressionNode node = ExpressionNode.readNextExpression(tokens); nodes.add(node); } - tokens.dropOrThrow(TokenType.SQUARE_BRACKET_CLOSE); - return new ArrayExpression(pos, nodes); + return new ArrayLiteral(pos, nodes); } @Override diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/LocationLiteral.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/LocationLiteral.java index 90a35ae9..98fdbce9 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/LocationLiteral.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/LocationLiteral.java @@ -100,6 +100,6 @@ public void validateTypes(@NotNull TypesContext context) { @Override public String toString() { - return "Loc{"+world+", ("+vectorX+","+vectorY+","+vectorZ+")}"; + return "LOC<"+world+", ("+vectorX+","+vectorY+","+vectorZ+")>"; } } diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/MapLiteral.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/MapLiteral.java index ab1eb4de..0c290d6f 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/MapLiteral.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/MapLiteral.java @@ -38,7 +38,7 @@ public void visit(@NotNull ExpressionVisitor visitor) { @Override public String toString() { - return "{" + expressions + "}"; + return "MAP" + PREFIX + expressions + SUFFIX; } @Override @@ -58,7 +58,7 @@ public static MapLiteral parseMap(TokenStream tokens) { TokenPosition pos = tokens.position(); Map expressions = new HashMap<>(); while(tokens.hasMore()) { - if(tokens.peek().getType() == TokenType.BRACKET_CLOSE) { + if(tokens.dropOptional(TokenType.BRACES_CLOSE)) { // EOP break; } @@ -82,7 +82,6 @@ public static MapLiteral parseMap(TokenStream tokens) { // build expressions.put(propKey, value); } - tokens.dropOrThrow(TokenType.BRACKET_CLOSE); return new MapLiteral(pos, expressions); } } diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/NullExpression.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/NullExpression.java index 4a40e3cb..fa3e48b6 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/NullExpression.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/NullExpression.java @@ -29,7 +29,7 @@ public NullExpression(@NotNull TokenPosition pos) { @Override public String toString() { - return "NULL"; + return PREFIX + "NULL" + SUFFIX; } @Override diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/ExpressionVisitor.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/ExpressionVisitor.java index 5cd82394..0ce9cb50 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/ExpressionVisitor.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/ExpressionVisitor.java @@ -29,7 +29,7 @@ public interface ExpressionVisitor { void handleFunctionCall(@NotNull FunctionCallExpression functionCall); // Specifics - void handleArray(@NotNull ArrayExpression expression); + void handleArray(@NotNull ArrayLiteral expression); void handleVariable(@NotNull ReferenceExpression expression); } diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/PrintingVisitor.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/PrintingVisitor.java index 65a572b1..300c33c9 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/PrintingVisitor.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/PrintingVisitor.java @@ -255,7 +255,18 @@ public void handleStringLiteral(@NotNull StringExpression literal) { @Override public void handleMapLiteral(@NotNull MapLiteral literal) { - //TODO + builder.append("{"); + right(); + boolean first = true; + for(var entry : literal.getExpressions().entrySet()) { + if(first) first = false; else builder.append(","); + builder.append("\n").append(indent()).append(entry.getKey()).append(" : "); + entry.getValue().visit(this); + } + left(); + if(!literal.getExpressions().isEmpty()) + builder.append("\n").append(indent()); + builder.append("}"); } @Override @@ -350,7 +361,7 @@ public void handleFunctionCall(@NotNull FunctionCallExpression functionCall) { } @Override - public void handleArray(@NotNull ArrayExpression expression) { + public void handleArray(@NotNull ArrayLiteral expression) { builder.append("["); boolean first = true; for(ExpressionNode child : expression.getElements()) { diff --git a/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/CorrectParsingTests.java b/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/CorrectParsingTests.java index 3da0081d..b4302e03 100644 --- a/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/CorrectParsingTests.java +++ b/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/CorrectParsingTests.java @@ -21,6 +21,11 @@ void correctLoops() { testFolder("corrects/loops"); } + @Test + void correctLiterals() { + testFolder("corrects/literals"); + } + // -- private void testFolder(@NotNull String folder) { diff --git a/dsl2/src/test/resources/parsing/corrects/literals/array_empty.uss b/dsl2/src/test/resources/parsing/corrects/literals/array_empty.uss new file mode 100644 index 00000000..a3227adb --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/literals/array_empty.uss @@ -0,0 +1 @@ +var arr = []; \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing/corrects/literals/array_small.uss b/dsl2/src/test/resources/parsing/corrects/literals/array_small.uss new file mode 100644 index 00000000..ef076cc6 --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/literals/array_small.uss @@ -0,0 +1,3 @@ +var arr = [ + "a", "b", "c" +]; \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing/corrects/literals/array_xl.uss b/dsl2/src/test/resources/parsing/corrects/literals/array_xl.uss new file mode 100644 index 00000000..7305088c --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/literals/array_xl.uss @@ -0,0 +1,5 @@ +var arr = [ + ["a", "b", "c"], + ["d", "e", "f"], + ["g", "h", "i"] +]; \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing/corrects/literals/map_empty.uss b/dsl2/src/test/resources/parsing/corrects/literals/map_empty.uss new file mode 100644 index 00000000..8ee707c5 --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/literals/map_empty.uss @@ -0,0 +1 @@ +var map = { }; \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing/corrects/literals/map_small.uss b/dsl2/src/test/resources/parsing/corrects/literals/map_small.uss new file mode 100644 index 00000000..52e2c88b --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/literals/map_small.uss @@ -0,0 +1,4 @@ +var map = { + foo: "foo", + bar: "bar" +}; \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing/corrects/literals/map_xl.uss b/dsl2/src/test/resources/parsing/corrects/literals/map_xl.uss new file mode 100644 index 00000000..ace172bb --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/literals/map_xl.uss @@ -0,0 +1,7 @@ +var map = { + foo: "foo", + bar: "bar", + intra: { + val: 23 + } +}; \ No newline at end of file From 2e1e5c92462539fda908d766517b9a4c5a007f60 Mon Sep 17 00:00:00 2001 From: "timothe.rosaz" Date: Thu, 23 Oct 2025 16:37:17 +0200 Subject: [PATCH 10/38] renamed some elements --- ...mDSL.java => UltimateSpellSystemDSL2.java} | 4 +- .../ultimatespellsystem/dsl2/ast/AST.java | 37 +++++ .../dsl2/ast/ASTOptimizer.java | 40 +++++ .../dsl2/ast/ConstantFoldingOptimizer.java | 147 ++++++++++++++++++ .../dsl2/nodes/ExpressionNode.java | 12 +- ...eanExpression.java => BooleanLiteral.java} | 4 +- ...onExpression.java => DurationLiteral.java} | 4 +- .../{NullExpression.java => NullLiteral.java} | 4 +- ...mberExpression.java => NumberLiteral.java} | 10 +- ...ringExpression.java => StringLiteral.java} | 4 +- .../expressions/operators/BiOperator.java | 8 +- .../expressions/operators/MonoOperator.java | 19 +-- .../nodes/expressions/operators/Operator.java | 1 - .../dsl2/visitor/ExpressionVisitor.java | 10 +- .../dsl2/visitor/PrintingVisitor.java | 14 +- .../ultimatespellsystem/dsl2/ParsingTest.java | 2 +- 16 files changed, 259 insertions(+), 61 deletions(-) rename dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/{UltimateSpellSystemDSL.java => UltimateSpellSystemDSL2.java} (96%) create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/ast/AST.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/ast/ASTOptimizer.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/ast/ConstantFoldingOptimizer.java rename dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/{BooleanExpression.java => BooleanLiteral.java} (89%) rename dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/{DurationExpression.java => DurationLiteral.java} (90%) rename dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/{NullExpression.java => NullLiteral.java} (88%) rename dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/{NumberExpression.java => NumberLiteral.java} (82%) rename dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/{StringExpression.java => StringLiteral.java} (89%) diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/UltimateSpellSystemDSL.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/UltimateSpellSystemDSL2.java similarity index 96% rename from dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/UltimateSpellSystemDSL.java rename to dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/UltimateSpellSystemDSL2.java index 26c0f7e5..5a9202db 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/UltimateSpellSystemDSL.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/UltimateSpellSystemDSL2.java @@ -16,8 +16,8 @@ /** * Central access to the DSL. */ -public final class UltimateSpellSystemDSL { - private UltimateSpellSystemDSL() {} +public final class UltimateSpellSystemDSL2 { + private UltimateSpellSystemDSL2() {} // Load the default metadata rules on class load. static { diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/ast/AST.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/ast/AST.java new file mode 100644 index 00000000..726061ee --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/ast/AST.java @@ -0,0 +1,37 @@ +package fr.jamailun.ultimatespellsystem.dsl2.ast; + +import fr.jamailun.ultimatespellsystem.dsl2.nodes.StatementNode; +import org.jetbrains.annotations.NotNull; + +import java.util.*; + +public class AST implements Iterable { + + private final List statements; + + /** + * Create a copy of a statements in the AST. + * @param statements a collection to copy. + */ + public AST(@NotNull SequencedCollection statements) { + this.statements = new ArrayList<>(statements); + } + + /** + * Get a mutable copy of the statements. + * @return a mutable list. + */ + public @NotNull List getStatements() { + return new ArrayList<>(statements); + } + + @Override + public @NotNull Iterator iterator() { + return statements.listIterator(); + } + + @Override + public Spliterator spliterator() { + return statements.spliterator(); + } +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/ast/ASTOptimizer.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/ast/ASTOptimizer.java new file mode 100644 index 00000000..b76f3dc1 --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/ast/ASTOptimizer.java @@ -0,0 +1,40 @@ +package fr.jamailun.ultimatespellsystem.dsl2.ast; + +import fr.jamailun.ultimatespellsystem.dsl2.nodes.StatementNode; +import org.jetbrains.annotations.NotNull; + +import java.util.Iterator; +import java.util.List; + +/** + * Stateful optimizer + */ +public abstract class ASTOptimizer { + + /** + * Optimize a single statement. + * @param statement statement to optimize. + */ + public abstract void optimize(@NotNull StatementNode statement); + + /** + * DO a full optimization of the AST. + * @param ast tree to optimize. + */ + public final void optimize(@NotNull AST ast) { + preOptimize(); + for(StatementNode statement : ast) { + optimize(statement); + } + postOptimize(); + } + + protected void preOptimize() { + // Rien + } + + protected void postOptimize() { + // Rien + } + +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/ast/ConstantFoldingOptimizer.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/ast/ConstantFoldingOptimizer.java new file mode 100644 index 00000000..008c07f4 --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/ast/ConstantFoldingOptimizer.java @@ -0,0 +1,147 @@ +package fr.jamailun.ultimatespellsystem.dsl2.ast; + +import fr.jamailun.ultimatespellsystem.dsl2.nodes.ExpressionNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.StatementNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.ParenthesisExpression; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.litteral.*; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.operators.BiOperator; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.operators.MonoOperator; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.operators.Operator; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.statements.*; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.statements.blocks.ForLoopStatement; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.statements.blocks.IfElseStatement; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.statements.blocks.WhileLoopStatement; +import fr.jamailun.ultimatespellsystem.dsl2.visitor.StatementVisitor; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +/** + * Fold constants in the AST. + */ +public class ConstantFoldingOptimizer extends ASTOptimizer implements StatementVisitor { + + @Override + public void optimize(@NotNull StatementNode statement) { + statement.visit(this); + } + + private void foldConstants(@Nullable ExpressionNode expression) { + + } + + private @Nullable Double foldConstants(@Nullable BiOperator biOperator) { + if(biOperator == null) { + return null; + } + //TODO ! + throw new UnsupportedOperationException("todo"); + } + + private @Nullable Double foldNumericConstants(@Nullable ExpressionNode expression) { + return switch (expression) { + case MapLiteral mapLiteral -> { + mapLiteral.getExpressions().values().forEach(this::foldNumericConstants); + yield null; + } + case ArrayLiteral arrayLiteral -> { + arrayLiteral.getElements().forEach(this::foldNumericConstants); + yield null; + } + case ParenthesisExpression pe -> foldNumericConstants(pe.getExpression()); + case NumberLiteral n -> n.getRaw(); + case BiOperator biOp -> { + Double left = foldNumericConstants(biOp.getLeft()); + Double right = foldNumericConstants(biOp.getRight()); + if(left != null && right != null) { + + } + yield null; + } + case null, default -> null; + }; + } + + private boolean isConstant(@Nullable ExpressionNode expression) { + return switch (expression) { + case MapLiteral mapLiteral -> mapLiteral.getExpressions().values().stream().allMatch(this::isConstant); + case ArrayLiteral arrayLiteral -> arrayLiteral.getElements().stream().allMatch(this::isConstant); + case LiteralExpression ignored -> true; + case LocationLiteral locLiteral -> + isConstant(locLiteral.getVectorX()) && + isConstant(locLiteral.getVectorY()) && + isConstant(locLiteral.getVectorZ()) && + isConstant(locLiteral.getWorld()) && + isConstant(locLiteral.getPitch()) && + isConstant(locLiteral.getYaw()); + case BiOperator biOp -> isConstant(biOp.getLeft()) && isConstant(biOp.getRight()); + case MonoOperator monoOp -> isConstant(monoOp.getChild()); + case ParenthesisExpression pe -> isConstant(pe.getExpression()); + case null, default -> false; + }; + } + + // -- visitor + + @Override + public void handleDeclareVariable(@NotNull DeclareNewVariableStatement statement) { + if(statement.getExpression() != null) { + + } + } + + @Override + public void handleAffectVariable(@NotNull AffectationStatement statement) { + statement.getExpression(); + } + + @Override + public void handleReturn(@NotNull ReturnStatement statement) { + if(statement.getExitCodeNode() != null) { + + } + } + + @Override + public void handleBlock(@NotNull BlockStatement statement) { + statement.getChildren().forEach(this::optimize); + } + + @Override + public void handleSimpleExpression(@NotNull SimpleExpressionStatement statement) { + + } + + @Override + public void handleIf(@NotNull IfElseStatement statement) { + + } + + @Override + public void handleForLoop(@NotNull ForLoopStatement statement) { + + } + + @Override + public void handleWhileLoop(@NotNull WhileLoopStatement statement) { + + } + + // rien + + @Override + public void handleIncrement(@NotNull IncrementStatement statement) { + // rien + } + + @Override + public void handleFunctionDeclaration(@NotNull FunctionDeclarationStatement statement) { + // rien + } + + @Override + public void handleBreakContinue(@NotNull BreakContinueStatement statement) { + // rien + } +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/ExpressionNode.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/ExpressionNode.java index 2dfde460..f4d4079c 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/ExpressionNode.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/ExpressionNode.java @@ -91,15 +91,15 @@ private static ExpressionNode readNextExpression(TokenStream tokens, MathParsing case OPE_SUB -> { TokenPosition position = tokens.position(); ExpressionNode nextExpression = readNextExpression(tokens); - yield new SubOperator(position, new NumberExpression(position, 0), nextExpression); + yield new SubOperator(position, new NumberLiteral(position, 0), nextExpression); } // Literals - case VALUE_NUMBER -> new NumberExpression(token); - case VALUE_BOOLEAN -> new BooleanExpression(token); - case VALUE_STRING -> new StringExpression(token); - case VALUE_DURATION -> new DurationExpression(token); - case NULL -> new NullExpression(token.pos()); + case VALUE_NUMBER -> new NumberLiteral(token); + case VALUE_BOOLEAN -> new BooleanLiteral(token); + case VALUE_STRING -> new StringLiteral(token); + case VALUE_DURATION -> new DurationLiteral(token); + case NULL -> new NullLiteral(token.pos()); case CHAR_AT -> LocationLiteral.readNextLocation(tokens); diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/BooleanExpression.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/BooleanLiteral.java similarity index 89% rename from dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/BooleanExpression.java rename to dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/BooleanLiteral.java index 164d31e7..46e70525 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/BooleanExpression.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/BooleanLiteral.java @@ -9,7 +9,7 @@ /** * A raw boolean literal. */ -public class BooleanExpression extends LiteralExpression { +public class BooleanLiteral extends LiteralExpression { private final boolean rawValue; @@ -17,7 +17,7 @@ public class BooleanExpression extends LiteralExpression { * New instance, from a token. * @param token non-null token to use. */ - public BooleanExpression(@NotNull Token token) { + public BooleanLiteral(@NotNull Token token) { super(token.pos()); this.rawValue = token.getContentBoolean(); } diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/DurationExpression.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/DurationLiteral.java similarity index 90% rename from dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/DurationExpression.java rename to dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/DurationLiteral.java index b2fa8156..fcb207e3 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/DurationExpression.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/DurationLiteral.java @@ -10,7 +10,7 @@ /** * A raw {@link Duration} literal. */ -public class DurationExpression extends LiteralExpression { +public class DurationLiteral extends LiteralExpression { private final Duration duration; @@ -18,7 +18,7 @@ public class DurationExpression extends LiteralExpression { * New instance, from a token. * @param token token to use. */ - public DurationExpression(@NotNull Token token) { + public DurationLiteral(@NotNull Token token) { super(token.pos()); this.duration = new Duration(token.getContentNumber(), token.getContentTimeUnit()); } diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/NullExpression.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/NullLiteral.java similarity index 88% rename from dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/NullExpression.java rename to dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/NullLiteral.java index fa3e48b6..8af74106 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/NullExpression.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/NullLiteral.java @@ -9,13 +9,13 @@ /** * The {@code NULL} representation. */ -public class NullExpression extends LiteralExpression { +public class NullLiteral extends LiteralExpression { /** * New instance. * @param pos position of the keyword. */ - public NullExpression(@NotNull TokenPosition pos) { + public NullLiteral(@NotNull TokenPosition pos) { super(pos); } diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/NumberExpression.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/NumberLiteral.java similarity index 82% rename from dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/NumberExpression.java rename to dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/NumberLiteral.java index 5916e6f0..eb86a3ae 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/NumberExpression.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/NumberLiteral.java @@ -10,15 +10,15 @@ /** * A raw number literal. */ -public class NumberExpression extends LiteralExpression { +public class NumberLiteral extends LiteralExpression { - private final Double rawValue; + private final double rawValue; /** * New literal, using a token. * @param token token to use. */ - public NumberExpression(@NotNull Token token) { + public NumberLiteral(@NotNull Token token) { super(token.pos()); this.rawValue = token.getContentNumber(); } @@ -28,13 +28,13 @@ public NumberExpression(@NotNull Token token) { * @param position position of the token. * @param number value. */ - public NumberExpression(@NotNull TokenPosition position, double number) { + public NumberLiteral(@NotNull TokenPosition position, double number) { super(position); this.rawValue = number; } @Override - public Double getRaw() { + public @NotNull Double getRaw() { return rawValue; } diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/StringExpression.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/StringLiteral.java similarity index 89% rename from dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/StringExpression.java rename to dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/StringLiteral.java index 40015b47..f87af22e 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/StringExpression.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/StringLiteral.java @@ -9,7 +9,7 @@ /** * A raw string literal. */ -public class StringExpression extends LiteralExpression { +public class StringLiteral extends LiteralExpression { private final String rawValue; @@ -17,7 +17,7 @@ public class StringExpression extends LiteralExpression { * New raw string. * @param token token to use. */ - public StringExpression(@NotNull Token token) { + public StringLiteral(@NotNull Token token) { super(token.pos()); this.rawValue = token.getContentString(); } diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/BiOperator.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/BiOperator.java index 9a1bae2a..44c8689f 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/BiOperator.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/BiOperator.java @@ -94,14 +94,8 @@ public enum BiOpeType { LESSER, AND, - OR, + OR - // List - - LIST_ADD, - LIST_REM, - LIST_REM_INDEX, - LIST_CONTAINS } } diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/MonoOperator.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/MonoOperator.java index c7ab96dd..03a7e1cb 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/MonoOperator.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/MonoOperator.java @@ -16,7 +16,7 @@ * Mono-operator, on a single expression. */ @Getter -public abstract class MonoOperator extends ExpressionNode { +public abstract class MonoOperator extends Operator { protected final ExpressionNode child; @@ -50,22 +50,7 @@ public final void validateTypes(@NotNull TypesContext context) { public abstract void validateTypes(@NotNull Type childType); public enum MonoOpeType { - NOT(x -> x), - SIN(x -> Math.sin(x.doubleValue())), - COS(x -> Math.cos(x.doubleValue())), - TAN(x -> Math.tan(x.doubleValue())), - SQRT(x -> Math.sqrt(x.doubleValue())), - ABS(x -> x instanceof Integer || x instanceof Long || x instanceof Short || x instanceof Byte ? Math.abs(x.longValue()) : Math.abs(x.doubleValue())), - ; - public final Function function; - MonoOpeType(Function function) { - this.function = function; - } - public static @Nullable MonoOpeType find(@NotNull String value) { - return Arrays.stream(values()) - .filter(v -> v.name().equalsIgnoreCase(value)) - .findAny().orElse(null); - } + NOT; } } diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/Operator.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/Operator.java index c5236a23..37e06ee2 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/Operator.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/Operator.java @@ -1,6 +1,5 @@ package fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.operators; -import fr.jamailun.ultimatespellsystem.dsl2.errors.TypeException; import fr.jamailun.ultimatespellsystem.dsl2.nodes.ExpressionNode; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenPosition; diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/ExpressionVisitor.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/ExpressionVisitor.java index 0ce9cb50..333f97bc 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/ExpressionVisitor.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/ExpressionVisitor.java @@ -12,12 +12,12 @@ public interface ExpressionVisitor { // Literals - void handleNullLiteral(@NotNull NullExpression literal); - void handleBooleanLiteral(@NotNull BooleanExpression literal); - void handleNumberLiteral(@NotNull NumberExpression literal); - void handleStringLiteral(@NotNull StringExpression literal); + void handleNullLiteral(@NotNull NullLiteral literal); + void handleBooleanLiteral(@NotNull BooleanLiteral literal); + void handleNumberLiteral(@NotNull NumberLiteral literal); + void handleStringLiteral(@NotNull StringLiteral literal); void handleMapLiteral(@NotNull MapLiteral literal); - void handleDurationLiteral(@NotNull DurationExpression literal); + void handleDurationLiteral(@NotNull DurationLiteral literal); void handleLocationLiteral(@NotNull LocationLiteral literal); // Operators-ish diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/PrintingVisitor.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/PrintingVisitor.java index 300c33c9..37fbbc11 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/PrintingVisitor.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/PrintingVisitor.java @@ -233,23 +233,23 @@ public void handleBreakContinue(@NotNull BreakContinueStatement statement) { } @Override - public void handleNullLiteral(@NotNull NullExpression literal) { + public void handleNullLiteral(@NotNull NullLiteral literal) { builder.append("NULL"); } @Override - public void handleBooleanLiteral(@NotNull BooleanExpression literal) { + public void handleBooleanLiteral(@NotNull BooleanLiteral literal) { builder.append(literal.getRaw()); } @Override - public void handleNumberLiteral(@NotNull NumberExpression literal) { + public void handleNumberLiteral(@NotNull NumberLiteral literal) { double num = literal.getRaw(); builder.append(formatNumber.format(num)); } @Override - public void handleStringLiteral(@NotNull StringExpression literal) { + public void handleStringLiteral(@NotNull StringLiteral literal) { builder.append("\"").append(literal.getRaw()).append("\""); } @@ -270,7 +270,7 @@ public void handleMapLiteral(@NotNull MapLiteral literal) { } @Override - public void handleDurationLiteral(@NotNull DurationExpression literal) { + public void handleDurationLiteral(@NotNull DurationLiteral literal) { Duration duration = literal.getRaw(); builder.append(formatNumber.format(duration.amount())) .append(" ") @@ -309,10 +309,6 @@ public void handleBiOperator(@NotNull BiOperator operator) { case LESSER -> "<"; case AND -> "and"; case OR -> "or"; - case LIST_ADD -> "append"; - case LIST_REM -> "remove"; - case LIST_CONTAINS -> "contains"; - case LIST_REM_INDEX -> "remove_idx"; }; builder.append(" ").append(ope).append(" "); operator.getRight().visit(this); diff --git a/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/ParsingTest.java b/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/ParsingTest.java index 4a91b2e0..03ecbaee 100644 --- a/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/ParsingTest.java +++ b/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/ParsingTest.java @@ -57,7 +57,7 @@ protected void parseAndVerify(@NotNull File file) throws UssException { System.out.println(tokens + "\n"); // Parse - List nodes = UltimateSpellSystemDSL.parse(tokens); + List nodes = UltimateSpellSystemDSL2.parse(tokens); System.out.println(" ----------------------- "); From 89ee02dafa87bd0f38ddd574914b815144ffe8d4 Mon Sep 17 00:00:00 2001 From: "timothe.rosaz" Date: Fri, 24 Oct 2025 15:12:59 +0200 Subject: [PATCH 11/38] Prepare validation --- .../dsl2/UltimateSpellSystemDSL2.java | 4 + .../ultimatespellsystem/dsl2/ast/AST.java | 12 ++- .../dsl2/library/ObjectsLibrary.java | 57 +++++++++++ .../dsl2/library/StructDefinition.java | 51 ++++++++++ .../dsl2/library/structs/EntityStruct.java | 51 ++++++++++ .../functions/FunctionArgument.java | 9 ++ .../functions/FunctionCallExpression.java | 94 ------------------- .../functions/FunctionDefinition.java | 7 ++ .../expressions/litteral/LocationLiteral.java | 2 +- .../expressions/operators/SubOperator.java | 10 +- .../dsl2/nodes/type/Type.java | 12 +++ .../dsl2/nodes/type/TypePrimitive.java | 12 ++- .../nodes/type/variables/TypesContext.java | 33 ++++++- .../registries/ObjectsDefinitionRegistry.java | 25 +++++ 14 files changed, 273 insertions(+), 106 deletions(-) create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/library/ObjectsLibrary.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/library/StructDefinition.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/library/structs/EntityStruct.java delete mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/functions/FunctionCallExpression.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/registries/ObjectsDefinitionRegistry.java diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/UltimateSpellSystemDSL2.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/UltimateSpellSystemDSL2.java index 5a9202db..7512e2da 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/UltimateSpellSystemDSL2.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/UltimateSpellSystemDSL2.java @@ -1,8 +1,10 @@ package fr.jamailun.ultimatespellsystem.dsl2; +import fr.jamailun.ultimatespellsystem.dsl2.library.structs.EntityStruct; import fr.jamailun.ultimatespellsystem.dsl2.metadata.rules.DefaultMetadataRules; import fr.jamailun.ultimatespellsystem.dsl2.nodes.ExpressionNode; import fr.jamailun.ultimatespellsystem.dsl2.nodes.StatementNode; +import fr.jamailun.ultimatespellsystem.dsl2.registries.ObjectsDefinitionRegistry; import fr.jamailun.ultimatespellsystem.dsl2.tokenization.CharStream; import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenStream; import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenType; @@ -22,6 +24,8 @@ private UltimateSpellSystemDSL2() {} // Load the default metadata rules on class load. static { DefaultMetadataRules.initialize(); + // + ObjectsDefinitionRegistry.registerDefaultStruct(new EntityStruct()); } /** diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/ast/AST.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/ast/AST.java index 726061ee..69c06f35 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/ast/AST.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/ast/AST.java @@ -1,20 +1,28 @@ package fr.jamailun.ultimatespellsystem.dsl2.ast; import fr.jamailun.ultimatespellsystem.dsl2.nodes.StatementNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.statements.FunctionDeclarationStatement; import org.jetbrains.annotations.NotNull; import java.util.*; public class AST implements Iterable { - private final List statements; + private final List functionDeclarationStatements = new ArrayList<>(); + private final List statements = new ArrayList<>(); /** * Create a copy of a statements in the AST. * @param statements a collection to copy. */ public AST(@NotNull SequencedCollection statements) { - this.statements = new ArrayList<>(statements); + for(StatementNode statement : statements) { + if(statement instanceof FunctionDeclarationStatement fda) { + functionDeclarationStatements.add(fda); + } else { + this.statements.add(statement); + } + } } /** diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/library/ObjectsLibrary.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/library/ObjectsLibrary.java new file mode 100644 index 00000000..24126f77 --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/library/ObjectsLibrary.java @@ -0,0 +1,57 @@ +package fr.jamailun.ultimatespellsystem.dsl2.library; + +import fr.jamailun.ultimatespellsystem.dsl2.nodes.StatementNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.statements.FunctionDeclarationStatement; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; +import fr.jamailun.ultimatespellsystem.dsl2.registries.ObjectsDefinitionRegistry; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.HashMap; +import java.util.Map; +import java.util.SequencedCollection; + +public class ObjectsLibrary { + + private final Map functions = new HashMap<>(); + private final Map structs = new HashMap<>(); + private final Map types = new HashMap<>(); + + public ObjectsLibrary() { + this(true); + } + + public ObjectsLibrary(boolean registerDefaults) { + types.putAll(TypePrimitive.getTypesMap()); + if(registerDefaults) { + ObjectsDefinitionRegistry.getDefaultStructs().forEach(this::registerStruct); + } + } + + public void registerStruct(@NotNull StructDefinition struct) { + structs.put(struct.getName(), struct); + types.put(struct.getName(), struct.asType()); + } + + public void registerStatements(@NotNull SequencedCollection statements) { + for(StatementNode statement : statements) { + if(statement instanceof FunctionDeclarationStatement fda) { + functions.put(fda.getFunctionName(), fda); + } + } + } + + public @Nullable FunctionDeclarationStatement getFunction(String name) { + return functions.get(name); + } + + public @Nullable StructDefinition getStruct(String name) { + return structs.get(name); + } + + public @Nullable Type getType(String name) { + return types.get(name); + } + +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/library/StructDefinition.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/library/StructDefinition.java new file mode 100644 index 00000000..1d6ec4fc --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/library/StructDefinition.java @@ -0,0 +1,51 @@ +package fr.jamailun.ultimatespellsystem.dsl2.library; + +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionDefinition; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.HashMap; +import java.util.Map; + +@RequiredArgsConstructor +public class StructDefinition { + + protected static final String LAZY_TYPE_LOCATION = "location"; + + @Getter private final String name; + private final Map fields = new HashMap<>(); + private final Map functions = new HashMap<>(); + + public void registerField(@NotNull String fieldName, @NotNull Type type) { + fields.put(fieldName, type); + } + + public void registerField(@NotNull String fieldName, @NotNull TypePrimitive primitive) { + fields.put(fieldName, new Type(primitive, 0)); + } + + protected void registerField(@NotNull String fieldName, @NotNull String lazyType) { + fields.put(fieldName, new Type(lazyType, 0)); + } + + public void registerFunction(@NotNull FunctionDefinition function) { + functions.put(function.id(), function); + } + + public @Nullable Type getFieldType(@NotNull String fieldName) { + return fields.get(fieldName); + } + + public @NotNull FunctionDefinition getFunction(@NotNull String functionName) { + return functions.get(functionName); + } + + public @NotNull Type asType() { + return new Type(name, 0); + } + +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/library/structs/EntityStruct.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/library/structs/EntityStruct.java new file mode 100644 index 00000000..0dd70f82 --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/library/structs/EntityStruct.java @@ -0,0 +1,51 @@ +package fr.jamailun.ultimatespellsystem.dsl2.library.structs; + +import fr.jamailun.ultimatespellsystem.dsl2.library.StructDefinition; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionDefinition; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; + +public class EntityStruct extends StructDefinition { + public EntityStruct() { + super("entity"); + initFields(); + initFunctions(); + } + + private void initFields() { + registerField("name", TypePrimitive.STRING); + + registerField("location", LAZY_TYPE_LOCATION); + registerField("position", LAZY_TYPE_LOCATION); + registerField("eye_location", LAZY_TYPE_LOCATION); + registerField("eye_position", LAZY_TYPE_LOCATION); + + // Location + registerField("x", TypePrimitive.NUMBER); + registerField("y", TypePrimitive.NUMBER); + registerField("z", TypePrimitive.NUMBER); + registerField("yaw", TypePrimitive.NUMBER); + registerField("pitch", TypePrimitive.NUMBER); + + // Attributes + registerField("health", TypePrimitive.NUMBER); + registerField("max_health", TypePrimitive.NUMBER); + registerField("attack", TypePrimitive.NUMBER); + registerField("armor", TypePrimitive.NUMBER); + } + + private void initFunctions() { + registerFunction(FunctionDefinition.of( + "teleport", + TypePrimitive.NULL.asType(), + FunctionArgument.of(LAZY_TYPE_LOCATION) + )); + + registerFunction(FunctionDefinition.of( + "heal", + TypePrimitive.NULL.asType(), + FunctionArgument.of(TypePrimitive.NUMBER) + )); + } + +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/functions/FunctionArgument.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/functions/FunctionArgument.java index cad108aa..c9fe042e 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/functions/FunctionArgument.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/functions/FunctionArgument.java @@ -1,6 +1,7 @@ package fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; @@ -16,4 +17,12 @@ public record FunctionArgument(@NotNull Type type, @NotNull String debugName, bo public @NotNull String toString() { return type + " " + debugName + (optional?"*":""); } + + public static FunctionArgument of(@NotNull String type) { + return new FunctionArgument(Type.of(type), type, false); + } + + public static FunctionArgument of(@NotNull TypePrimitive type) { + return new FunctionArgument(Type.of(type), type.name().toLowerCase(), false); + } } diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/functions/FunctionCallExpression.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/functions/FunctionCallExpression.java deleted file mode 100644 index 995aeb26..00000000 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/functions/FunctionCallExpression.java +++ /dev/null @@ -1,94 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions; - -import fr.jamailun.ultimatespellsystem.dsl2.errors.SyntaxException; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.ExpressionNode; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.variables.TypesContext; -import fr.jamailun.ultimatespellsystem.dsl2.tokenization.*; -import fr.jamailun.ultimatespellsystem.dsl2.visitor.ExpressionVisitor; -import lombok.Getter; -import org.jetbrains.annotations.NotNull; - -import java.util.ArrayList; -import java.util.List; - -/** - * A function call statement. - */ -@Getter -public final class FunctionCallExpression extends ExpressionNode { - - private final FunctionDefinition function; - private final List arguments; - - public FunctionCallExpression(@NotNull TokenPosition position, @NotNull FunctionDefinition function, @NotNull List arguments) { - super(position); - this.function = function; - this.arguments = arguments; - } - - @Override - public void validateTypes(@NotNull TypesContext contextRaw) { - TypesContext context = contextRaw.childContext(); - - // Check argument amount - List listArgs = function.arguments(); - - // Then validate arguments types - for(int i = 0; i < arguments.size(); i++) { - FunctionArgument expected = listArgs.get(i); - ExpressionNode obtained = arguments.get(i); - obtained.validateTypes(context); - } - } - - @Override - public void visit(@NotNull ExpressionVisitor visitor) { - throw new UnsupportedOperationException("plus maintenant"); - } - - @Override - public @NotNull Type getExpressionType() { - return function.returnedType(); - } - - /** - * Parse a new function call expression from the tokens stream. - * @param functionDefinition found definition. - * @param tokens tokens streams. - * @return a new instance. - */ - @PreviousIndicator(expected = TokenType.BRACKET_OPEN) - public static @NotNull FunctionCallExpression readNextFunctionCall(@NotNull FunctionDefinition functionDefinition, @NotNull TokenStream tokens) { - List arguments = new ArrayList<>(); - TokenPosition position = tokens.position(); - - boolean first = true; - while(tokens.hasMore()) { - Token peek = tokens.peek(); - if(peek.getType() == TokenType.BRACKET_CLOSE) - break; - if( ! first) { - tokens.dropOrThrow(TokenType.COMMA); - } first = false; - - ExpressionNode argument = ExpressionNode.readNextExpression(tokens); - arguments.add(argument); - } - tokens.dropOrThrow(TokenType.BRACKET_CLOSE); - - // Assert obtained arguments count is expected - if(arguments.size() < functionDefinition.mandatoryArgumentsCount()) - throw new SyntaxException(position, "Invalid arguments count. Expected " + functionDefinition.arguments().size() + " mandatory, got " + arguments.size()); - if(arguments.size() > functionDefinition.arguments().size()) - throw new SyntaxException(position, "Invalid arguments count. Expected " + functionDefinition.arguments().size() + ", got " + arguments.size()); - - // Create and return node - return new FunctionCallExpression(position, functionDefinition, arguments); - } - - @Override - public @NotNull String toString() { - return "F-call{"+function.id()+" (" + arguments + ")}"; - } -} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/functions/FunctionDefinition.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/functions/FunctionDefinition.java index f7085cab..62aafe1c 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/functions/FunctionDefinition.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/functions/FunctionDefinition.java @@ -21,7 +21,14 @@ public int mandatoryArgumentsCount() { return (int) arguments.stream() .filter(a -> ! a.optional()) .count(); + } + public static FunctionDefinition of( + @NotNull String id, + @NotNull Type type, + @NotNull FunctionArgument... arguments + ) { + return new FunctionDefinition(id, type, List.of(arguments)); } } diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/LocationLiteral.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/LocationLiteral.java index 98fdbce9..aaf18b41 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/LocationLiteral.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/LocationLiteral.java @@ -41,7 +41,7 @@ public boolean asYawAndPitch() { @Override public @NotNull Type getExpressionType() { - return TypePrimitive.LOCATION.asType(); + return Type.of("location"); } @Override diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/SubOperator.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/SubOperator.java index 5068535e..24081462 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/SubOperator.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/SubOperator.java @@ -29,7 +29,11 @@ public SubOperator(TokenPosition pos, ExpressionNode left, ExpressionNode right) return BiOpeType.SUB; } - private final static List ALLOWED = List.of(TypePrimitive.NUMBER, TypePrimitive.DURATION, TypePrimitive.LOCATION); + private final static List ALLOWED = List.of( + Type.of(TypePrimitive.NUMBER), + Type.of(TypePrimitive.DURATION), + Type.of("location") + ); @Override public void validateTypes(@NotNull Type leftType, @NotNull Type rightType, @NotNull TypesContext context) { @@ -38,9 +42,9 @@ public void validateTypes(@NotNull Type leftType, @NotNull Type rightType, @NotN throw new TypeException(this, "A NEGATION cannot handle collections."); } - if(!leftType.isOneOf(ALLOWED.toArray(new TypePrimitive[0]))) + if(!leftType.isOneOf(ALLOWED)) throw new TypeException(this, "SUB cannot handle L=" + leftType); - if(!rightType.isOneOf(ALLOWED.toArray(new TypePrimitive[0]))) + if(!rightType.isOneOf(ALLOWED)) throw new TypeException(this, "SUB cannot handle R=" + rightType); // Otherwise same type : always compatible diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/Type.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/Type.java index 558016a1..18beba83 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/Type.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/Type.java @@ -4,6 +4,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Collection; import java.util.Objects; import java.util.Set; @@ -48,6 +49,10 @@ public boolean isOneOf(@NotNull TypePrimitive... primitives) { return Set.of(primitives).contains(primitive); } + public boolean isOneOf(@NotNull Collection types) { + return types.stream().anyMatch(this::equals); + } + public boolean is(@NotNull String objectClass) { return this.objectClass != null && this.objectClass.equals(objectClass); } @@ -84,4 +89,11 @@ public boolean equals(Object o) { public int hashCode() { return Objects.hash(primitive, objectClass, arrayLevel); } + + public static @NotNull Type of(@NotNull String name) { + return new Type(name, 0); + } + public static @NotNull Type of(@NotNull TypePrimitive name) { + return new Type(name, 0); + } } diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/TypePrimitive.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/TypePrimitive.java index 62638ba3..41dd24dc 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/TypePrimitive.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/TypePrimitive.java @@ -4,6 +4,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.HashMap; import java.util.Map; /** @@ -24,8 +25,6 @@ public enum TypePrimitive { /** A temporal duration. */ DURATION(Duration.class), - LOCATION, - MAP(Map.class), /** A {@code null} value. */ @@ -75,4 +74,13 @@ public enum TypePrimitive { }; } + public static @NotNull Map getTypesMap() { + Map map = new HashMap<>(); + for (TypePrimitive primitive : TypePrimitive.values()) { + if(primitive.clazz != null) + map.put(primitive.name().toLowerCase(), primitive.asType()); + } + return map; + } + } diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/variables/TypesContext.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/variables/TypesContext.java index c66b746f..456723ad 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/variables/TypesContext.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/variables/TypesContext.java @@ -1,7 +1,10 @@ package fr.jamailun.ultimatespellsystem.dsl2.nodes.type.variables; import fr.jamailun.ultimatespellsystem.dsl2.errors.SyntaxException; +import fr.jamailun.ultimatespellsystem.dsl2.library.ObjectsLibrary; +import fr.jamailun.ultimatespellsystem.dsl2.library.StructDefinition; import fr.jamailun.ultimatespellsystem.dsl2.nodes.ExpressionNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.statements.FunctionDeclarationStatement; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenPosition; import org.jetbrains.annotations.Contract; @@ -17,13 +20,23 @@ public class TypesContext { private final Map vars = new HashMap<>(); + private final ObjectsLibrary objectsLibrary; /** - * Create a new context, and register the {@code %caster} variable. + * Create a new context.
+ * The variable {@code caster} will be registered. */ public TypesContext() { - //TODO -// promiseVariable("caster", TypePrimitive.ENTITY.asType()); + this.objectsLibrary = new ObjectsLibrary(true); + promiseVariable("caster", Type.of("entity")); + } + + /** + * Create a new context. + * @param objectsLibrary reference library to use. + */ + private TypesContext(@NotNull ObjectsLibrary objectsLibrary) { + this.objectsLibrary = objectsLibrary; } /** @@ -75,13 +88,25 @@ public void registerVariable(@NotNull String varName, @NotNull TokenPosition pos return vars.get(varName); } + public @Nullable Type findType(@NotNull String name) { + return objectsLibrary.getType(name); + } + + public @Nullable FunctionDeclarationStatement findFunction(@NotNull String name) { + return objectsLibrary.getFunction(name); + } + + public @Nullable StructDefinition findStruct(@NotNull String name) { + return objectsLibrary.getStruct(name); + } + /** * Create a new context. This allows sub-scopes to be independents. * @return a new instance of context, copying the current variables. */ @Contract(" -> new") public @NotNull TypesContext childContext() { - TypesContext child = new TypesContext(); + TypesContext child = new TypesContext(objectsLibrary); child.vars.putAll(vars); return child; } diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/registries/ObjectsDefinitionRegistry.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/registries/ObjectsDefinitionRegistry.java new file mode 100644 index 00000000..3a7055ba --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/registries/ObjectsDefinitionRegistry.java @@ -0,0 +1,25 @@ +package fr.jamailun.ultimatespellsystem.dsl2.registries; + +import fr.jamailun.ultimatespellsystem.dsl2.library.StructDefinition; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.UnmodifiableView; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +public final class ObjectsDefinitionRegistry { + private ObjectsDefinitionRegistry() {/* private */} + + private static final Map DEFAULT_STRUCTS = new HashMap<>(); + + public static void registerDefaultStruct(@NotNull StructDefinition definition) { + DEFAULT_STRUCTS.put(definition.getName(), definition); + } + + public static @NotNull @UnmodifiableView Collection getDefaultStructs() { + return Collections.unmodifiableCollection(DEFAULT_STRUCTS.values()); + } + +} From 6a0f31599adf9d7489098abaf056844b41693b9e Mon Sep 17 00:00:00 2001 From: "timothe.rosaz" Date: Fri, 24 Oct 2025 21:09:13 +0200 Subject: [PATCH 12/38] Validation of assignment --- .../dsl2/errors/TypeException.java | 4 +++ .../expressions/ReferenceExpression.java | 5 +++ .../statements/AffectationStatement.java | 28 +++++++++++++-- .../DeclareNewVariableStatement.java | 36 ++++++++++++++++--- .../dsl2/nodes/type/Type.java | 14 ++++++++ .../nodes/type/variables/TypesContext.java | 4 +-- .../dsl2/FailuresParsingTests.java | 22 +----------- .../invalid/bad_type/bad_assignment.uss | 2 ++ 8 files changed, 86 insertions(+), 29 deletions(-) create mode 100644 dsl2/src/test/resources/parsing/invalid/bad_type/bad_assignment.uss diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/errors/TypeException.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/errors/TypeException.java index 33684408..94cb8334 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/errors/TypeException.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/errors/TypeException.java @@ -1,6 +1,7 @@ package fr.jamailun.ultimatespellsystem.dsl2.errors; import fr.jamailun.ultimatespellsystem.dsl2.nodes.ExpressionNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenPosition; @@ -18,6 +19,9 @@ public TypeException(ExpressionNode expression, TypePrimitive expected) { super(expression.firstTokenPosition(), "Expression " + expression + " has type " + expression.getExpressionType() + ", expected " + expected); } + public TypeException(ExpressionNode expression, Type expected) { + super(expression.firstTokenPosition(), "Expression " + expression + " has type " + expression.getExpressionType() + ", expected " + expected); + } /** * Unexpected expression type. * @param expression expression source of tbe exception. Must have a type set. diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/ReferenceExpression.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/ReferenceExpression.java index 09a3947e..0aecb32c 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/ReferenceExpression.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/ReferenceExpression.java @@ -27,6 +27,11 @@ public ReferenceExpression(@NotNull Token token) { this.varName = token.getContentString(); } + public void signalType(@NotNull Type type) { + //TODO trucs + runtimeType = type; + } + /** * Get the name of the variable. * @return a non-null string. diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/AffectationStatement.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/AffectationStatement.java index 6e46d843..75ee0e84 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/AffectationStatement.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/AffectationStatement.java @@ -1,7 +1,10 @@ package fr.jamailun.ultimatespellsystem.dsl2.nodes.statements; +import fr.jamailun.ultimatespellsystem.dsl2.errors.TypeException; import fr.jamailun.ultimatespellsystem.dsl2.nodes.ExpressionNode; import fr.jamailun.ultimatespellsystem.dsl2.nodes.StatementNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.ReferenceExpression; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.variables.TypesContext; import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenStream; import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenType; @@ -10,6 +13,8 @@ import lombok.RequiredArgsConstructor; import org.jetbrains.annotations.NotNull; +import java.util.Objects; + /** * Set a variable value. */ @@ -22,8 +27,27 @@ public class AffectationStatement extends StatementNode { @Override public void validateTypes(@NotNull TypesContext context) { - //TODO - // expression.validateTypes(context); + // Validate right expression + expression.validateTypes(context); + Type typeRight = expression.getExpressionType(); + + // Validate left (propagate if needed) + valueHolder.validateTypes(context); + Type leftType = valueHolder.getExpressionType(); + + // If left is NULL : only happens with a VAR declaration + if(leftType.isNull()) { + // is it an assignment + if(valueHolder instanceof ReferenceExpression ref) { + ref.signalType(leftType); + } + return; + } + + // Left is not NULL (it's as such explicit) + if(!Objects.equals(leftType, typeRight)) { + throw new TypeException(expression, "Assignment for " + valueHolder + " expected " + leftType + ". Expression is of type " + typeRight); + } } @Override diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/DeclareNewVariableStatement.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/DeclareNewVariableStatement.java index 597d2cba..011dd94d 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/DeclareNewVariableStatement.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/DeclareNewVariableStatement.java @@ -1,12 +1,15 @@ package fr.jamailun.ultimatespellsystem.dsl2.nodes.statements; +import fr.jamailun.ultimatespellsystem.dsl2.errors.SyntaxException; +import fr.jamailun.ultimatespellsystem.dsl2.errors.TypeException; import fr.jamailun.ultimatespellsystem.dsl2.nodes.ExpressionNode; import fr.jamailun.ultimatespellsystem.dsl2.nodes.StatementNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.variables.TypesContext; import fr.jamailun.ultimatespellsystem.dsl2.tokenization.Token; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenPosition; import fr.jamailun.ultimatespellsystem.dsl2.visitor.StatementVisitor; import lombok.Getter; -import lombok.RequiredArgsConstructor; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -16,14 +19,15 @@ * Define statement will set a variable to something. */ @Getter -@RequiredArgsConstructor public class DeclareNewVariableStatement extends StatementNode { + private final @NotNull TokenPosition position; private final @Nullable String varType; private final @NotNull String varName; private final @Nullable ExpressionNode expression; public DeclareNewVariableStatement(@Nullable Token varType, @NotNull Token varName, @Nullable ExpressionNode expression) { + this.position = varName.pos(); this.varType = varType == null ? null : varType.getContentString(); this.varName = varName.getContentString(); this.expression = expression; @@ -31,11 +35,35 @@ public DeclareNewVariableStatement(@Nullable Token varType, @NotNull Token varNa @Override public void validateTypes(@NotNull TypesContext context) { + // 1. Check the variable does not already exist ? + var existingVariable = context.findVariable(varName); + if(existingVariable != null) { + throw new SyntaxException(position, "Variable '" + varName + "' is already set."); + } + + // 2. At least the type or the expression must be defined + if(varType == null && expression == null) { + throw new SyntaxException(position, "Variable '" + varName + "' cannot use the 'var' keyword without direct assignation."); + } + + // 3. Validate expression if possible. + Type type; if(expression != null) { expression.validateTypes(context); - //TODO - context.registerVariable(varName, expression); + type = expression.getExpressionType(); + } else { + type = Type.ofAny(varType); } + + // 4. If the type is explicit, check it matches + if(varType != null) { + if(!Objects.equals(Type.ofAny(varType), type)) { + throw new TypeException(position, "Assignment for " + varName + " expected " + varType + ". Expression is of type " + type); + } + } + + // Register the variable + context.registerVariable(position, varName, type); } @Override diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/Type.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/Type.java index 18beba83..4c2d8b55 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/Type.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/Type.java @@ -61,6 +61,10 @@ public boolean isCollection() { return arrayLevel > 0; } + public boolean isNull() { + return is(TypePrimitive.NULL); + } + @Contract(pure = true) public @NotNull Type popArray() { return new Type(primitive, objectClass, Math.max(0, arrayLevel - 1)); @@ -96,4 +100,14 @@ public int hashCode() { public static @NotNull Type of(@NotNull TypePrimitive name) { return new Type(name, 0); } + + /** + * Get the {@link Type} of an identifier. + * @param name the identifier to use. + * @return a non-null Type, either with a primitive or not. + */ + public static @NotNull Type ofAny(@NotNull String name) { + TypePrimitive primitive = TypePrimitive.parsePrimitive(name); + return primitive == null ? Type.of(name) : Type.of(primitive); + } } diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/variables/TypesContext.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/variables/TypesContext.java index 456723ad..b0656e03 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/variables/TypesContext.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/variables/TypesContext.java @@ -70,9 +70,9 @@ public void promiseVariable(@NotNull String name, @NotNull Type type) { * @param position the position of the declaration. * @param type the type of variable. */ - public void registerVariable(@NotNull String varName, @NotNull TokenPosition position, @NotNull Type type) { + public void registerVariable(@NotNull TokenPosition position, @NotNull String varName, @NotNull Type type) { if("caster".equals(varName)) { - throw new SyntaxException(position, "Cannot override variable '%" + varName + "'."); + throw new SyntaxException(position, "Cannot override variable '" + varName + "'."); } vars.putIfAbsent(varName, new VariableDefinition(varName)); diff --git a/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/FailuresParsingTests.java b/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/FailuresParsingTests.java index cc93edf5..4a10d1ac 100644 --- a/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/FailuresParsingTests.java +++ b/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/FailuresParsingTests.java @@ -11,29 +11,9 @@ */ public class FailuresParsingTests extends ParsingTest { - @Test - void badParsing() { - badParsing("bad_parsing", ParsingException.class); - } - - @Test - void badSyntax() { - badParsing("bad_syntax", SyntaxException.class); - } - @Test void badType() { - badParsing("bad_type", TypeException.class); - } - - @Test - void badTreeValidation() { - badParsing("bad_tree", TreeValidationException.class); - } - - @Test - void badMix() { - badParsing("bad_mix", UssException.class); + badParsing("invalid/bad_type", TypeException.class); } private void badParsing(@NotNull String folder, @NotNull Class clazz) { diff --git a/dsl2/src/test/resources/parsing/invalid/bad_type/bad_assignment.uss b/dsl2/src/test/resources/parsing/invalid/bad_type/bad_assignment.uss new file mode 100644 index 00000000..7c10d3d0 --- /dev/null +++ b/dsl2/src/test/resources/parsing/invalid/bad_type/bad_assignment.uss @@ -0,0 +1,2 @@ +# Ne peut pas fonctionner xd +int a = "string"; \ No newline at end of file From 83bbf40dd6e7105228dc3080d279506498d6c4b3 Mon Sep 17 00:00:00 2001 From: "timothe.rosaz" Date: Fri, 24 Oct 2025 21:32:44 +0200 Subject: [PATCH 13/38] Function validation --- .../dsl2/library/ObjectsLibrary.java | 6 +++- .../DeclareNewVariableStatement.java | 2 +- .../FunctionDeclarationStatement.java | 30 ++++++++++++++++--- .../nodes/statements/ReturnStatement.java | 2 +- .../dsl2/nodes/type/TypePrimitive.java | 2 +- .../nodes/type/variables/TypesContext.java | 8 +++++ .../dsl2/tokenization/TokenType.java | 1 - .../dsl2/visitor/PrintingVisitor.java | 6 +++- .../dsl2/CorrectParsingTests.java | 5 ++++ .../dsl2/FailuresParsingTests.java | 5 ++++ .../corrects/basics/basic_function_int.uss | 3 ++ .../corrects/basics/basic_function_void.uss | 3 ++ .../functions/basic_function_void.uss | 3 ++ .../invalid/bad_syntax/caster_assign.uss | 1 + .../parsing/invalid/bad_syntax/empty_var.uss | 1 + .../bad_syntax/repeated_declaration.uss | 2 ++ .../invalid/bad_syntax/repeated_function.uss | 2 ++ .../invalid/bad_type/bad_assignment.uss | 1 - .../invalid/bad_type/bad_reassignment.uss | 2 ++ 19 files changed, 74 insertions(+), 11 deletions(-) create mode 100644 dsl2/src/test/resources/parsing/corrects/basics/basic_function_int.uss create mode 100644 dsl2/src/test/resources/parsing/corrects/basics/basic_function_void.uss create mode 100644 dsl2/src/test/resources/parsing/corrects/functions/basic_function_void.uss create mode 100644 dsl2/src/test/resources/parsing/invalid/bad_syntax/caster_assign.uss create mode 100644 dsl2/src/test/resources/parsing/invalid/bad_syntax/empty_var.uss create mode 100644 dsl2/src/test/resources/parsing/invalid/bad_syntax/repeated_declaration.uss create mode 100644 dsl2/src/test/resources/parsing/invalid/bad_syntax/repeated_function.uss create mode 100644 dsl2/src/test/resources/parsing/invalid/bad_type/bad_reassignment.uss diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/library/ObjectsLibrary.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/library/ObjectsLibrary.java index 24126f77..b97d2037 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/library/ObjectsLibrary.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/library/ObjectsLibrary.java @@ -37,11 +37,15 @@ public void registerStruct(@NotNull StructDefinition struct) { public void registerStatements(@NotNull SequencedCollection statements) { for(StatementNode statement : statements) { if(statement instanceof FunctionDeclarationStatement fda) { - functions.put(fda.getFunctionName(), fda); + registerFunction(fda); } } } + public void registerFunction(@NotNull FunctionDeclarationStatement declaration) { + functions.put(declaration.getFunctionName(), declaration); + } + public @Nullable FunctionDeclarationStatement getFunction(String name) { return functions.get(name); } diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/DeclareNewVariableStatement.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/DeclareNewVariableStatement.java index 011dd94d..16bd8686 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/DeclareNewVariableStatement.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/DeclareNewVariableStatement.java @@ -62,7 +62,7 @@ public void validateTypes(@NotNull TypesContext context) { } } - // Register the variable + // 5. Register the variable context.registerVariable(position, varName, type); } diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/FunctionDeclarationStatement.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/FunctionDeclarationStatement.java index 9e631d74..56860000 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/FunctionDeclarationStatement.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/FunctionDeclarationStatement.java @@ -1,8 +1,10 @@ package fr.jamailun.ultimatespellsystem.dsl2.nodes.statements; +import fr.jamailun.ultimatespellsystem.dsl2.errors.SyntaxException; import fr.jamailun.ultimatespellsystem.dsl2.nodes.StatementNode; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.variables.TypesContext; import fr.jamailun.ultimatespellsystem.dsl2.tokenization.Token; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenPosition; import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenStream; import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenType; import fr.jamailun.ultimatespellsystem.dsl2.visitor.StatementVisitor; @@ -17,6 +19,7 @@ @AllArgsConstructor public class FunctionDeclarationStatement extends StatementNode { + private final @NotNull TokenPosition position; private final String functionReturnType; private final String functionName; private final List parameters; @@ -29,7 +32,22 @@ public void visit(@NotNull StatementVisitor visitor) { @Override public void validateTypes(@NotNull TypesContext context) { - //TODO !! + // 1. Check function does not already exist + var existingFunction = context.findFunction(functionName); + if (existingFunction != null) { + throw new SyntaxException(position, "The function '" + functionName + "' has already been defined. Signature is " + existingFunction.signature()); + } + + // 2. Propagate to children + TypesContext child = context.childContext(); + for(StatementNode statement : statements) { + statement.validateTypes(child); + } + + //TODO Validate tree and return ! + + // Register function + context.registerFunction(this); } public static @NotNull FunctionDeclarationStatement parseNextFunction(@NotNull Token typeIdentifier, @NotNull Token nameIdentifier, @NotNull TokenStream tokens) { @@ -43,8 +61,8 @@ public void validateTypes(@NotNull TypesContext context) { while(! tokens.dropOptional(TokenType.BRACKET_CLOSE)) { if(first) first = false; else tokens.dropOrThrow(TokenType.COMMA, "Arguments need to be separated by a comma."); // Each parameter - Token identifierType = tokens.nextOrThrow(TokenType.IDENTIFIER); - Token identifierName = tokens.nextOrThrow(TokenType.IDENTIFIER); + Token identifierType = tokens.nextOrThrow(TokenType.IDENTIFIER, "Missing parameter type in function '" + functionName + "'."); + Token identifierName = tokens.nextOrThrow(TokenType.IDENTIFIER, "Missing parameter name in function '" + functionName + "'."); parameters.add(new FunctionParameter(identifierType.getContentString(), identifierName.getContentString())); } @@ -56,7 +74,7 @@ public void validateTypes(@NotNull TypesContext context) { tokens.dropOptional(TokenType.SEMI_COLON); } - return new FunctionDeclarationStatement(functionReturnType, functionName, parameters, statements); + return new FunctionDeclarationStatement(typeIdentifier.pos(), functionReturnType, functionName, parameters, statements); } public record FunctionParameter(String type, String name) {} @@ -69,4 +87,8 @@ public String toString() { statements.toString() + "}"; } + + public @NotNull String signature() { + return functionReturnType + " " + functionName + "(" + String.join(", ", getParameters().stream().map(Object::toString).toList()) + ")"; + } } diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/ReturnStatement.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/ReturnStatement.java index f5706640..58a21621 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/ReturnStatement.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/ReturnStatement.java @@ -45,7 +45,7 @@ public void visit(@NotNull StatementVisitor visitor) { return new ReturnStatement(null); } else { ExpressionNode exitNode = ExpressionNode.readNextExpression(tokens); - tokens.dropOrThrow(TokenType.SEMI_COLON); + tokens.dropOrThrow(TokenType.SEMI_COLON, "Expected a semi-colon after a RETURN statement value."); return new ReturnStatement(exitNode); } } diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/TypePrimitive.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/TypePrimitive.java index 41dd24dc..182c7486 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/TypePrimitive.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/TypePrimitive.java @@ -68,7 +68,7 @@ public enum TypePrimitive { case "number", "double", "float", "integer", "int", "short", "byte" -> NUMBER; case "boolean", "bool" -> BOOLEAN; case "duration", "time", "chrono" -> DURATION; - case "null" -> NULL; + case "null", "void" -> NULL; case "map", "data", "properties", "properties-set", "properties_set" -> MAP; default -> null; }; diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/variables/TypesContext.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/variables/TypesContext.java index b0656e03..926784e7 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/variables/TypesContext.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/variables/TypesContext.java @@ -100,6 +100,14 @@ public void registerVariable(@NotNull TokenPosition position, @NotNull String va return objectsLibrary.getStruct(name); } + /** + * Register a new function to the context + * @param declaration the declaration to use. + */ + public void registerFunction(@NotNull FunctionDeclarationStatement declaration) { + objectsLibrary.registerFunction(declaration); + } + /** * Create a new context. This allows sub-scopes to be independents. * @return a new instance of context, copying the current variables. diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/tokenization/TokenType.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/tokenization/TokenType.java index 9ff926ec..9f81d736 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/tokenization/TokenType.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/tokenization/TokenType.java @@ -58,7 +58,6 @@ public enum TokenType { // == RAW VALUES NULL(true), - VOID(true), // == N-CHARS OPERATORS diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/PrintingVisitor.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/PrintingVisitor.java index 37fbbc11..61126bac 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/PrintingVisitor.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/PrintingVisitor.java @@ -106,7 +106,11 @@ private void eol() { @Override public void handleReturn(@NotNull ReturnStatement statement) { - builder.append(indent()).append("stop"); + builder.append(indent()).append("return"); + if(statement.getExitCodeNode() != null) { + builder.append(" "); + statement.getExitCodeNode().visit(this); + } } @Override diff --git a/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/CorrectParsingTests.java b/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/CorrectParsingTests.java index b4302e03..4067bd5e 100644 --- a/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/CorrectParsingTests.java +++ b/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/CorrectParsingTests.java @@ -26,6 +26,11 @@ void correctLiterals() { testFolder("corrects/literals"); } + @Test + void correctFunctions() { + testFolder("corrects/functions"); + } + // -- private void testFolder(@NotNull String folder) { diff --git a/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/FailuresParsingTests.java b/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/FailuresParsingTests.java index 4a10d1ac..77dd788e 100644 --- a/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/FailuresParsingTests.java +++ b/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/FailuresParsingTests.java @@ -16,6 +16,11 @@ void badType() { badParsing("invalid/bad_type", TypeException.class); } + @Test + void badSyntax() { + badParsing("invalid/bad_syntax", SyntaxException.class); + } + private void badParsing(@NotNull String folder, @NotNull Class clazz) { String title = "[! EXPECTED "+clazz.getSimpleName()+"] "; for(File file : listTests(folder)) { diff --git a/dsl2/src/test/resources/parsing/corrects/basics/basic_function_int.uss b/dsl2/src/test/resources/parsing/corrects/basics/basic_function_int.uss new file mode 100644 index 00000000..b0e2df09 --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/basics/basic_function_int.uss @@ -0,0 +1,3 @@ +int foo() { + return 1; +} \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing/corrects/basics/basic_function_void.uss b/dsl2/src/test/resources/parsing/corrects/basics/basic_function_void.uss new file mode 100644 index 00000000..8375d758 --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/basics/basic_function_void.uss @@ -0,0 +1,3 @@ +void foo() { + return; +} \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing/corrects/functions/basic_function_void.uss b/dsl2/src/test/resources/parsing/corrects/functions/basic_function_void.uss new file mode 100644 index 00000000..8375d758 --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/functions/basic_function_void.uss @@ -0,0 +1,3 @@ +void foo() { + return; +} \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing/invalid/bad_syntax/caster_assign.uss b/dsl2/src/test/resources/parsing/invalid/bad_syntax/caster_assign.uss new file mode 100644 index 00000000..17f62803 --- /dev/null +++ b/dsl2/src/test/resources/parsing/invalid/bad_syntax/caster_assign.uss @@ -0,0 +1 @@ +int caster = 1; \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing/invalid/bad_syntax/empty_var.uss b/dsl2/src/test/resources/parsing/invalid/bad_syntax/empty_var.uss new file mode 100644 index 00000000..e39dc0ea --- /dev/null +++ b/dsl2/src/test/resources/parsing/invalid/bad_syntax/empty_var.uss @@ -0,0 +1 @@ +var foo; \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing/invalid/bad_syntax/repeated_declaration.uss b/dsl2/src/test/resources/parsing/invalid/bad_syntax/repeated_declaration.uss new file mode 100644 index 00000000..d33bc8f7 --- /dev/null +++ b/dsl2/src/test/resources/parsing/invalid/bad_syntax/repeated_declaration.uss @@ -0,0 +1,2 @@ +int foo = 1; +int foo = 2; \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing/invalid/bad_syntax/repeated_function.uss b/dsl2/src/test/resources/parsing/invalid/bad_syntax/repeated_function.uss new file mode 100644 index 00000000..ba41b4d8 --- /dev/null +++ b/dsl2/src/test/resources/parsing/invalid/bad_syntax/repeated_function.uss @@ -0,0 +1,2 @@ +void a() {} +void a() {} diff --git a/dsl2/src/test/resources/parsing/invalid/bad_type/bad_assignment.uss b/dsl2/src/test/resources/parsing/invalid/bad_type/bad_assignment.uss index 7c10d3d0..ca8cdd2d 100644 --- a/dsl2/src/test/resources/parsing/invalid/bad_type/bad_assignment.uss +++ b/dsl2/src/test/resources/parsing/invalid/bad_type/bad_assignment.uss @@ -1,2 +1 @@ -# Ne peut pas fonctionner xd int a = "string"; \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing/invalid/bad_type/bad_reassignment.uss b/dsl2/src/test/resources/parsing/invalid/bad_type/bad_reassignment.uss new file mode 100644 index 00000000..8b066b2a --- /dev/null +++ b/dsl2/src/test/resources/parsing/invalid/bad_type/bad_reassignment.uss @@ -0,0 +1,2 @@ +string a = "string"; +a = 2; \ No newline at end of file From 304a41cf4471c641cdb3861217f5430d64ee2164 Mon Sep 17 00:00:00 2001 From: "timothe.rosaz" Date: Sat, 25 Oct 2025 00:40:35 +0200 Subject: [PATCH 14/38] Increment/decrement are now expressions --- .../dsl/nodes/StatementNode.java | 4 -- .../dsl2/ast/ConstantFoldingOptimizer.java | 6 +- .../dsl2/nodes/ExpressionNode.java | 19 +++-- .../dsl2/nodes/StatementNode.java | 10 +-- .../operators/IncrementExpression.java | 70 +++++++++++++++++++ .../nodes/expressions/operators/Operator.java | 7 +- .../nodes/statements/IncrementStatement.java | 60 ---------------- .../StructureValidationVisitor.java | 2 - .../dsl2/visitor/ExpressionVisitor.java | 4 +- .../dsl2/visitor/PrintingVisitor.java | 11 ++- .../dsl2/visitor/StatementVisitor.java | 1 - .../ultimatespellsystem/dsl2/ParsingTest.java | 3 +- .../parsing/corrects/basics/increment_add.uss | 3 + .../corrects/basics/increment_decrement.uss | 5 ++ 14 files changed, 112 insertions(+), 93 deletions(-) create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/IncrementExpression.java delete mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/IncrementStatement.java create mode 100644 dsl2/src/test/resources/parsing/corrects/basics/increment_add.uss create mode 100644 dsl2/src/test/resources/parsing/corrects/basics/increment_decrement.uss diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/StatementNode.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/StatementNode.java index f05f8b67..9724ba41 100644 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/StatementNode.java +++ b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/StatementNode.java @@ -42,10 +42,6 @@ public abstract class StatementNode extends Node { case REPEAT -> RepeatStatement.parseRepeat(tokens); case CALLBACK -> CallbackStatement.parseCallback(tokens); - // Increment / decrement - case INCREMENT -> IncrementStatement.parseIncrementOrDecrement(tokens, true); - case DECREMENT -> IncrementStatement.parseIncrementOrDecrement(tokens, false); - // Variable set case DEFINE -> DefineStatement.parseNextDefine(tokens); case VALUE_VARIABLE -> { diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/ast/ConstantFoldingOptimizer.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/ast/ConstantFoldingOptimizer.java index 008c07f4..fc018122 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/ast/ConstantFoldingOptimizer.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/ast/ConstantFoldingOptimizer.java @@ -5,6 +5,7 @@ import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.ParenthesisExpression; import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.litteral.*; import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.operators.BiOperator; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.operators.IncrementExpression; import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.operators.MonoOperator; import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.operators.Operator; import fr.jamailun.ultimatespellsystem.dsl2.nodes.statements.*; @@ -130,11 +131,6 @@ public void handleWhileLoop(@NotNull WhileLoopStatement statement) { // rien - @Override - public void handleIncrement(@NotNull IncrementStatement statement) { - // rien - } - @Override public void handleFunctionDeclaration(@NotNull FunctionDeclarationStatement statement) { // rien diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/ExpressionNode.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/ExpressionNode.java index f4d4079c..3156e523 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/ExpressionNode.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/ExpressionNode.java @@ -5,13 +5,11 @@ import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.*; import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.litteral.*; import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.operators.BiOperator; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.operators.IncrementExpression; import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.operators.NotOperator; import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.operators.SubOperator; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; -import fr.jamailun.ultimatespellsystem.dsl2.tokenization.Token; -import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenPosition; -import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenStream; -import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenType; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.*; import fr.jamailun.ultimatespellsystem.dsl2.visitor.ExpressionVisitor; import org.jetbrains.annotations.NotNull; @@ -67,7 +65,7 @@ protected ExpressionNode(@NotNull TokenPosition position) { return readNextExpression(tokens, new MathParsingQueue(false), true); } - private static ExpressionNode readNextExpression(TokenStream tokens, MathParsingQueue mathStack, boolean logicFirst) { + private static @NotNull ExpressionNode readNextExpression(TokenStream tokens, MathParsingQueue mathStack, boolean logicFirst) { ExpressionNode raw = readNextExpressionBuffer(tokens); // Check if the element is accessed ! if(tokens.dropOptional(TokenType.SQUARE_BRACKET_OPEN)) { @@ -102,6 +100,9 @@ private static ExpressionNode readNextExpression(TokenStream tokens, MathParsing case NULL -> new NullLiteral(token.pos()); case CHAR_AT -> LocationLiteral.readNextLocation(tokens); + // Increment / decrement + case INCREMENT -> IncrementExpression.parseIncrementOrDecrement(tokens, true); + case DECREMENT -> IncrementExpression.parseIncrementOrDecrement(tokens, false); // Toutes les compositions de // "A.B", "A.B(...)", "A[B]" et "A". @@ -119,8 +120,14 @@ private static ExpressionNode readNextExpression(TokenStream tokens, MathParsing }; } + @PreviousIndicator(expected = TokenType.IDENTIFIER) + public static @NotNull ExpressionNode parseIdentifierExpression(@NotNull Token first, @NotNull TokenStream tokens) { + if(tokens.dropOptional(TokenType.INCREMENT)) { + return new IncrementExpression(first, true, true); + } else if(tokens.dropOptional(TokenType.DECREMENT)) { + return new IncrementExpression(first, false, true); + } - public static ExpressionNode parseIdentifierExpression(Token first, TokenStream tokens) { ExpressionNode left = new ReferenceExpression(first); return parseIdentifierExpression(left, tokens); } diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/StatementNode.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/StatementNode.java index bbcc2987..eb76a013 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/StatementNode.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/StatementNode.java @@ -7,6 +7,7 @@ import fr.jamailun.ultimatespellsystem.dsl2.nodes.statements.blocks.ForLoopStatement; import fr.jamailun.ultimatespellsystem.dsl2.nodes.statements.blocks.IfElseStatement; import fr.jamailun.ultimatespellsystem.dsl2.nodes.statements.blocks.WhileLoopStatement; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.PreviousIndicator; import fr.jamailun.ultimatespellsystem.dsl2.tokenization.Token; import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenStream; import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenType; @@ -26,6 +27,7 @@ public abstract class StatementNode extends Node { */ public abstract void visit(@NotNull StatementVisitor visitor); + @PreviousIndicator(expected = TokenType.IDENTIFIER) private static @NotNull StatementNode parseFromIdentifier(@NotNull Token first, @NotNull TokenStream tokens) { if(!tokens.hasMore()) throw new ParsingException(tokens.position(), "Unexpected end of tokens after identifier."); @@ -38,7 +40,7 @@ public abstract class StatementNode extends Node { if(tokens.dropOptional(TokenType.EQUAL)) { ExpressionNode definition = ExpressionNode.readNextExpression(tokens); StatementNode output = new DeclareNewVariableStatement(first, second, definition); - tokens.dropOrThrow(TokenType.SEMI_COLON, "Expected a SEMI COLON."); + tokens.dropOptional(TokenType.SEMI_COLON); return output; } @@ -56,8 +58,6 @@ public abstract class StatementNode extends Node { throw new SyntaxException(tokens.position(), "Unexpected token after 'IDENTIFIER IDENTIFIER' : " + tokens.peek()); } - //TODO Incrment / decrement ! - // On essaye de wrapper le token en expression ("a" ou "a.b().c") pour voir si on a un EQUAL ensuite. ExpressionNode wrapped = ExpressionNode.parseIdentifierExpression(first, tokens); @@ -105,10 +105,6 @@ public abstract class StatementNode extends Node { // Blocks case BRACES_OPEN -> BlockStatement.parseNextBlock(tokens); - // Increment / decrement - case INCREMENT -> IncrementStatement.parseIncrementOrDecrement(tokens, true); - case DECREMENT -> IncrementStatement.parseIncrementOrDecrement(tokens, false); - // Control-Flow case IF -> IfElseStatement.parseIfStatement(tokens); case ELSE -> throw new SyntaxException(token, "An ELSE must follow an IF (or the IF's child statement)."); diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/IncrementExpression.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/IncrementExpression.java new file mode 100644 index 00000000..97a00762 --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/IncrementExpression.java @@ -0,0 +1,70 @@ +package fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.operators; + +import fr.jamailun.ultimatespellsystem.dsl2.errors.SyntaxException; +import fr.jamailun.ultimatespellsystem.dsl2.errors.TypeException; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.ExpressionNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.variables.TypesContext; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.variables.VariableDefinition; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.*; +import fr.jamailun.ultimatespellsystem.dsl2.visitor.ExpressionVisitor; +import lombok.Getter; +import org.jetbrains.annotations.NotNull; + +/** + * Either {@code increment} or {@code decrement}. + */ +@Getter +public class IncrementExpression extends ExpressionNode { + + private final String varName; + private final boolean positive; + private final boolean afterVar; + + public IncrementExpression(@NotNull Token identifierToken, boolean positive, boolean afterVar) { + super(identifierToken.pos()); + this.varName = identifierToken.getContentString(); + this.positive = positive; + this.afterVar = afterVar; + } + + @Override + public void validateTypes(@NotNull TypesContext context) { + VariableDefinition variableDefinition = context.findVariable(varName); + if(variableDefinition == null) + throw new SyntaxException(firstTokenPosition(), "Unknown variable to " + (positive?"increment":"decrement") + " : '" + varName + "'."); + + Type type = variableDefinition.getType(context); + if(!type.is(TypePrimitive.NUMBER)) + throw new TypeException(firstTokenPosition(), "For " + (positive?"increment":"decrement") + " %"+varName+", expected NUMBER. Got type " + type + "."); + } + + @Override + public void visit(@NotNull ExpressionVisitor visitor) { + visitor.handleIncrementDecrement(this); + } + + /** + * Parse a increment/decrement statement. + * @param tokens streams of tokens. + * @return a new instance. + */ + @PreviousIndicator(expected = {TokenType.INCREMENT, TokenType.DECREMENT}) + public static @NotNull IncrementExpression parseIncrementOrDecrement(@NotNull TokenStream tokens, boolean increment) { + Token var = tokens.nextOrThrow(TokenType.IDENTIFIER, "After an " + (increment?"INCREMENT":"DECREMENT")+ " a variable name is required."); + tokens.dropOptional(TokenType.SEMI_COLON); + return new IncrementExpression(var, increment, false); + } + + @Override + public String toString() { + String symbol = positive ?"++":"--"; + return afterVar ? varName + symbol : symbol + varName; + } + + @Override + public @NotNull Type getExpressionType() { + return Type.of(TypePrimitive.NUMBER); + } +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/Operator.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/Operator.java index 37e06ee2..af8ccb17 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/Operator.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/Operator.java @@ -1,7 +1,9 @@ package fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.operators; +import fr.jamailun.ultimatespellsystem.dsl2.errors.SyntaxException; import fr.jamailun.ultimatespellsystem.dsl2.nodes.ExpressionNode; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenPosition; import org.jetbrains.annotations.NotNull; @@ -29,7 +31,10 @@ protected Operator(@NotNull TokenPosition position) { */ protected void assertNotMathIncompatible(@NotNull Type a) { //TODO FIXME !! - throw new UnsupportedOperationException("todo"); + boolean canBeAdded = a.is(TypePrimitive.DURATION) || a.is(TypePrimitive.NUMBER); + if(!canBeAdded) { + throw new SyntaxException(firstTokenPosition(), "The type " + a + " cannot be added."); + } } @Override diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/IncrementStatement.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/IncrementStatement.java deleted file mode 100644 index 3f63e3e2..00000000 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/IncrementStatement.java +++ /dev/null @@ -1,60 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl2.nodes.statements; - -import fr.jamailun.ultimatespellsystem.dsl2.errors.SyntaxException; -import fr.jamailun.ultimatespellsystem.dsl2.errors.TypeException; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.StatementNode; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.variables.TypesContext; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.variables.VariableDefinition; -import fr.jamailun.ultimatespellsystem.dsl2.tokenization.*; -import fr.jamailun.ultimatespellsystem.dsl2.visitor.StatementVisitor; -import lombok.Getter; -import lombok.RequiredArgsConstructor; -import org.jetbrains.annotations.NotNull; - -/** - * Either {@code increment} or {@code decrement}. - */ -@Getter -@RequiredArgsConstructor -public class IncrementStatement extends StatementNode { - - private final TokenPosition tokenPosition; - private final String varName; - private final boolean positive; - private final boolean afterVar; - - @Override - public void validateTypes(@NotNull TypesContext context) { - VariableDefinition variableDefinition = context.findVariable(varName); - if(variableDefinition == null) - throw new SyntaxException(tokenPosition, "Unknown variable to " + (positive?"increment":"decrement") + " : '" + varName + "'."); - - Type type = variableDefinition.getType(context); - if(!type.is(TypePrimitive.NUMBER)) - throw new TypeException(tokenPosition, "For " + (positive?"increment":"decrement") + " %"+varName+", expected NUMBER. Got type " + type + "."); - } - - @Override - public void visit(@NotNull StatementVisitor visitor) { - visitor.handleIncrement(this); - } - - /** - * Parse a increment/decrement statement. - * @param tokens streams of tokens. - * @return a new instance. - */ - @PreviousIndicator(expected = {TokenType.INCREMENT, TokenType.DECREMENT}) - public static @NotNull IncrementStatement parseIncrementOrDecrement(@NotNull TokenStream tokens, boolean increment) { - Token var = tokens.nextOrThrow(TokenType.IDENTIFIER); - tokens.dropOptional(TokenType.SEMI_COLON); - return new IncrementStatement(var.pos(), var.getContentString(), increment, false); - } - - @Override - public String toString() { - return (positive ?"++":"--") + "%" + varName; - } -} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/validators/StructureValidationVisitor.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/validators/StructureValidationVisitor.java index e4275806..4cbf6b5f 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/validators/StructureValidationVisitor.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/validators/StructureValidationVisitor.java @@ -90,8 +90,6 @@ public void handleFunctionDeclaration(@NotNull FunctionDeclarationStatement stat //TODO ?? } - @Override - public void handleIncrement(@NotNull IncrementStatement statement) {handleMono();} @Override public void handleSimpleExpression(@NotNull SimpleExpressionStatement statement) {handleMono();} } diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/ExpressionVisitor.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/ExpressionVisitor.java index 333f97bc..a643e6dd 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/ExpressionVisitor.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/ExpressionVisitor.java @@ -2,8 +2,7 @@ import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.*; import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.litteral.*; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.operators.BiOperator; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.operators.MonoOperator; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.operators.*; import org.jetbrains.annotations.NotNull; /** @@ -27,6 +26,7 @@ public interface ExpressionVisitor { void handleArrayGet(@NotNull ArrayGetterExpression arrayGetter); void handleFieldGet(@NotNull FieldGetExpression fieldGetter); void handleFunctionCall(@NotNull FunctionCallExpression functionCall); + void handleIncrementDecrement(@NotNull IncrementExpression expression); // Specifics void handleArray(@NotNull ArrayLiteral expression); diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/PrintingVisitor.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/PrintingVisitor.java index 61126bac..8ba19404 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/PrintingVisitor.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/PrintingVisitor.java @@ -5,6 +5,7 @@ import fr.jamailun.ultimatespellsystem.dsl2.nodes.StatementNode; import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.litteral.*; import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.operators.BiOperator; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.operators.IncrementExpression; import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.operators.MonoOperator; import fr.jamailun.ultimatespellsystem.dsl2.nodes.statements.*; import fr.jamailun.ultimatespellsystem.dsl2.nodes.statements.blocks.ForLoopStatement; @@ -169,9 +170,13 @@ public void handleBlock(@NotNull BlockStatement statement) { } @Override - public void handleIncrement(@NotNull IncrementStatement statement) { - builder.append(statement.isPositive() ? "++" : "--") - .append("%").append(statement.getVarName()); + public void handleIncrementDecrement(@NotNull IncrementExpression expression) { + String symbol = expression.isPositive() ? "++" : "--"; + if(expression.isAfterVar()) { + builder.append(expression.getVarName()).append(symbol); + } else { + builder.append(symbol).append(expression.getVarName()); + } } diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/StatementVisitor.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/StatementVisitor.java index f32ecc76..4c127ce0 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/StatementVisitor.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/StatementVisitor.java @@ -17,7 +17,6 @@ public interface StatementVisitor { void handleReturn(@NotNull ReturnStatement statement); void handleBlock(@NotNull BlockStatement statement); - void handleIncrement(@NotNull IncrementStatement statement); void handleSimpleExpression(@NotNull SimpleExpressionStatement statement); void handleIf(@NotNull IfElseStatement statement); diff --git a/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/ParsingTest.java b/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/ParsingTest.java index 03ecbaee..9507d2df 100644 --- a/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/ParsingTest.java +++ b/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/ParsingTest.java @@ -90,8 +90,7 @@ protected void printResults() { } System.out.println("\n" + WHITE_BOLD + "=====================================================" + RESET + "\n"); - if(!failures.isEmpty()) - System.exit(42); + Assertions.assertTrue(failures.isEmpty(), "Some tests failed."); } } diff --git a/dsl2/src/test/resources/parsing/corrects/basics/increment_add.uss b/dsl2/src/test/resources/parsing/corrects/basics/increment_add.uss new file mode 100644 index 00000000..38f0537e --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/basics/increment_add.uss @@ -0,0 +1,3 @@ +int a = 0; +int b = a++ + 1; +int c = ++a + 1; diff --git a/dsl2/src/test/resources/parsing/corrects/basics/increment_decrement.uss b/dsl2/src/test/resources/parsing/corrects/basics/increment_decrement.uss new file mode 100644 index 00000000..c31d77d1 --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/basics/increment_decrement.uss @@ -0,0 +1,5 @@ +int a = 0; +a++; +++a; +#a--; +#--a; From 5bd077a9b014791211c8994da94a4f98377ee751 Mon Sep 17 00:00:00 2001 From: "timothe.rosaz" Date: Fri, 24 Oct 2025 22:43:38 +0200 Subject: [PATCH 15/38] Bad increment tests. --- .../test/resources/parsing/invalid/bad_syntax/bad_increment.uss | 1 + .../test/resources/parsing/invalid/bad_type/increment_type.uss | 2 ++ 2 files changed, 3 insertions(+) create mode 100644 dsl2/src/test/resources/parsing/invalid/bad_syntax/bad_increment.uss create mode 100644 dsl2/src/test/resources/parsing/invalid/bad_type/increment_type.uss diff --git a/dsl2/src/test/resources/parsing/invalid/bad_syntax/bad_increment.uss b/dsl2/src/test/resources/parsing/invalid/bad_syntax/bad_increment.uss new file mode 100644 index 00000000..2506c9d9 --- /dev/null +++ b/dsl2/src/test/resources/parsing/invalid/bad_syntax/bad_increment.uss @@ -0,0 +1 @@ +++12; \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing/invalid/bad_type/increment_type.uss b/dsl2/src/test/resources/parsing/invalid/bad_type/increment_type.uss new file mode 100644 index 00000000..ba3a34f3 --- /dev/null +++ b/dsl2/src/test/resources/parsing/invalid/bad_type/increment_type.uss @@ -0,0 +1,2 @@ +string a = "a"; +a++; \ No newline at end of file From bdae58c753420a4768af9ddd2e99bce31b29737f Mon Sep 17 00:00:00 2001 From: "timothe.rosaz" Date: Fri, 24 Oct 2025 22:59:18 +0200 Subject: [PATCH 16/38] Cleanup, added tests --- .../dsl2/errors/ParsingException.java | 1 + .../dsl2/tokenization/TokenType.java | 12 +++--------- .../dsl2/CorrectParsingTests.java | 10 ++++++++++ .../dsl2/FailuresParsingTests.java | 5 +++++ .../resources/parsing/corrects/arrays/basic_get.uss | 2 ++ .../resources/parsing/corrects/arrays/multi_get.uss | 4 ++++ .../resources/parsing/corrects/parsing/numbers.uss | 3 +++ .../parsing/invalid/bad_parsing/bad_time_unit.uss | 1 + .../parsing/invalid/bad_parsing/string_invalid.uss | 3 +++ .../invalid/bad_parsing/string_not_ending.uss | 1 + .../parsing/invalid/bad_syntax/unknown_variable.uss | 1 + .../parsing/invalid/bad_type/bad_array_get.uss | 2 ++ 12 files changed, 36 insertions(+), 9 deletions(-) create mode 100644 dsl2/src/test/resources/parsing/corrects/arrays/basic_get.uss create mode 100644 dsl2/src/test/resources/parsing/corrects/arrays/multi_get.uss create mode 100644 dsl2/src/test/resources/parsing/corrects/parsing/numbers.uss create mode 100644 dsl2/src/test/resources/parsing/invalid/bad_parsing/bad_time_unit.uss create mode 100644 dsl2/src/test/resources/parsing/invalid/bad_parsing/string_invalid.uss create mode 100644 dsl2/src/test/resources/parsing/invalid/bad_parsing/string_not_ending.uss create mode 100644 dsl2/src/test/resources/parsing/invalid/bad_syntax/unknown_variable.uss create mode 100644 dsl2/src/test/resources/parsing/invalid/bad_type/bad_array_get.uss diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/errors/ParsingException.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/errors/ParsingException.java index 231be5bd..9ea5752b 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/errors/ParsingException.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/errors/ParsingException.java @@ -3,6 +3,7 @@ import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenPosition; import org.jetbrains.annotations.NotNull; + /** * Exception throw in the parsing phase. */ diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/tokenization/TokenType.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/tokenization/TokenType.java index 9f81d736..4f088f4e 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/tokenization/TokenType.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/tokenization/TokenType.java @@ -1,5 +1,7 @@ package fr.jamailun.ultimatespellsystem.dsl2.tokenization; +import org.jetbrains.annotations.NotNull; + /** * Type of token. */ @@ -79,16 +81,8 @@ public enum TokenType { this.letters = letters; } - public Token toToken(TokenPosition position) { + public @NotNull Token toToken(@NotNull TokenPosition position) { return new Token(this, position); } - public boolean isRawValue() { - return this == IDENTIFIER || - this == VALUE_STRING || - this == VALUE_NUMBER || - this == VALUE_DURATION || - this == VALUE_BOOLEAN ; - } - } diff --git a/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/CorrectParsingTests.java b/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/CorrectParsingTests.java index 4067bd5e..1a2f6f00 100644 --- a/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/CorrectParsingTests.java +++ b/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/CorrectParsingTests.java @@ -11,6 +11,11 @@ */ public class CorrectParsingTests extends ParsingTest { + @Test + void correctParsing() { + testFolder("corrects/parsing"); + } + @Test void correctBasics() { testFolder("corrects/basics"); @@ -31,6 +36,11 @@ void correctFunctions() { testFolder("corrects/functions"); } + @Test + void correctArrays() { + testFolder("corrects/arrays"); + } + // -- private void testFolder(@NotNull String folder) { diff --git a/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/FailuresParsingTests.java b/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/FailuresParsingTests.java index 77dd788e..7f0bea35 100644 --- a/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/FailuresParsingTests.java +++ b/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/FailuresParsingTests.java @@ -21,6 +21,11 @@ void badSyntax() { badParsing("invalid/bad_syntax", SyntaxException.class); } + @Test + void badParsing() { + badParsing("invalid/bad_parsing", ParsingException.class); + } + private void badParsing(@NotNull String folder, @NotNull Class clazz) { String title = "[! EXPECTED "+clazz.getSimpleName()+"] "; for(File file : listTests(folder)) { diff --git a/dsl2/src/test/resources/parsing/corrects/arrays/basic_get.uss b/dsl2/src/test/resources/parsing/corrects/arrays/basic_get.uss new file mode 100644 index 00000000..5df3f66f --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/arrays/basic_get.uss @@ -0,0 +1,2 @@ +var arr = [1, 2, 3]; +int a = arr[1]; \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing/corrects/arrays/multi_get.uss b/dsl2/src/test/resources/parsing/corrects/arrays/multi_get.uss new file mode 100644 index 00000000..a86ecd04 --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/arrays/multi_get.uss @@ -0,0 +1,4 @@ +var arr = [[1, 2, 3], [4, 5, 6]]; +var l1 = arr[1]; +int v1 = l1[0]; +int v2 = arr[0][0]; \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing/corrects/parsing/numbers.uss b/dsl2/src/test/resources/parsing/corrects/parsing/numbers.uss new file mode 100644 index 00000000..c782a4fe --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/parsing/numbers.uss @@ -0,0 +1,3 @@ +int a = 1; +int b = 1.2; +int c = .3; \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing/invalid/bad_parsing/bad_time_unit.uss b/dsl2/src/test/resources/parsing/invalid/bad_parsing/bad_time_unit.uss new file mode 100644 index 00000000..feecaa18 --- /dev/null +++ b/dsl2/src/test/resources/parsing/invalid/bad_parsing/bad_time_unit.uss @@ -0,0 +1 @@ +var oupsi = minutes; \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing/invalid/bad_parsing/string_invalid.uss b/dsl2/src/test/resources/parsing/invalid/bad_parsing/string_invalid.uss new file mode 100644 index 00000000..95ec3462 --- /dev/null +++ b/dsl2/src/test/resources/parsing/invalid/bad_parsing/string_invalid.uss @@ -0,0 +1,3 @@ +string val = "a +a +a"; \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing/invalid/bad_parsing/string_not_ending.uss b/dsl2/src/test/resources/parsing/invalid/bad_parsing/string_not_ending.uss new file mode 100644 index 00000000..621fa54c --- /dev/null +++ b/dsl2/src/test/resources/parsing/invalid/bad_parsing/string_not_ending.uss @@ -0,0 +1 @@ +string val = " \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing/invalid/bad_syntax/unknown_variable.uss b/dsl2/src/test/resources/parsing/invalid/bad_syntax/unknown_variable.uss new file mode 100644 index 00000000..a7b41895 --- /dev/null +++ b/dsl2/src/test/resources/parsing/invalid/bad_syntax/unknown_variable.uss @@ -0,0 +1 @@ +int a = i_do_not_exist + 1; \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing/invalid/bad_type/bad_array_get.uss b/dsl2/src/test/resources/parsing/invalid/bad_type/bad_array_get.uss new file mode 100644 index 00000000..1cf29111 --- /dev/null +++ b/dsl2/src/test/resources/parsing/invalid/bad_type/bad_array_get.uss @@ -0,0 +1,2 @@ +var a = [1, 2, 3]; +string v = a[0]; \ No newline at end of file From a20f8088af8710cc617f4709f078617db311b4a0 Mon Sep 17 00:00:00 2001 From: "timothe.rosaz" Date: Sat, 25 Oct 2025 17:18:58 +0200 Subject: [PATCH 17/38] Fixed console type, caller functions, global functions --- .../dsl2/UltimateSpellSystemDSL2.java | 2 + .../dsl2/library/StructDefinition.java | 2 +- .../dsl2/library/structs/ConsoleStruct.java | 45 ++++++++++++ .../dsl2/library/structs/EntityStruct.java | 17 ++++- .../dsl2/nodes/ExpressionNode.java | 13 +++- .../expressions/FunctionCallExpression.java | 69 ++++++++++++++++--- .../FunctionDeclarationStatement.java | 24 +++++++ .../dsl2/nodes/type/Type.java | 8 +++ .../nodes/type/variables/TypesContext.java | 13 +++- .../dsl2/visitor/PrintingVisitor.java | 7 +- .../parsing/corrects/basics/block_if.uss | 2 +- .../parsing/corrects/basics/block_if_else.uss | 4 +- .../corrects/basics/block_if_elseif.uss | 6 +- .../parsing/corrects/basics/field_access.uss | 2 +- .../corrects/functions/fuction_call.uss | 5 ++ .../corrects/parsing/string_escape.uss | 1 + 16 files changed, 196 insertions(+), 24 deletions(-) create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/library/structs/ConsoleStruct.java create mode 100644 dsl2/src/test/resources/parsing/corrects/functions/fuction_call.uss create mode 100644 dsl2/src/test/resources/parsing/corrects/parsing/string_escape.uss diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/UltimateSpellSystemDSL2.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/UltimateSpellSystemDSL2.java index 7512e2da..349d7ffa 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/UltimateSpellSystemDSL2.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/UltimateSpellSystemDSL2.java @@ -1,5 +1,6 @@ package fr.jamailun.ultimatespellsystem.dsl2; +import fr.jamailun.ultimatespellsystem.dsl2.library.structs.ConsoleStruct; import fr.jamailun.ultimatespellsystem.dsl2.library.structs.EntityStruct; import fr.jamailun.ultimatespellsystem.dsl2.metadata.rules.DefaultMetadataRules; import fr.jamailun.ultimatespellsystem.dsl2.nodes.ExpressionNode; @@ -26,6 +27,7 @@ private UltimateSpellSystemDSL2() {} DefaultMetadataRules.initialize(); // ObjectsDefinitionRegistry.registerDefaultStruct(new EntityStruct()); + ObjectsDefinitionRegistry.registerDefaultStruct(new ConsoleStruct()); } /** diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/library/StructDefinition.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/library/StructDefinition.java index 1d6ec4fc..fc65ef9c 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/library/StructDefinition.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/library/StructDefinition.java @@ -40,7 +40,7 @@ public void registerFunction(@NotNull FunctionDefinition function) { return fields.get(fieldName); } - public @NotNull FunctionDefinition getFunction(@NotNull String functionName) { + public @Nullable FunctionDefinition getFunction(@NotNull String functionName) { return functions.get(functionName); } diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/library/structs/ConsoleStruct.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/library/structs/ConsoleStruct.java new file mode 100644 index 00000000..79e1767b --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/library/structs/ConsoleStruct.java @@ -0,0 +1,45 @@ +package fr.jamailun.ultimatespellsystem.dsl2.library.structs; + +import fr.jamailun.ultimatespellsystem.dsl2.library.StructDefinition; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionDefinition; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; + +public class ConsoleStruct extends StructDefinition { + + public static final String NAME = "console"; + + public ConsoleStruct() { + super(NAME); + initFunctions(); + } + + private void initFunctions() { + registerFunction(FunctionDefinition.of( + "send", + TypePrimitive.NULL.asType(), + FunctionArgument.of(TypePrimitive.STRING) + )); + registerFunction(FunctionDefinition.of( + "info", + TypePrimitive.NULL.asType(), + FunctionArgument.of(TypePrimitive.STRING) + )); + registerFunction(FunctionDefinition.of( + "debug", + TypePrimitive.NULL.asType(), + FunctionArgument.of(TypePrimitive.STRING) + )); + registerFunction(FunctionDefinition.of( + "warning", + TypePrimitive.NULL.asType(), + FunctionArgument.of(TypePrimitive.STRING) + )); + registerFunction(FunctionDefinition.of( + "error", + TypePrimitive.NULL.asType(), + FunctionArgument.of(TypePrimitive.STRING) + )); + } + +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/library/structs/EntityStruct.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/library/structs/EntityStruct.java index 0dd70f82..94c839fc 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/library/structs/EntityStruct.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/library/structs/EntityStruct.java @@ -6,8 +6,11 @@ import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; public class EntityStruct extends StructDefinition { + + public static final String NAME = "entity"; + public EntityStruct() { - super("entity"); + super(NAME); initFields(); initFunctions(); } @@ -46,6 +49,18 @@ private void initFunctions() { TypePrimitive.NULL.asType(), FunctionArgument.of(TypePrimitive.NUMBER) )); + + registerFunction(FunctionDefinition.of( + "send", + TypePrimitive.NULL.asType(), + FunctionArgument.of(TypePrimitive.STRING) + )); + + registerFunction(FunctionDefinition.of( + "send_message", + TypePrimitive.NULL.asType(), + FunctionArgument.of(TypePrimitive.STRING) + )); } } diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/ExpressionNode.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/ExpressionNode.java index 3156e523..25e998ac 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/ExpressionNode.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/ExpressionNode.java @@ -128,6 +128,14 @@ protected ExpressionNode(@NotNull TokenPosition position) { return new IncrementExpression(first, false, true); } + // IDENTIFIER( ? + if(tokens.dropOptional(TokenType.BRACKET_OPEN)) { + List arguments = parseArgumentsParameter(tokens); + ExpressionNode expression = new FunctionCallExpression(null, first, arguments); + return parseIdentifierExpression(expression, tokens); + } + + ExpressionNode left = new ReferenceExpression(first); return parseIdentifierExpression(left, tokens); } @@ -145,8 +153,7 @@ protected ExpressionNode(@NotNull TokenPosition position) { // a.IDENTIFIER(...) if(tokens.dropOptional(TokenType.BRACKET_OPEN)) { List arguments = parseArgumentsParameter(tokens); - String fctName = identifier.getContentString(); - ExpressionNode fctCall = new FunctionCallExpression(left, fctName, arguments); + ExpressionNode fctCall = new FunctionCallExpression(left, identifier, arguments); // Après "a.b(...)" on peut avoir une suite. Donc, on refait une boucle. return parseIdentifierExpression(fctCall, tokens); @@ -175,7 +182,7 @@ protected ExpressionNode(@NotNull TokenPosition position) { return left; } - public static List parseArgumentsParameter(@NotNull TokenStream tokens) { + public static @NotNull List parseArgumentsParameter(@NotNull TokenStream tokens) { List list = new ArrayList<>(); boolean first = true; while(!tokens.dropOptional(TokenType.BRACKET_CLOSE)) { diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/FunctionCallExpression.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/FunctionCallExpression.java index 0c453e29..351a2eb7 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/FunctionCallExpression.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/FunctionCallExpression.java @@ -1,41 +1,92 @@ package fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions; +import fr.jamailun.ultimatespellsystem.dsl2.errors.SyntaxException; +import fr.jamailun.ultimatespellsystem.dsl2.errors.TypeException; +import fr.jamailun.ultimatespellsystem.dsl2.library.StructDefinition; import fr.jamailun.ultimatespellsystem.dsl2.nodes.ExpressionNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionDefinition; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.statements.FunctionDeclarationStatement; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.variables.TypesContext; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.Token; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenPosition; import fr.jamailun.ultimatespellsystem.dsl2.visitor.ExpressionVisitor; import lombok.Getter; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.List; +import java.util.Objects; @Getter public class FunctionCallExpression extends ExpressionNode { - private final ExpressionNode caller; + private Type runtimeType = null; + + private final TokenPosition position; + private final @Nullable ExpressionNode caller; private final String functionName; private final List arguments; - public FunctionCallExpression(@NotNull ExpressionNode caller, @NotNull String functionName, @NotNull List arguments) { - super(caller.firstTokenPosition()); + public FunctionCallExpression(@Nullable ExpressionNode caller, @NotNull Token functionName, @NotNull List arguments) { + super(functionName.pos()); this.caller = caller; - this.functionName = functionName; + this.position = functionName.pos(); + this.functionName = functionName.getContentString(); this.arguments = arguments; } @Override public @NotNull Type getExpressionType() { - // Pas facile : il faut un registre de définition. - // Ne peut être su qu'après avoir défini toutes les "classes". - throw new UnsupportedOperationException("Not supported yet."); + assert runtimeType != null; + return runtimeType; } @Override public void validateTypes(@NotNull TypesContext context) { - // 1. On vérifie que nos arguments existent :) + // 1. Propagate to arguments for(ExpressionNode argument : arguments) { argument.validateTypes(context.childContext()); } + + // 2. If we have a caller : we check the function from the type definition. + FunctionDefinition function; + if(caller != null) { + caller.validateTypes(context); + Type callerType = caller.getExpressionType(); + StructDefinition struct = context.findStruct(callerType); + if(struct == null) { + throw new TypeException(position, "Unknown struct for type " + callerType); + } + function = struct.getFunction(functionName); + if(function == null) { + throw new TypeException(position, "Cannot call function '" + functionName + "' on type " + callerType + "."); + } + } + // Pas de caller : function globale + else { + FunctionDeclarationStatement declaration = context.findFunction(functionName); + if(declaration == null) { + throw new SyntaxException(position, "Function '" + functionName + "' not found"); + } + function = declaration.asFunctionDefinition(); + } + + // 3. Set our type + this.runtimeType = function.returnedType(); + + // 4. Check arguments list match requested types + if(arguments.size() != function.arguments().size()) { + throw new SyntaxException(position, "Function argument count mismatch. Expected " + function.arguments().size() + " but got " + arguments.size() + "."); + } + for(int i = 0; i < arguments.size(); i++) { + ExpressionNode arg = arguments.get(i); + FunctionArgument def = function.arguments().get(i); + if(!Objects.equals(arg.getExpressionType(), def.type())) { + throw new TypeException(arg.firstTokenPosition(), "Bad argument type. Function " + functionName + " expected " + def.type() + " on argument n°" + (i+1) + ", but got " + arg.getExpressionType() + "."); + } + } } @Override @@ -45,6 +96,6 @@ public void visit(@NotNull ExpressionVisitor visitor) { @Override public String toString() { - return caller + "." + functionName + "(" + arguments + ")"; + return (caller == null ? "" : caller + ".") + functionName + "(" + arguments + ")"; } } diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/FunctionDeclarationStatement.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/FunctionDeclarationStatement.java index 56860000..a5f974ce 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/FunctionDeclarationStatement.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/FunctionDeclarationStatement.java @@ -2,6 +2,9 @@ import fr.jamailun.ultimatespellsystem.dsl2.errors.SyntaxException; import fr.jamailun.ultimatespellsystem.dsl2.nodes.StatementNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionDefinition; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.variables.TypesContext; import fr.jamailun.ultimatespellsystem.dsl2.tokenization.Token; import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenPosition; @@ -30,6 +33,10 @@ public void visit(@NotNull StatementVisitor visitor) { visitor.handleFunctionDeclaration(this); } + public @NotNull Type getOutputType() { + return Type.ofAny(functionReturnType); + } + @Override public void validateTypes(@NotNull TypesContext context) { // 1. Check function does not already exist @@ -91,4 +98,21 @@ public String toString() { public @NotNull String signature() { return functionReturnType + " " + functionName + "(" + String.join(", ", getParameters().stream().map(Object::toString).toList()) + ")"; } + + /** + * Create a function declaration instance from this function declaration. + * @return a new function definition. + */ + public @NotNull FunctionDefinition asFunctionDefinition() { + return new FunctionDefinition( + functionName, + getOutputType(), + parameters.stream() + .map(p -> new FunctionArgument( + Type.ofAny(p.type), + p.name, + false + )).toList() + ); + } } diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/Type.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/Type.java index 4c2d8b55..edb9400c 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/Type.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/Type.java @@ -65,6 +65,10 @@ public boolean isNull() { return is(TypePrimitive.NULL); } + public boolean isPrimitive() { + return primitive != null; + } + @Contract(pure = true) public @NotNull Type popArray() { return new Type(primitive, objectClass, Math.max(0, arrayLevel - 1)); @@ -75,6 +79,10 @@ public boolean isNull() { return new Type(primitive, objectClass, arrayLevel + 1); } + public @NotNull String getName() { + return primitive == null ? Objects.requireNonNull(objectClass) : primitive.name(); + } + @Contract(pure = true) @Override public @NotNull String toString() { diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/variables/TypesContext.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/variables/TypesContext.java index 926784e7..6e9c6b87 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/variables/TypesContext.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/variables/TypesContext.java @@ -3,6 +3,8 @@ import fr.jamailun.ultimatespellsystem.dsl2.errors.SyntaxException; import fr.jamailun.ultimatespellsystem.dsl2.library.ObjectsLibrary; import fr.jamailun.ultimatespellsystem.dsl2.library.StructDefinition; +import fr.jamailun.ultimatespellsystem.dsl2.library.structs.ConsoleStruct; +import fr.jamailun.ultimatespellsystem.dsl2.library.structs.EntityStruct; import fr.jamailun.ultimatespellsystem.dsl2.nodes.ExpressionNode; import fr.jamailun.ultimatespellsystem.dsl2.nodes.statements.FunctionDeclarationStatement; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; @@ -28,7 +30,8 @@ public class TypesContext { */ public TypesContext() { this.objectsLibrary = new ObjectsLibrary(true); - promiseVariable("caster", Type.of("entity")); + promiseVariable("caster", Type.of(EntityStruct.NAME)); + promiseVariable("console", Type.of(ConsoleStruct.NAME)); } /** @@ -100,6 +103,14 @@ public void registerVariable(@NotNull TokenPosition position, @NotNull String va return objectsLibrary.getStruct(name); } + public @Nullable StructDefinition findStruct(@NotNull Type type) { + if(type.isPrimitive()) { + //TODO specialized structs ? + return null; + } + return objectsLibrary.getStruct(type.getName()); + } + /** * Register a new function to the context * @param declaration the declaration to use. diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/PrintingVisitor.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/PrintingVisitor.java index 8ba19404..4fd4ecb6 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/PrintingVisitor.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/PrintingVisitor.java @@ -355,8 +355,11 @@ public void handleFieldGet(@NotNull FieldGetExpression fieldGetter) { @Override public void handleFunctionCall(@NotNull FunctionCallExpression functionCall) { - functionCall.getCaller().visit(this); - builder.append(".").append(functionCall.getFunctionName()).append("("); + if(functionCall.getCaller() != null) { + functionCall.getCaller().visit(this); + builder.append("."); + } + builder.append(functionCall.getFunctionName()).append("("); boolean first = true; for(ExpressionNode arg : functionCall.getArguments()) { if(first) first = false; else builder.append(", "); diff --git a/dsl2/src/test/resources/parsing/corrects/basics/block_if.uss b/dsl2/src/test/resources/parsing/corrects/basics/block_if.uss index 8be32932..708866a3 100644 --- a/dsl2/src/test/resources/parsing/corrects/basics/block_if.uss +++ b/dsl2/src/test/resources/parsing/corrects/basics/block_if.uss @@ -1,4 +1,4 @@ bool a = false; if(a == true || false) { - console.log("ok"); + console.info("ok"); } \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing/corrects/basics/block_if_else.uss b/dsl2/src/test/resources/parsing/corrects/basics/block_if_else.uss index b05fe097..108d21d8 100644 --- a/dsl2/src/test/resources/parsing/corrects/basics/block_if_else.uss +++ b/dsl2/src/test/resources/parsing/corrects/basics/block_if_else.uss @@ -1,6 +1,6 @@ bool a = false; if(a == true || false) { - console.log("ok"); + console.info("ok"); } else { - console.log("non"); + console.info("non"); } \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing/corrects/basics/block_if_elseif.uss b/dsl2/src/test/resources/parsing/corrects/basics/block_if_elseif.uss index a00ea6ad..ae9c3e9b 100644 --- a/dsl2/src/test/resources/parsing/corrects/basics/block_if_elseif.uss +++ b/dsl2/src/test/resources/parsing/corrects/basics/block_if_elseif.uss @@ -1,8 +1,8 @@ bool a = false; if(a) { - console.log("ok"); + console.info("ok"); } else if(!a) { - console.log("non"); + console.info("non"); } else { - console.log("??"); + console.info("??"); } \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing/corrects/basics/field_access.uss b/dsl2/src/test/resources/parsing/corrects/basics/field_access.uss index 14c198ca..d4b90e43 100644 --- a/dsl2/src/test/resources/parsing/corrects/basics/field_access.uss +++ b/dsl2/src/test/resources/parsing/corrects/basics/field_access.uss @@ -1 +1 @@ -console.log("test"); +console.info("test"); diff --git a/dsl2/src/test/resources/parsing/corrects/functions/fuction_call.uss b/dsl2/src/test/resources/parsing/corrects/functions/fuction_call.uss new file mode 100644 index 00000000..012da562 --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/functions/fuction_call.uss @@ -0,0 +1,5 @@ +void foo() { + int a = 2; +} + +foo(); diff --git a/dsl2/src/test/resources/parsing/corrects/parsing/string_escape.uss b/dsl2/src/test/resources/parsing/corrects/parsing/string_escape.uss new file mode 100644 index 00000000..10dcd06f --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/parsing/string_escape.uss @@ -0,0 +1 @@ +var a = "a\"b"; \ No newline at end of file From 2cf8eda2984ac71b8746c3d45f3772ef8181a7e2 Mon Sep 17 00:00:00 2001 From: "timothe.rosaz" Date: Sat, 25 Oct 2025 17:29:47 +0200 Subject: [PATCH 18/38] Functions call properly register their new variables. --- .../expressions/FunctionCallExpression.java | 2 +- .../FunctionDeclarationStatement.java | 23 +++++++++++-------- .../dsl2/objects/CallbackEvent.java | 2 +- .../corrects/functions/function_call_args.uss | 5 ++++ .../corrects/functions/function_call_expr.uss | 6 +++++ .../function_call_void_expression.uss | 5 ++++ .../invalid/bad_syntax/unknown_function.uss | 1 + .../bad_type/function_call_bad_args.uss | 5 ++++ 8 files changed, 38 insertions(+), 11 deletions(-) create mode 100644 dsl2/src/test/resources/parsing/corrects/functions/function_call_args.uss create mode 100644 dsl2/src/test/resources/parsing/corrects/functions/function_call_expr.uss create mode 100644 dsl2/src/test/resources/parsing/invalid/bad_syntax/function_call_void_expression.uss create mode 100644 dsl2/src/test/resources/parsing/invalid/bad_syntax/unknown_function.uss create mode 100644 dsl2/src/test/resources/parsing/invalid/bad_type/function_call_bad_args.uss diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/FunctionCallExpression.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/FunctionCallExpression.java index 351a2eb7..559c1f09 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/FunctionCallExpression.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/FunctionCallExpression.java @@ -68,7 +68,7 @@ public void validateTypes(@NotNull TypesContext context) { else { FunctionDeclarationStatement declaration = context.findFunction(functionName); if(declaration == null) { - throw new SyntaxException(position, "Function '" + functionName + "' not found"); + throw new SyntaxException(position, "Global function '" + functionName + "' not found"); } function = declaration.asFunctionDefinition(); } diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/FunctionDeclarationStatement.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/FunctionDeclarationStatement.java index a5f974ce..095102bd 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/FunctionDeclarationStatement.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/FunctionDeclarationStatement.java @@ -45,16 +45,17 @@ public void validateTypes(@NotNull TypesContext context) { throw new SyntaxException(position, "The function '" + functionName + "' has already been defined. Signature is " + existingFunction.signature()); } - // 2. Propagate to children + // 2. Register function and variables ! + context.registerFunction(this); + for(FunctionParameter parameter : parameters) { + context.registerVariable(position, parameter.name, parameter.getType()); + } + + // 3. Propagate to children TypesContext child = context.childContext(); for(StatementNode statement : statements) { statement.validateTypes(child); } - - //TODO Validate tree and return ! - - // Register function - context.registerFunction(this); } public static @NotNull FunctionDeclarationStatement parseNextFunction(@NotNull Token typeIdentifier, @NotNull Token nameIdentifier, @NotNull TokenStream tokens) { @@ -84,7 +85,11 @@ public void validateTypes(@NotNull TypesContext context) { return new FunctionDeclarationStatement(typeIdentifier.pos(), functionReturnType, functionName, parameters, statements); } - public record FunctionParameter(String type, String name) {} + public record FunctionParameter(@NotNull String type, @NotNull String name) { + public @NotNull Type getType() { + return Type.ofAny(type); + } + } @Override public String toString() { @@ -109,8 +114,8 @@ public String toString() { getOutputType(), parameters.stream() .map(p -> new FunctionArgument( - Type.ofAny(p.type), - p.name, + p.getType(), + p.name(), false )).toList() ); diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/objects/CallbackEvent.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/objects/CallbackEvent.java index cc482b7d..f8f14bbd 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/objects/CallbackEvent.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/objects/CallbackEvent.java @@ -15,7 +15,7 @@ public record CallbackEvent(@NotNull String name, @Nullable CallbackArgument arg public CallbackEvent { if(name.indexOf(' ') > -1) { - throw new RuntimeException("Invalid callback name. Cannot contain spaces."); + throw new IllegalArgumentException("Invalid callback name. Cannot contain spaces."); } } diff --git a/dsl2/src/test/resources/parsing/corrects/functions/function_call_args.uss b/dsl2/src/test/resources/parsing/corrects/functions/function_call_args.uss new file mode 100644 index 00000000..5902c36c --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/functions/function_call_args.uss @@ -0,0 +1,5 @@ +void foo(int a, string b) { + console.info("a = " + a + ", b = " + b); +} + +foo(12, "oui"); diff --git a/dsl2/src/test/resources/parsing/corrects/functions/function_call_expr.uss b/dsl2/src/test/resources/parsing/corrects/functions/function_call_expr.uss new file mode 100644 index 00000000..5dbf2a72 --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/functions/function_call_expr.uss @@ -0,0 +1,6 @@ +int plus_one(int a) { + return a + 1; +} + +int three = plus_one(plus_one(1)); +int five = plus_one(three) + 1; \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing/invalid/bad_syntax/function_call_void_expression.uss b/dsl2/src/test/resources/parsing/invalid/bad_syntax/function_call_void_expression.uss new file mode 100644 index 00000000..240f40be --- /dev/null +++ b/dsl2/src/test/resources/parsing/invalid/bad_syntax/function_call_void_expression.uss @@ -0,0 +1,5 @@ +void foo(int a) { + int b = a + 1; +} + +int three = 1 + foo(1); \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing/invalid/bad_syntax/unknown_function.uss b/dsl2/src/test/resources/parsing/invalid/bad_syntax/unknown_function.uss new file mode 100644 index 00000000..4ff30255 --- /dev/null +++ b/dsl2/src/test/resources/parsing/invalid/bad_syntax/unknown_function.uss @@ -0,0 +1 @@ +some_function(); \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing/invalid/bad_type/function_call_bad_args.uss b/dsl2/src/test/resources/parsing/invalid/bad_type/function_call_bad_args.uss new file mode 100644 index 00000000..f2065b50 --- /dev/null +++ b/dsl2/src/test/resources/parsing/invalid/bad_type/function_call_bad_args.uss @@ -0,0 +1,5 @@ +void foo(int a, string b) { + console.info("a = " + a + ", b = " + b); +} + +foo(12, 4567); From 8015d132a2c1637663546bc519d129ff711c5cdb Mon Sep 17 00:00:00 2001 From: "timothe.rosaz" Date: Sat, 25 Oct 2025 17:43:24 +0200 Subject: [PATCH 19/38] Fixed a bug with time keywords --- .../nodes/expressions/litteral/ArrayLiteral.java | 1 - .../expressions/litteral/LocationLiteral.java | 15 +++++++-------- .../dsl2/tokenization/Tokenizer.java | 3 ++- .../dsl2/visitor/PrintingVisitor.java | 2 +- .../dsl2/CorrectParsingTests.java | 5 +++++ .../parsing/corrects/types/durations.uss | 8 ++++++++ .../parsing/corrects/types/locations.uss | 3 +++ .../parsing/invalid/bad_parsing/bad_time_unit.uss | 1 - 8 files changed, 26 insertions(+), 12 deletions(-) create mode 100644 dsl2/src/test/resources/parsing/corrects/types/durations.uss create mode 100644 dsl2/src/test/resources/parsing/corrects/types/locations.uss delete mode 100644 dsl2/src/test/resources/parsing/invalid/bad_parsing/bad_time_unit.uss diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/ArrayLiteral.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/ArrayLiteral.java index de85dfdb..65f7881d 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/ArrayLiteral.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/ArrayLiteral.java @@ -53,7 +53,6 @@ public void validateTypes(@NotNull TypesContext contextParent) { if(elementsType == null) { elementsType = node.getExpressionType(); } else { - //TODO assertExpressionType(node, elementsType); } } diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/LocationLiteral.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/LocationLiteral.java index aaf18b41..2474a5c3 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/LocationLiteral.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/LocationLiteral.java @@ -35,7 +35,7 @@ protected LocationLiteral(TokenPosition position, ExpressionNode world, Expressi this.pitch = pitch; } - public boolean asYawAndPitch() { + public boolean hasYawAndPitch() { return yaw != null && pitch != null; } @@ -56,7 +56,7 @@ public void validateTypes(@NotNull TypesContext context) { assertExpressionType(vectorY, context, TypePrimitive.NUMBER); assertExpressionType(vectorZ, context, TypePrimitive.NUMBER); - if(asYawAndPitch()) { + if(hasYawAndPitch()) { assertExpressionType(yaw, context, TypePrimitive.NUMBER); assertExpressionType(pitch, context, TypePrimitive.NUMBER); } @@ -75,11 +75,11 @@ public void validateTypes(@NotNull TypesContext context) { // World + vector ExpressionNode world = ExpressionNode.readNextExpression(tokens); - tokens.dropOrThrow(TokenType.COMMA); + tokens.dropOrThrow(TokenType.COMMA, "A location literal needs a X coordinate after the world."); ExpressionNode x = ExpressionNode.readNextExpression(tokens); - tokens.dropOrThrow(TokenType.COMMA); + tokens.dropOrThrow(TokenType.COMMA, "A location literal needs a Y coordinate after the world and X."); ExpressionNode y = ExpressionNode.readNextExpression(tokens); - tokens.dropOrThrow(TokenType.COMMA); + tokens.dropOrThrow(TokenType.COMMA, "A location literal needs a Z coordinate avec world and X + Y coordinates."); ExpressionNode z = ExpressionNode.readNextExpression(tokens); // Optional yaw + pitch @@ -87,13 +87,12 @@ public void validateTypes(@NotNull TypesContext context) { ExpressionNode pitch = null; if(tokens.dropOptional(TokenType.COMMA)) { yaw = ExpressionNode.readNextExpression(tokens); - } - if(tokens.dropOptional(TokenType.COMMA)) { + tokens.dropOrThrow(TokenType.COMMA, "In a location literal, after the yaw, a pitch value is required."); pitch = ExpressionNode.readNextExpression(tokens); } // Close - tokens.dropOrThrow(TokenType.BRACKET_CLOSE); + tokens.dropOrThrow(TokenType.BRACKET_CLOSE, "A location literal needs a ')' at the end."); return new LocationLiteral(position, world, x, y, z, yaw, pitch); } diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/tokenization/Tokenizer.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/tokenization/Tokenizer.java index 8fe8b9ce..f8319a2e 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/tokenization/Tokenizer.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/tokenization/Tokenizer.java @@ -146,7 +146,8 @@ private TokenStream tokenize() { if(TIME_UNITS.containsKey(word)) { if(tokens.isEmpty() || last().getType() != TokenType.VALUE_NUMBER ) { - throw new ParsingException(chars.pos(), "Unexpected time unit '"+word+"'."); + tokens.add(Token.fromIdentifier(word, position)); + continue; } // Replace number by duration double number = last().getContentNumber(); diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/PrintingVisitor.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/PrintingVisitor.java index 4fd4ecb6..fc9f020a 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/PrintingVisitor.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/PrintingVisitor.java @@ -293,7 +293,7 @@ public void handleLocationLiteral(@NotNull LocationLiteral literal) { literal.getVectorX().visit(this); builder.append(", "); literal.getVectorY().visit(this); builder.append(", "); literal.getVectorZ().visit(this); - if(literal.asYawAndPitch()) { + if(literal.hasYawAndPitch()) { builder.append(", "); literal.getYaw().visit(this); builder.append(", "); diff --git a/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/CorrectParsingTests.java b/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/CorrectParsingTests.java index 1a2f6f00..e0005e47 100644 --- a/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/CorrectParsingTests.java +++ b/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/CorrectParsingTests.java @@ -41,6 +41,11 @@ void correctArrays() { testFolder("corrects/arrays"); } + @Test + void correctTypes() { + testFolder("corrects/types"); + } + // -- private void testFolder(@NotNull String folder) { diff --git a/dsl2/src/test/resources/parsing/corrects/types/durations.uss b/dsl2/src/test/resources/parsing/corrects/types/durations.uss new file mode 100644 index 00000000..1ea49d35 --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/types/durations.uss @@ -0,0 +1,8 @@ +var a = 3 seconds; +a = 3s; +var b = 5minutes; +b = 5m; +var c = 8 milliseconds; +c = 8 ms; +var d = 7 hours; +d = 7h; \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing/corrects/types/locations.uss b/dsl2/src/test/resources/parsing/corrects/types/locations.uss new file mode 100644 index 00000000..1eb7a5b4 --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/types/locations.uss @@ -0,0 +1,3 @@ +var l = @("world", 0, 100, 0); + +l = @("world_the_end", 0, 100, 0, 0, 90); diff --git a/dsl2/src/test/resources/parsing/invalid/bad_parsing/bad_time_unit.uss b/dsl2/src/test/resources/parsing/invalid/bad_parsing/bad_time_unit.uss deleted file mode 100644 index feecaa18..00000000 --- a/dsl2/src/test/resources/parsing/invalid/bad_parsing/bad_time_unit.uss +++ /dev/null @@ -1 +0,0 @@ -var oupsi = minutes; \ No newline at end of file From 3280eec4366fbad4473adc5074abaaa95d41f52d Mon Sep 17 00:00:00 2001 From: "timothe.rosaz" Date: Sun, 26 Oct 2025 16:34:30 +0100 Subject: [PATCH 20/38] one lomre duration test --- .../dsl2/nodes/type/DurationTests.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/DurationTests.java b/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/DurationTests.java index b13a2a0b..aa591724 100644 --- a/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/DurationTests.java +++ b/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/DurationTests.java @@ -3,6 +3,7 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import java.time.temporal.TemporalUnit; import java.util.concurrent.TimeUnit; /** @@ -19,6 +20,7 @@ void testDurOpeDur() { Duration c = new Duration(1, TimeUnit.HOURS); Duration d = new Duration(1, TimeUnit.SECONDS); Assertions.assertEquals(new Duration(3601, TimeUnit.SECONDS), c.add(d)); + Assertions.assertEquals(new Duration(3599, TimeUnit.SECONDS), c.sub(d)); Assertions.assertEquals(new Duration(2, TimeUnit.HOURS), c.add(c)); } @@ -35,4 +37,12 @@ void testDurMul() { Assertions.assertEquals(new Duration(1, TimeUnit.HOURS), a.mul(5)); } + @Test + void conversionsTest() { + Duration oneSecond = new Duration(1, TimeUnit.SECONDS); + Assertions.assertEquals(1000L, oneSecond.toMs()); + Assertions.assertEquals(20L, oneSecond.toTicks()); + Assertions.assertEquals(java.time.Duration.ofSeconds(1), oneSecond.asJavaDuration()); + } + } From 32c298743517461154260f737f5a03c4944d9855 Mon Sep 17 00:00:00 2001 From: "timothe.rosaz" Date: Sun, 26 Oct 2025 17:18:32 +0100 Subject: [PATCH 21/38] Tree validation for functions --- .../nodes/statements/ReturnStatement.java | 16 +++++- .../dsl2/tokenization/TokenStream.java | 5 ++ .../StructureValidationVisitor.java | 55 +++++++++++++------ .../dsl2/FailuresParsingTests.java | 5 ++ .../parsing/corrects/basics/declarations.uss | 1 + .../invalid/bad_tree/func_bad_return.uss | 3 + .../invalid/bad_tree/func_bad_return_2.uss | 5 ++ .../invalid/bad_tree/func_no_return.uss | 3 + .../invalid/bad_tree/global_bad_return.uss | 3 + .../bad_mix/invalid_param_meta.uss | 3 - .../parsing_old/bad_mix/unknown_function.uss | 1 - .../parsing_old/bad_parsing/bad_number.uss | 1 - .../parsing_old/bad_parsing/bad_string.uss | 2 - .../parsing_old/bad_syntax/bad_else.uss | 3 - .../bad_syntax/bad_entity_type.uss | 3 - .../parsing_old/bad_syntax/bad_send.uss | 3 - .../parsing_old/bad_syntax/bad_var.uss | 2 - .../bad_syntax/redefine_caster.uss | 1 - .../parsing_old/bad_tree/after_break.uss | 6 -- .../parsing_old/bad_tree/after_meta_1.uss | 5 -- .../parsing_old/bad_tree/after_meta_2.uss | 5 -- .../parsing_old/bad_tree/after_stop_1.uss | 2 - .../parsing_old/bad_tree/after_stop_2.uss | 3 - .../parsing_old/bad_tree/after_stop_3.uss | 5 -- .../bad_type/bad_collection_teleport.uss | 4 -- .../parsing_old/bad_type/bad_list_append.uss | 3 - .../parsing_old/bad_type/bad_ope.uss | 5 -- .../parsing_old/bad_type/bad_ope_2.uss | 6 -- .../parsing_old/bad_type/bad_ope_3.uss | 7 --- .../parsing_old/bad_type/increment_type.uss | 2 - .../bad_type/redefine_difftype.uss | 2 - .../parsing_old/bad_type/stop_type.uss | 1 - .../parsing_old/corrects/blocks/for.uss | 14 ----- .../parsing_old/corrects/blocks/for_break.uss | 5 -- .../parsing_old/corrects/blocks/foreach.uss | 6 -- .../parsing_old/corrects/blocks/ifelse_p1.uss | 7 --- .../parsing_old/corrects/blocks/ifelse_p2.uss | 20 ------- .../parsing_old/corrects/blocks/repeat.uss | 13 ----- .../parsing_old/corrects/blocks/repeat_2.uss | 9 --- .../parsing_old/corrects/blocks/run_later.uss | 9 --- .../parsing_old/corrects/blocks/while.uss | 15 ----- .../corrects/metadata/param_metadata.uss | 3 - .../parsing_old/corrects/mix/cercle.uss | 12 ---- .../parsing_old/corrects/mix/collections.uss | 8 --- .../parsing_old/corrects/mix/empty.uss | 0 .../corrects/mix/implicit_define.uss | 2 - .../parsing_old/corrects/mix/metadata.uss | 5 -- .../corrects/mix/null_recovery.uss | 6 -- .../parsing_old/corrects/mix/null_set.uss | 7 --- .../corrects/mix/particle_shape.uss | 8 --- .../parsing_old/corrects/mix/test_allof.uss | 6 -- .../parsing_old/corrects/mix/test_basic.uss | 4 -- .../corrects/mix/test_complex_tp.uss | 27 --------- .../corrects/mix/test_location_literal.uss | 2 - .../parsing_old/corrects/mix/test_null.uss | 5 -- .../corrects/mix/test_teleport.uss | 6 -- .../corrects/operators/bool_operators.uss | 2 - .../corrects/operators/conditions.uss | 13 ----- .../corrects/operators/list_append.uss | 16 ------ .../parsing_old/corrects/operators/math.uss | 3 - .../corrects/operators/operator_priority.uss | 11 ---- .../corrects/operators/parenthesis.uss | 6 -- .../corrects/operators/type_operators.uss | 5 -- .../corrects/statements/define.uss | 12 ---- .../parsing_old/corrects/statements/give.uss | 10 ---- .../corrects/statements/increment.uss | 3 - .../parsing_old/corrects/statements/play.uss | 17 ------ .../parsing_old/corrects/statements/send.uss | 22 -------- .../corrects/statements/send_nbt.uss | 1 - .../corrects/statements/stop_1.uss | 2 - .../corrects/statements/stop_2.uss | 2 - .../corrects/statements/stop_3.uss | 3 - .../corrects/statements/summon.uss | 9 --- .../corrects/statements/teleport.uss | 4 -- .../corrects_with_custom/callback.uss | 6 -- .../corrects_with_custom/custom.uss | 4 -- 76 files changed, 77 insertions(+), 444 deletions(-) create mode 100644 dsl2/src/test/resources/parsing/invalid/bad_tree/func_bad_return.uss create mode 100644 dsl2/src/test/resources/parsing/invalid/bad_tree/func_bad_return_2.uss create mode 100644 dsl2/src/test/resources/parsing/invalid/bad_tree/func_no_return.uss create mode 100644 dsl2/src/test/resources/parsing/invalid/bad_tree/global_bad_return.uss delete mode 100644 dsl2/src/test/resources/parsing_old/bad_mix/invalid_param_meta.uss delete mode 100644 dsl2/src/test/resources/parsing_old/bad_mix/unknown_function.uss delete mode 100644 dsl2/src/test/resources/parsing_old/bad_parsing/bad_number.uss delete mode 100644 dsl2/src/test/resources/parsing_old/bad_parsing/bad_string.uss delete mode 100644 dsl2/src/test/resources/parsing_old/bad_syntax/bad_else.uss delete mode 100644 dsl2/src/test/resources/parsing_old/bad_syntax/bad_entity_type.uss delete mode 100644 dsl2/src/test/resources/parsing_old/bad_syntax/bad_send.uss delete mode 100644 dsl2/src/test/resources/parsing_old/bad_syntax/bad_var.uss delete mode 100644 dsl2/src/test/resources/parsing_old/bad_syntax/redefine_caster.uss delete mode 100644 dsl2/src/test/resources/parsing_old/bad_tree/after_break.uss delete mode 100644 dsl2/src/test/resources/parsing_old/bad_tree/after_meta_1.uss delete mode 100644 dsl2/src/test/resources/parsing_old/bad_tree/after_meta_2.uss delete mode 100644 dsl2/src/test/resources/parsing_old/bad_tree/after_stop_1.uss delete mode 100644 dsl2/src/test/resources/parsing_old/bad_tree/after_stop_2.uss delete mode 100644 dsl2/src/test/resources/parsing_old/bad_tree/after_stop_3.uss delete mode 100644 dsl2/src/test/resources/parsing_old/bad_type/bad_collection_teleport.uss delete mode 100644 dsl2/src/test/resources/parsing_old/bad_type/bad_list_append.uss delete mode 100644 dsl2/src/test/resources/parsing_old/bad_type/bad_ope.uss delete mode 100644 dsl2/src/test/resources/parsing_old/bad_type/bad_ope_2.uss delete mode 100644 dsl2/src/test/resources/parsing_old/bad_type/bad_ope_3.uss delete mode 100644 dsl2/src/test/resources/parsing_old/bad_type/increment_type.uss delete mode 100644 dsl2/src/test/resources/parsing_old/bad_type/redefine_difftype.uss delete mode 100644 dsl2/src/test/resources/parsing_old/bad_type/stop_type.uss delete mode 100644 dsl2/src/test/resources/parsing_old/corrects/blocks/for.uss delete mode 100644 dsl2/src/test/resources/parsing_old/corrects/blocks/for_break.uss delete mode 100644 dsl2/src/test/resources/parsing_old/corrects/blocks/foreach.uss delete mode 100644 dsl2/src/test/resources/parsing_old/corrects/blocks/ifelse_p1.uss delete mode 100644 dsl2/src/test/resources/parsing_old/corrects/blocks/ifelse_p2.uss delete mode 100644 dsl2/src/test/resources/parsing_old/corrects/blocks/repeat.uss delete mode 100644 dsl2/src/test/resources/parsing_old/corrects/blocks/repeat_2.uss delete mode 100644 dsl2/src/test/resources/parsing_old/corrects/blocks/run_later.uss delete mode 100644 dsl2/src/test/resources/parsing_old/corrects/blocks/while.uss delete mode 100644 dsl2/src/test/resources/parsing_old/corrects/metadata/param_metadata.uss delete mode 100644 dsl2/src/test/resources/parsing_old/corrects/mix/cercle.uss delete mode 100644 dsl2/src/test/resources/parsing_old/corrects/mix/collections.uss delete mode 100644 dsl2/src/test/resources/parsing_old/corrects/mix/empty.uss delete mode 100644 dsl2/src/test/resources/parsing_old/corrects/mix/implicit_define.uss delete mode 100644 dsl2/src/test/resources/parsing_old/corrects/mix/metadata.uss delete mode 100644 dsl2/src/test/resources/parsing_old/corrects/mix/null_recovery.uss delete mode 100644 dsl2/src/test/resources/parsing_old/corrects/mix/null_set.uss delete mode 100644 dsl2/src/test/resources/parsing_old/corrects/mix/particle_shape.uss delete mode 100644 dsl2/src/test/resources/parsing_old/corrects/mix/test_allof.uss delete mode 100644 dsl2/src/test/resources/parsing_old/corrects/mix/test_basic.uss delete mode 100644 dsl2/src/test/resources/parsing_old/corrects/mix/test_complex_tp.uss delete mode 100644 dsl2/src/test/resources/parsing_old/corrects/mix/test_location_literal.uss delete mode 100644 dsl2/src/test/resources/parsing_old/corrects/mix/test_null.uss delete mode 100644 dsl2/src/test/resources/parsing_old/corrects/mix/test_teleport.uss delete mode 100644 dsl2/src/test/resources/parsing_old/corrects/operators/bool_operators.uss delete mode 100644 dsl2/src/test/resources/parsing_old/corrects/operators/conditions.uss delete mode 100644 dsl2/src/test/resources/parsing_old/corrects/operators/list_append.uss delete mode 100644 dsl2/src/test/resources/parsing_old/corrects/operators/math.uss delete mode 100644 dsl2/src/test/resources/parsing_old/corrects/operators/operator_priority.uss delete mode 100644 dsl2/src/test/resources/parsing_old/corrects/operators/parenthesis.uss delete mode 100644 dsl2/src/test/resources/parsing_old/corrects/operators/type_operators.uss delete mode 100644 dsl2/src/test/resources/parsing_old/corrects/statements/define.uss delete mode 100644 dsl2/src/test/resources/parsing_old/corrects/statements/give.uss delete mode 100644 dsl2/src/test/resources/parsing_old/corrects/statements/increment.uss delete mode 100644 dsl2/src/test/resources/parsing_old/corrects/statements/play.uss delete mode 100644 dsl2/src/test/resources/parsing_old/corrects/statements/send.uss delete mode 100644 dsl2/src/test/resources/parsing_old/corrects/statements/send_nbt.uss delete mode 100644 dsl2/src/test/resources/parsing_old/corrects/statements/stop_1.uss delete mode 100644 dsl2/src/test/resources/parsing_old/corrects/statements/stop_2.uss delete mode 100644 dsl2/src/test/resources/parsing_old/corrects/statements/stop_3.uss delete mode 100644 dsl2/src/test/resources/parsing_old/corrects/statements/summon.uss delete mode 100644 dsl2/src/test/resources/parsing_old/corrects/statements/teleport.uss delete mode 100644 dsl2/src/test/resources/parsing_old/corrects_with_custom/callback.uss delete mode 100644 dsl2/src/test/resources/parsing_old/corrects_with_custom/custom.uss diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/ReturnStatement.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/ReturnStatement.java index 58a21621..41fd5c6b 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/ReturnStatement.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/ReturnStatement.java @@ -3,9 +3,11 @@ import fr.jamailun.ultimatespellsystem.dsl2.nodes.ExpressionNode; import fr.jamailun.ultimatespellsystem.dsl2.nodes.StatementNode; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.CollectionFilter; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.variables.TypesContext; import fr.jamailun.ultimatespellsystem.dsl2.tokenization.PreviousIndicator; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenPosition; import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenStream; import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenType; import fr.jamailun.ultimatespellsystem.dsl2.visitor.StatementVisitor; @@ -21,12 +23,19 @@ @Getter public class ReturnStatement extends StatementNode { + private final TokenPosition pos; private final @Nullable ExpressionNode exitCodeNode; @Override public void validateTypes(@NotNull TypesContext context) { if(exitCodeNode != null) - assertExpressionType(exitCodeNode, CollectionFilter.MONO_ELEMENT, context, TypePrimitive.NUMBER); + exitCodeNode.validateTypes(context); + } + + public @Nullable Type getReturnType() { + if(exitCodeNode != null) + return exitCodeNode.getExpressionType(); + return Type.of(TypePrimitive.NULL); } @Override @@ -41,12 +50,13 @@ public void visit(@NotNull StatementVisitor visitor) { */ @PreviousIndicator(expected = TokenType.RETURN) public static @NotNull ReturnStatement parseReturn(@NotNull TokenStream tokens) { + TokenPosition pos = tokens.previousPos(); if(tokens.dropOptional(TokenType.SEMI_COLON)) { - return new ReturnStatement(null); + return new ReturnStatement(pos, null); } else { ExpressionNode exitNode = ExpressionNode.readNextExpression(tokens); tokens.dropOrThrow(TokenType.SEMI_COLON, "Expected a semi-colon after a RETURN statement value."); - return new ReturnStatement(exitNode); + return new ReturnStatement(pos, exitNode); } } diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/tokenization/TokenStream.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/tokenization/TokenStream.java index 1deb98de..101758b9 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/tokenization/TokenStream.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/tokenization/TokenStream.java @@ -142,6 +142,11 @@ public boolean hasMore() { return "TokenStream{index="+index+", TOKENS = [" + sj + "] }"; } + public @NotNull TokenPosition previousPos() { + Preconditions.checkState(index > 0, "Cannot fetch previous position on start."); + return tokens.get(index - 1).pos(); + } + /** * Get the current token position. * @return the current position. diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/validators/StructureValidationVisitor.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/validators/StructureValidationVisitor.java index 4cbf6b5f..fe85e613 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/validators/StructureValidationVisitor.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/validators/StructureValidationVisitor.java @@ -6,36 +6,40 @@ import fr.jamailun.ultimatespellsystem.dsl2.nodes.statements.blocks.ForLoopStatement; import fr.jamailun.ultimatespellsystem.dsl2.nodes.statements.blocks.IfElseStatement; import fr.jamailun.ultimatespellsystem.dsl2.nodes.statements.blocks.WhileLoopStatement; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenPosition; import fr.jamailun.ultimatespellsystem.dsl2.visitor.StatementVisitor; import org.jetbrains.annotations.NotNull; +import java.util.Objects; + /** * Structure validation. */ public class StructureValidationVisitor implements StatementVisitor { - private boolean stopMet = false; + + private TypeRef returnType = new TypeRef(); // reference + private boolean returnMet = false; private boolean breakMet = false; private boolean metadataAllowed = true; - private StructureValidationVisitor child() { + private @NotNull StructureValidationVisitor child() { StructureValidationVisitor clone = new StructureValidationVisitor(); clone.metadataAllowed = metadataAllowed; - clone.stopMet = stopMet; + clone.returnMet = returnMet; clone.breakMet = breakMet; + clone.returnType = returnType; // copy ref return clone; } - /* @Override - public void handleMetadata(@NotNull MetadataStatement statement) { - if(!metadataAllowed) - throw new TreeValidationException(TokenPosition.unknown(), "Meta-data can only be the first statements."); - }*/ - @Override public void handleReturn(@NotNull ReturnStatement statement) { handleMono(); - stopMet = true; + returnMet = true; + if(returnType.type != null && !Objects.equals(returnType.type, statement.getReturnType())) { + throw new TreeValidationException(statement.getPos(), "Cannot use a return of type " + statement.getReturnType() + " : another return in the same scoped returned a " + returnType.type); + } + returnType.type = statement.getReturnType(); } @Override public void handleBreakContinue(@NotNull BreakContinueStatement statement) { @@ -50,13 +54,33 @@ public void handleBlock(@NotNull BlockStatement statement) { statement.getChildren().forEach(n -> n.visit(child)); } + @Override + public void handleFunctionDeclaration(@NotNull FunctionDeclarationStatement statement) { + // Prepare child context + StructureValidationVisitor child = child(); + child.returnType = new TypeRef(); + + // Apply to statements + statement.getStatements().forEach(n -> n.visit(child)); + + // Check returns + if(!statement.getOutputType().isNull()) { + // No return + if(!child.returnMet) + throw new TreeValidationException(statement.getPosition(), "Function " + statement.getFunctionName() + " should return " + statement.getFunctionReturnType() + ", but not all branches return a value."); + // Different return type. + if(!Objects.equals(statement.getOutputType(), child.returnType.type)) + throw new TreeValidationException(statement.getPosition(), "Function " + statement.getFunctionName() + " should return " + statement.getFunctionReturnType() + ", but returned "+child.returnType.type+" instead."); + } + } + private void handleSub(@NotNull StatementNode child) { child.visit(child()); } private void handleMono() { metadataAllowed = false; - if(stopMet) { + if(returnMet) { throw new TreeValidationException(TokenPosition.unknown(), "Cannot have a statement after a STOP."); } if(breakMet) { @@ -85,11 +109,10 @@ public void handleAffectVariable(@NotNull AffectationStatement statement) { handleMono(); } - @Override - public void handleFunctionDeclaration(@NotNull FunctionDeclarationStatement statement) { - //TODO ?? - } - @Override public void handleSimpleExpression(@NotNull SimpleExpressionStatement statement) {handleMono();} + + private static class TypeRef { + Type type; + } } diff --git a/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/FailuresParsingTests.java b/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/FailuresParsingTests.java index 7f0bea35..c4c507ca 100644 --- a/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/FailuresParsingTests.java +++ b/dsl2/src/test/java/fr/jamailun/ultimatespellsystem/dsl2/FailuresParsingTests.java @@ -26,6 +26,11 @@ void badParsing() { badParsing("invalid/bad_parsing", ParsingException.class); } + @Test + void badTree() { + badParsing("invalid/bad_tree", TreeValidationException.class); + } + private void badParsing(@NotNull String folder, @NotNull Class clazz) { String title = "[! EXPECTED "+clazz.getSimpleName()+"] "; for(File file : listTests(folder)) { diff --git a/dsl2/src/test/resources/parsing/corrects/basics/declarations.uss b/dsl2/src/test/resources/parsing/corrects/basics/declarations.uss index ecb4f595..ac9b4dd8 100644 --- a/dsl2/src/test/resources/parsing/corrects/basics/declarations.uss +++ b/dsl2/src/test/resources/parsing/corrects/basics/declarations.uss @@ -1,3 +1,4 @@ int some_method() { int some_var; + return some_var; } \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing/invalid/bad_tree/func_bad_return.uss b/dsl2/src/test/resources/parsing/invalid/bad_tree/func_bad_return.uss new file mode 100644 index 00000000..bbf0fa6d --- /dev/null +++ b/dsl2/src/test/resources/parsing/invalid/bad_tree/func_bad_return.uss @@ -0,0 +1,3 @@ +int foo() { + return "non"; +} diff --git a/dsl2/src/test/resources/parsing/invalid/bad_tree/func_bad_return_2.uss b/dsl2/src/test/resources/parsing/invalid/bad_tree/func_bad_return_2.uss new file mode 100644 index 00000000..f5fd5ab4 --- /dev/null +++ b/dsl2/src/test/resources/parsing/invalid/bad_tree/func_bad_return_2.uss @@ -0,0 +1,5 @@ +int foo() { + if(1 == 1) + return "non"; + return 12; +} diff --git a/dsl2/src/test/resources/parsing/invalid/bad_tree/func_no_return.uss b/dsl2/src/test/resources/parsing/invalid/bad_tree/func_no_return.uss new file mode 100644 index 00000000..be22943d --- /dev/null +++ b/dsl2/src/test/resources/parsing/invalid/bad_tree/func_no_return.uss @@ -0,0 +1,3 @@ +int foo() { + console.info("non"); +} diff --git a/dsl2/src/test/resources/parsing/invalid/bad_tree/global_bad_return.uss b/dsl2/src/test/resources/parsing/invalid/bad_tree/global_bad_return.uss new file mode 100644 index 00000000..23bac20e --- /dev/null +++ b/dsl2/src/test/resources/parsing/invalid/bad_tree/global_bad_return.uss @@ -0,0 +1,3 @@ +if(1 == 1) + return 1; +return "autre"; \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing_old/bad_mix/invalid_param_meta.uss b/dsl2/src/test/resources/parsing_old/bad_mix/invalid_param_meta.uss deleted file mode 100644 index db31ab9e..00000000 --- a/dsl2/src/test/resources/parsing_old/bad_mix/invalid_param_meta.uss +++ /dev/null @@ -1,3 +0,0 @@ -@param(12, ""); - -define %a = 2; diff --git a/dsl2/src/test/resources/parsing_old/bad_mix/unknown_function.uss b/dsl2/src/test/resources/parsing_old/bad_mix/unknown_function.uss deleted file mode 100644 index 055a585e..00000000 --- a/dsl2/src/test/resources/parsing_old/bad_mix/unknown_function.uss +++ /dev/null @@ -1 +0,0 @@ -define %a = i_dont_exist("toto"); \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing_old/bad_parsing/bad_number.uss b/dsl2/src/test/resources/parsing_old/bad_parsing/bad_number.uss deleted file mode 100644 index d1da7e46..00000000 --- a/dsl2/src/test/resources/parsing_old/bad_parsing/bad_number.uss +++ /dev/null @@ -1 +0,0 @@ -define %a = 5..1; \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing_old/bad_parsing/bad_string.uss b/dsl2/src/test/resources/parsing_old/bad_parsing/bad_string.uss deleted file mode 100644 index b807acac..00000000 --- a/dsl2/src/test/resources/parsing_old/bad_parsing/bad_string.uss +++ /dev/null @@ -1,2 +0,0 @@ -define %a = "a -b"; \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing_old/bad_syntax/bad_else.uss b/dsl2/src/test/resources/parsing_old/bad_syntax/bad_else.uss deleted file mode 100644 index 1efc7306..00000000 --- a/dsl2/src/test/resources/parsing_old/bad_syntax/bad_else.uss +++ /dev/null @@ -1,3 +0,0 @@ -if(1 == 1) stop; -else stop; -else stop; diff --git a/dsl2/src/test/resources/parsing_old/bad_syntax/bad_entity_type.uss b/dsl2/src/test/resources/parsing_old/bad_syntax/bad_entity_type.uss deleted file mode 100644 index 6af8ceec..00000000 --- a/dsl2/src/test/resources/parsing_old/bad_syntax/bad_entity_type.uss +++ /dev/null @@ -1,3 +0,0 @@ -# Unknown subtype of send'. - -summon I_DONT_EXIST for 4s; diff --git a/dsl2/src/test/resources/parsing_old/bad_syntax/bad_send.uss b/dsl2/src/test/resources/parsing_old/bad_syntax/bad_send.uss deleted file mode 100644 index e8e1f09f..00000000 --- a/dsl2/src/test/resources/parsing_old/bad_syntax/bad_send.uss +++ /dev/null @@ -1,3 +0,0 @@ -# Unknown subtype of send'. - -send to %caster I_DONT_EXIST "I'm a failure"; diff --git a/dsl2/src/test/resources/parsing_old/bad_syntax/bad_var.uss b/dsl2/src/test/resources/parsing_old/bad_syntax/bad_var.uss deleted file mode 100644 index 7fa3c971..00000000 --- a/dsl2/src/test/resources/parsing_old/bad_syntax/bad_var.uss +++ /dev/null @@ -1,2 +0,0 @@ -define %correct = 12; -%correct; \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing_old/bad_syntax/redefine_caster.uss b/dsl2/src/test/resources/parsing_old/bad_syntax/redefine_caster.uss deleted file mode 100644 index 4ccdb855..00000000 --- a/dsl2/src/test/resources/parsing_old/bad_syntax/redefine_caster.uss +++ /dev/null @@ -1 +0,0 @@ -define %caster = 2; diff --git a/dsl2/src/test/resources/parsing_old/bad_tree/after_break.uss b/dsl2/src/test/resources/parsing_old/bad_tree/after_break.uss deleted file mode 100644 index 865eb84b..00000000 --- a/dsl2/src/test/resources/parsing_old/bad_tree/after_break.uss +++ /dev/null @@ -1,6 +0,0 @@ -for(%i = 1; %i < 3; increment %i) { - if(%i == 2) { - break; - send to %caster message "oops"; - } -} \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing_old/bad_tree/after_meta_1.uss b/dsl2/src/test/resources/parsing_old/bad_tree/after_meta_1.uss deleted file mode 100644 index f4b62256..00000000 --- a/dsl2/src/test/resources/parsing_old/bad_tree/after_meta_1.uss +++ /dev/null @@ -1,5 +0,0 @@ -@meta_flag -if(1==1){ - @meta_flag - send to %caster message "foo"; -} diff --git a/dsl2/src/test/resources/parsing_old/bad_tree/after_meta_2.uss b/dsl2/src/test/resources/parsing_old/bad_tree/after_meta_2.uss deleted file mode 100644 index b62c339f..00000000 --- a/dsl2/src/test/resources/parsing_old/bad_tree/after_meta_2.uss +++ /dev/null @@ -1,5 +0,0 @@ -@meta_flag -{ - send to %caster message "foo"; -} -@meta_flag diff --git a/dsl2/src/test/resources/parsing_old/bad_tree/after_stop_1.uss b/dsl2/src/test/resources/parsing_old/bad_tree/after_stop_1.uss deleted file mode 100644 index 139cee45..00000000 --- a/dsl2/src/test/resources/parsing_old/bad_tree/after_stop_1.uss +++ /dev/null @@ -1,2 +0,0 @@ -stop; -stop; \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing_old/bad_tree/after_stop_2.uss b/dsl2/src/test/resources/parsing_old/bad_tree/after_stop_2.uss deleted file mode 100644 index 0b7a38ba..00000000 --- a/dsl2/src/test/resources/parsing_old/bad_tree/after_stop_2.uss +++ /dev/null @@ -1,3 +0,0 @@ -send to %caster message "a"; -stop; -send to %caster message "b"; \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing_old/bad_tree/after_stop_3.uss b/dsl2/src/test/resources/parsing_old/bad_tree/after_stop_3.uss deleted file mode 100644 index 9248fcef..00000000 --- a/dsl2/src/test/resources/parsing_old/bad_tree/after_stop_3.uss +++ /dev/null @@ -1,5 +0,0 @@ -@meta_flag -stop; -{ - send to %caster message "foo"; -} \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing_old/bad_type/bad_collection_teleport.uss b/dsl2/src/test/resources/parsing_old/bad_type/bad_collection_teleport.uss deleted file mode 100644 index 1bcf6687..00000000 --- a/dsl2/src/test/resources/parsing_old/bad_type/bad_collection_teleport.uss +++ /dev/null @@ -1,4 +0,0 @@ - -define %coll = all entities within 10 around %caster; - -teleport %caster to %coll; diff --git a/dsl2/src/test/resources/parsing_old/bad_type/bad_list_append.uss b/dsl2/src/test/resources/parsing_old/bad_type/bad_list_append.uss deleted file mode 100644 index 60f785a2..00000000 --- a/dsl2/src/test/resources/parsing_old/bad_type/bad_list_append.uss +++ /dev/null @@ -1,3 +0,0 @@ -%l = [[]]; -%l :+ "a"; -%l :+ true; diff --git a/dsl2/src/test/resources/parsing_old/bad_type/bad_ope.uss b/dsl2/src/test/resources/parsing_old/bad_type/bad_ope.uss deleted file mode 100644 index b7e3807c..00000000 --- a/dsl2/src/test/resources/parsing_old/bad_type/bad_ope.uss +++ /dev/null @@ -1,5 +0,0 @@ -# Valid -define %x = 1 * 2; - -# Not valid -define %z = [[1]] * 2; \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing_old/bad_type/bad_ope_2.uss b/dsl2/src/test/resources/parsing_old/bad_type/bad_ope_2.uss deleted file mode 100644 index 2f815f23..00000000 --- a/dsl2/src/test/resources/parsing_old/bad_type/bad_ope_2.uss +++ /dev/null @@ -1,6 +0,0 @@ -# Valid -define %x = 1 + "1" -define %y = "1" + 1; - -# Not valid -define %z = 1 * "oops"; diff --git a/dsl2/src/test/resources/parsing_old/bad_type/bad_ope_3.uss b/dsl2/src/test/resources/parsing_old/bad_type/bad_ope_3.uss deleted file mode 100644 index d6d21b41..00000000 --- a/dsl2/src/test/resources/parsing_old/bad_type/bad_ope_3.uss +++ /dev/null @@ -1,7 +0,0 @@ -# Valid -%a = true; -%b = !%a; - -# Invalid -%c = 14; -%d = !%c; diff --git a/dsl2/src/test/resources/parsing_old/bad_type/increment_type.uss b/dsl2/src/test/resources/parsing_old/bad_type/increment_type.uss deleted file mode 100644 index f2f8f169..00000000 --- a/dsl2/src/test/resources/parsing_old/bad_type/increment_type.uss +++ /dev/null @@ -1,2 +0,0 @@ -define %i = "a"; -decrement %i; diff --git a/dsl2/src/test/resources/parsing_old/bad_type/redefine_difftype.uss b/dsl2/src/test/resources/parsing_old/bad_type/redefine_difftype.uss deleted file mode 100644 index d13c23cf..00000000 --- a/dsl2/src/test/resources/parsing_old/bad_type/redefine_difftype.uss +++ /dev/null @@ -1,2 +0,0 @@ -define %a = 1; -define %a = "toto"; \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing_old/bad_type/stop_type.uss b/dsl2/src/test/resources/parsing_old/bad_type/stop_type.uss deleted file mode 100644 index f0623a9a..00000000 --- a/dsl2/src/test/resources/parsing_old/bad_type/stop_type.uss +++ /dev/null @@ -1 +0,0 @@ -stop "non"; \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing_old/corrects/blocks/for.uss b/dsl2/src/test/resources/parsing_old/corrects/blocks/for.uss deleted file mode 100644 index abc070ed..00000000 --- a/dsl2/src/test/resources/parsing_old/corrects/blocks/for.uss +++ /dev/null @@ -1,14 +0,0 @@ -for(define %i = 0; %i < 5; increment %i) { - send to %caster message "i=%i"; -} - -%x = 12; -for(; %x < 5; decrement %x) { - send to %caster message "x=%x"; -} - -%z = 8; -for(; %x > 5; ) { - decrement %z; - send to %caster message "z=%z"; -} \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing_old/corrects/blocks/for_break.uss b/dsl2/src/test/resources/parsing_old/corrects/blocks/for_break.uss deleted file mode 100644 index 0c24ebbd..00000000 --- a/dsl2/src/test/resources/parsing_old/corrects/blocks/for_break.uss +++ /dev/null @@ -1,5 +0,0 @@ -for(define %i = 0; %i < 5; increment %i) { - send to %caster message "[%i]"; - if(%i > 3) - break; -} \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing_old/corrects/blocks/foreach.uss b/dsl2/src/test/resources/parsing_old/corrects/blocks/foreach.uss deleted file mode 100644 index d0356410..00000000 --- a/dsl2/src/test/resources/parsing_old/corrects/blocks/foreach.uss +++ /dev/null @@ -1,6 +0,0 @@ -define %around = (all PLAYER within 50 around %caster); - -foreach(%p : %around) { - send to %caster message "Found " + %p; -} -send to %caster message "All = %around"; \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing_old/corrects/blocks/ifelse_p1.uss b/dsl2/src/test/resources/parsing_old/corrects/blocks/ifelse_p1.uss deleted file mode 100644 index f6e36220..00000000 --- a/dsl2/src/test/resources/parsing_old/corrects/blocks/ifelse_p1.uss +++ /dev/null @@ -1,7 +0,0 @@ -define %a = null; -if(%caster == %caster) - define %a = "a"; -else - define %a = "b"; - -send to %caster message %a; \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing_old/corrects/blocks/ifelse_p2.uss b/dsl2/src/test/resources/parsing_old/corrects/blocks/ifelse_p2.uss deleted file mode 100644 index e2c674a3..00000000 --- a/dsl2/src/test/resources/parsing_old/corrects/blocks/ifelse_p2.uss +++ /dev/null @@ -1,20 +0,0 @@ -define %a = 2; -define %even = null; - -if(%a == 0) { - define %even = true; -} else if(%a == 1) { - define %even = false; -} else if(%a == 2) { - define %even = true; -} else if(%a == 3) { - define %even = false; -} else if(%a == 4) { - define %even = true; -} else if(%a == 5) { - define %even = false; -} else { - send to %caster message "trop duuur !"; - stop; -} -send to %caster message "even ? %even"; diff --git a/dsl2/src/test/resources/parsing_old/corrects/blocks/repeat.uss b/dsl2/src/test/resources/parsing_old/corrects/blocks/repeat.uss deleted file mode 100644 index d69744ce..00000000 --- a/dsl2/src/test/resources/parsing_old/corrects/blocks/repeat.uss +++ /dev/null @@ -1,13 +0,0 @@ -repeat after 1s 5 times every 2 seconds: { - send to %caster message "boum 1."; -} - -repeat 2 times every 5 seconds: { - send to %caster message "boum 2."; -} - -define %count = 1 + 1; -define %delay = 3sec; -repeat %count times every %delay: { - send to %caster message "boum 3."; -} diff --git a/dsl2/src/test/resources/parsing_old/corrects/blocks/repeat_2.uss b/dsl2/src/test/resources/parsing_old/corrects/blocks/repeat_2.uss deleted file mode 100644 index 39727800..00000000 --- a/dsl2/src/test/resources/parsing_old/corrects/blocks/repeat_2.uss +++ /dev/null @@ -1,9 +0,0 @@ -repeat after 1s every 2 seconds for 2 m: { - send to %caster message "boum 1."; -} - -%dur = 1 minute; -%freq = 15s; -repeat every %freq for %dur: { - send %caster message "test"; -} diff --git a/dsl2/src/test/resources/parsing_old/corrects/blocks/run_later.uss b/dsl2/src/test/resources/parsing_old/corrects/blocks/run_later.uss deleted file mode 100644 index 37ec5afc..00000000 --- a/dsl2/src/test/resources/parsing_old/corrects/blocks/run_later.uss +++ /dev/null @@ -1,9 +0,0 @@ -send to %caster message "Timer: &a1 minute."; -run after 1 minute: { - send to %caster message "Timer is over."; -} - -define %delay = 3sec; -run after %delay: { - send to %caster message "post 3 secs."; -} diff --git a/dsl2/src/test/resources/parsing_old/corrects/blocks/while.uss b/dsl2/src/test/resources/parsing_old/corrects/blocks/while.uss deleted file mode 100644 index 6bebbaee..00000000 --- a/dsl2/src/test/resources/parsing_old/corrects/blocks/while.uss +++ /dev/null @@ -1,15 +0,0 @@ -define %i = 0; - -while(%i < 10) { - send to %caster message "&a+&f > i=%i"; - increment %i; - if(%i > 100) - continue; -} - -do { - send to %caster message "&c-&f > i=%i"; - decrement %i; -} while(%i > 0); - -send to %caster message "done"; diff --git a/dsl2/src/test/resources/parsing_old/corrects/metadata/param_metadata.uss b/dsl2/src/test/resources/parsing_old/corrects/metadata/param_metadata.uss deleted file mode 100644 index e637dc2b..00000000 --- a/dsl2/src/test/resources/parsing_old/corrects/metadata/param_metadata.uss +++ /dev/null @@ -1,3 +0,0 @@ -@param(test, int) - -define %foo = 3 + %test; diff --git a/dsl2/src/test/resources/parsing_old/corrects/mix/cercle.uss b/dsl2/src/test/resources/parsing_old/corrects/mix/cercle.uss deleted file mode 100644 index dd98fbe4..00000000 --- a/dsl2/src/test/resources/parsing_old/corrects/mix/cercle.uss +++ /dev/null @@ -1,12 +0,0 @@ -define %pos = position of %caster; - -define %pos = %pos + [[0,-1,0]]; -for(define %x = -5; %x <= 5; increment %x) { - for(define %z = -5; %z <= 5; increment %z) { - define %temp = %pos + [[%x, 0, %z]]; - play block at %pos with: {{ - type: MAGMA_BLOCK, - duration: 3 secs - }} - } -} \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing_old/corrects/mix/collections.uss b/dsl2/src/test/resources/parsing_old/corrects/mix/collections.uss deleted file mode 100644 index e1e4bb58..00000000 --- a/dsl2/src/test/resources/parsing_old/corrects/mix/collections.uss +++ /dev/null @@ -1,8 +0,0 @@ -define %msgs = [["a", "b", "c"]]; -send to %caster message %msgs; - -send to %caster message "1st is '" + %msgs[0] + "'"; - -for(define %i = 0; %i < sizeof(%msgs); increment %i) { - send to %caster message "&e MSG[%i] = '%a" + %msgs[%i] + "&e'"; -} diff --git a/dsl2/src/test/resources/parsing_old/corrects/mix/empty.uss b/dsl2/src/test/resources/parsing_old/corrects/mix/empty.uss deleted file mode 100644 index e69de29b..00000000 diff --git a/dsl2/src/test/resources/parsing_old/corrects/mix/implicit_define.uss b/dsl2/src/test/resources/parsing_old/corrects/mix/implicit_define.uss deleted file mode 100644 index 965dd96e..00000000 --- a/dsl2/src/test/resources/parsing_old/corrects/mix/implicit_define.uss +++ /dev/null @@ -1,2 +0,0 @@ -define %a = 1; -%a = 2; \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing_old/corrects/mix/metadata.uss b/dsl2/src/test/resources/parsing_old/corrects/mix/metadata.uss deleted file mode 100644 index 20c60e4d..00000000 --- a/dsl2/src/test/resources/parsing_old/corrects/mix/metadata.uss +++ /dev/null @@ -1,5 +0,0 @@ -@name("a nice spell") -@color("&b") -@param("a", int) - -send to %caster message ""; diff --git a/dsl2/src/test/resources/parsing_old/corrects/mix/null_recovery.uss b/dsl2/src/test/resources/parsing_old/corrects/mix/null_recovery.uss deleted file mode 100644 index 7c825e60..00000000 --- a/dsl2/src/test/resources/parsing_old/corrects/mix/null_recovery.uss +++ /dev/null @@ -1,6 +0,0 @@ -%a = 1; -%a = null; -%a = 1 - -send to %caster message "a = " + %a; - diff --git a/dsl2/src/test/resources/parsing_old/corrects/mix/null_set.uss b/dsl2/src/test/resources/parsing_old/corrects/mix/null_set.uss deleted file mode 100644 index f6e78789..00000000 --- a/dsl2/src/test/resources/parsing_old/corrects/mix/null_set.uss +++ /dev/null @@ -1,7 +0,0 @@ -define %a = 1; -define %b = null; - -if(%b == null) - define %b = 2; - -define %c = %a + %b; diff --git a/dsl2/src/test/resources/parsing_old/corrects/mix/particle_shape.uss b/dsl2/src/test/resources/parsing_old/corrects/mix/particle_shape.uss deleted file mode 100644 index e27159a3..00000000 --- a/dsl2/src/test/resources/parsing_old/corrects/mix/particle_shape.uss +++ /dev/null @@ -1,8 +0,0 @@ -define %pos = position of %caster; -play particle at %pos with: {{ - type: FIRE, - shape: {{ - type: "circle", - radius: 6.5 - }} -}} \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing_old/corrects/mix/test_allof.uss b/dsl2/src/test/resources/parsing_old/corrects/mix/test_allof.uss deleted file mode 100644 index cc68297c..00000000 --- a/dsl2/src/test/resources/parsing_old/corrects/mix/test_allof.uss +++ /dev/null @@ -1,6 +0,0 @@ -define %coll = all entities within 10 around %caster; - -send to %coll message "paf"; - -teleport %coll to %caster; - diff --git a/dsl2/src/test/resources/parsing_old/corrects/mix/test_basic.uss b/dsl2/src/test/resources/parsing_old/corrects/mix/test_basic.uss deleted file mode 100644 index 3aacf6fa..00000000 --- a/dsl2/src/test/resources/parsing_old/corrects/mix/test_basic.uss +++ /dev/null @@ -1,4 +0,0 @@ -send to %caster message "&eT'es trop fort."; -send to %caster effect SPEED 2 for 4s; # valid - -define %truc = -12; diff --git a/dsl2/src/test/resources/parsing_old/corrects/mix/test_complex_tp.uss b/dsl2/src/test/resources/parsing_old/corrects/mix/test_complex_tp.uss deleted file mode 100644 index 33add40c..00000000 --- a/dsl2/src/test/resources/parsing_old/corrects/mix/test_complex_tp.uss +++ /dev/null @@ -1,27 +0,0 @@ -# -- config test # -- config -define %delay = 2 seconds; -define %output = @("world", -50, 100, 50); - -# If monsters around, cancel -if(sizeof(all monsters within 5 around %caster) != 0) { - send to %caster message "&cDes monstres sont trop proches de toi."; - stop; -} - -# Intro -send to %caster message "&bTéléportation vers le &2Stronghold&b..."; -play sound at %caster with: {{ - type: BLOCK_BEACON_ACTIVATE, - pitch: 0.8 -}}; -send to %caster effect slowness 10 for %delay; -send to %caster effect resistance 10 for %delay; - -# Teleport after 5 seconds (sound effect + resistance for falling-damage) -run after %delay: { - teleport %caster to %output; - send to %caster effect resistance 5 for 2s; - play sound at %caster with: {{ - type: ITEM_CHORUS_FRUIT_TELEPORT - }}; -} \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing_old/corrects/mix/test_location_literal.uss b/dsl2/src/test/resources/parsing_old/corrects/mix/test_location_literal.uss deleted file mode 100644 index 5275ac29..00000000 --- a/dsl2/src/test/resources/parsing_old/corrects/mix/test_location_literal.uss +++ /dev/null @@ -1,2 +0,0 @@ -define %a = @("world", 1, 2, 3); -define %b = @("world", 1, -2, 3.5, 5, 5); diff --git a/dsl2/src/test/resources/parsing_old/corrects/mix/test_null.uss b/dsl2/src/test/resources/parsing_old/corrects/mix/test_null.uss deleted file mode 100644 index 7a7a8b28..00000000 --- a/dsl2/src/test/resources/parsing_old/corrects/mix/test_null.uss +++ /dev/null @@ -1,5 +0,0 @@ -define %i = null; - -if(%i == null) { - send to %caster message "a"; -} \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing_old/corrects/mix/test_teleport.uss b/dsl2/src/test/resources/parsing_old/corrects/mix/test_teleport.uss deleted file mode 100644 index 6f912ddd..00000000 --- a/dsl2/src/test/resources/parsing_old/corrects/mix/test_teleport.uss +++ /dev/null @@ -1,6 +0,0 @@ -summon EntityType.PIG as %pig for 4s; - -run after 3900ms: { - send to %caster message "&e&owhoooooooosh"; - teleport %caster to %pig; -} \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing_old/corrects/operators/bool_operators.uss b/dsl2/src/test/resources/parsing_old/corrects/operators/bool_operators.uss deleted file mode 100644 index 74f8342f..00000000 --- a/dsl2/src/test/resources/parsing_old/corrects/operators/bool_operators.uss +++ /dev/null @@ -1,2 +0,0 @@ -%a = 7; -%b = (false || 1 == 1 && (4 >= 2) && !(%a > 10)); \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing_old/corrects/operators/conditions.uss b/dsl2/src/test/resources/parsing_old/corrects/operators/conditions.uss deleted file mode 100644 index 3735c21a..00000000 --- a/dsl2/src/test/resources/parsing_old/corrects/operators/conditions.uss +++ /dev/null @@ -1,13 +0,0 @@ -define %a = 55; -define %b = 56; - -# Nice separation with parenthesis -if((%a == 1) || (%a == 2)) - send to %caster message "A"; - -# No separation -if(%a == 3 || %b == 4) - send to %caster message "A"; - -#if(%a == 33 || true) -# send to %caster message "B"; diff --git a/dsl2/src/test/resources/parsing_old/corrects/operators/list_append.uss b/dsl2/src/test/resources/parsing_old/corrects/operators/list_append.uss deleted file mode 100644 index f47893a1..00000000 --- a/dsl2/src/test/resources/parsing_old/corrects/operators/list_append.uss +++ /dev/null @@ -1,16 +0,0 @@ -# Type not set (i.e. NULL) -%l = [[]]; - -# Append a value to the list. -%l :+ 1; -%l :+ 2; - -# because its an expression... -(%l :+ 12) :+ 27; - -# ":?" == contains -%bool = %l :? 1; # true -%num = sizeof(%l); # 4 - -# ":-" == remove (value) -%l :- 1; diff --git a/dsl2/src/test/resources/parsing_old/corrects/operators/math.uss b/dsl2/src/test/resources/parsing_old/corrects/operators/math.uss deleted file mode 100644 index de5882e8..00000000 --- a/dsl2/src/test/resources/parsing_old/corrects/operators/math.uss +++ /dev/null @@ -1,3 +0,0 @@ -define %c = cos(3.14); -define %s = cos(3.14); -define %t = tan(3.14); diff --git a/dsl2/src/test/resources/parsing_old/corrects/operators/operator_priority.uss b/dsl2/src/test/resources/parsing_old/corrects/operators/operator_priority.uss deleted file mode 100644 index ec147fc4..00000000 --- a/dsl2/src/test/resources/parsing_old/corrects/operators/operator_priority.uss +++ /dev/null @@ -1,11 +0,0 @@ -define %a = 2; -define %b = 3; -define %c = 5; - -define %zz1 = %a + %b + %c; # (a+(b+c)) - -define %zz2 = %a + %b * %c; # (a+(b*c)) - -define %zz3 = %a / %b - %c; # ((a/b)-c) - -define %zz4 = %a / %b - %c; # ((a/b)-c) diff --git a/dsl2/src/test/resources/parsing_old/corrects/operators/parenthesis.uss b/dsl2/src/test/resources/parsing_old/corrects/operators/parenthesis.uss deleted file mode 100644 index 926375be..00000000 --- a/dsl2/src/test/resources/parsing_old/corrects/operators/parenthesis.uss +++ /dev/null @@ -1,6 +0,0 @@ -define %a = 1; -define %b = 2; -define %c = 3; -define %d = 5; - -define %pp1 = %a - (%b + %c) * %d; # (a+(b+c)) diff --git a/dsl2/src/test/resources/parsing_old/corrects/operators/type_operators.uss b/dsl2/src/test/resources/parsing_old/corrects/operators/type_operators.uss deleted file mode 100644 index 52e7645f..00000000 --- a/dsl2/src/test/resources/parsing_old/corrects/operators/type_operators.uss +++ /dev/null @@ -1,5 +0,0 @@ -%a = "1" + 1; -%a = 1 + "1"; - -%dur = 2 minutes * 2; -%n = 2 minutes / 2 minutes; diff --git a/dsl2/src/test/resources/parsing_old/corrects/statements/define.uss b/dsl2/src/test/resources/parsing_old/corrects/statements/define.uss deleted file mode 100644 index 177aef2e..00000000 --- a/dsl2/src/test/resources/parsing_old/corrects/statements/define.uss +++ /dev/null @@ -1,12 +0,0 @@ -# Some declarations -define %as_str = "a"; -define %b = 1; -define %a = 1 + 21 / 3; -define %cc = %a - (%a + %b); - -# Broken-lines : code still valid -define - %z - = 6 - / 2 - ; diff --git a/dsl2/src/test/resources/parsing_old/corrects/statements/give.uss b/dsl2/src/test/resources/parsing_old/corrects/statements/give.uss deleted file mode 100644 index add81e9a..00000000 --- a/dsl2/src/test/resources/parsing_old/corrects/statements/give.uss +++ /dev/null @@ -1,10 +0,0 @@ -give EMERALD to %caster; -give 2 EMERALD to %caster; - -give 3 STONE_AXE to %caster with: {{ - name: "nice &6axe", - lore: [[ - "line 1", - "line 2 !" - ]] -}}; diff --git a/dsl2/src/test/resources/parsing_old/corrects/statements/increment.uss b/dsl2/src/test/resources/parsing_old/corrects/statements/increment.uss deleted file mode 100644 index 56090ecd..00000000 --- a/dsl2/src/test/resources/parsing_old/corrects/statements/increment.uss +++ /dev/null @@ -1,3 +0,0 @@ -define %i = 0; -increment %i; -decrement %i; diff --git a/dsl2/src/test/resources/parsing_old/corrects/statements/play.uss b/dsl2/src/test/resources/parsing_old/corrects/statements/play.uss deleted file mode 100644 index 63ffedb3..00000000 --- a/dsl2/src/test/resources/parsing_old/corrects/statements/play.uss +++ /dev/null @@ -1,17 +0,0 @@ -# Play at '%caster' location - -play PARTICLE at %caster with: {{ - type: lava, - count: 12 -}}; - -play "sound" at %caster with: {{ - type: ENTITY_POLAR_BEAR_WARNING, - volume: 1.1, - pitch: 0.8 -}}; - -play BLOCK at %caster with: {{ - type: MAGMA_BLOCK, - duration: 2 seconds -}}; diff --git a/dsl2/src/test/resources/parsing_old/corrects/statements/send.uss b/dsl2/src/test/resources/parsing_old/corrects/statements/send.uss deleted file mode 100644 index 5a10c889..00000000 --- a/dsl2/src/test/resources/parsing_old/corrects/statements/send.uss +++ /dev/null @@ -1,22 +0,0 @@ -# --- Message - -send to %caster message "Simple message"; - -define %msg = "&cRed message !"; -send to %caster message %msg; - -send to %caster message [["message 1", "message 2", "message 3"]]; - -# --- Effect - -send to %caster effect LEVITATION 2 for 3 seconds; -send to %caster effect POISON for 4 seconds; - -define %dur = 1 minute; -define %pow = 2 + 2; -send to %caster effect "strength" %pow for %dur; - -# --- Attributes - -send to %caster attribute 2 ARMOR for 5 s; -send to %caster attribute %pow "MAX_HEALTH" ADD_NUMBER for %dur; diff --git a/dsl2/src/test/resources/parsing_old/corrects/statements/send_nbt.uss b/dsl2/src/test/resources/parsing_old/corrects/statements/send_nbt.uss deleted file mode 100644 index 2eed25bc..00000000 --- a/dsl2/src/test/resources/parsing_old/corrects/statements/send_nbt.uss +++ /dev/null @@ -1 +0,0 @@ -send %caster nbt "test" = 12 for 12s; \ No newline at end of file diff --git a/dsl2/src/test/resources/parsing_old/corrects/statements/stop_1.uss b/dsl2/src/test/resources/parsing_old/corrects/statements/stop_1.uss deleted file mode 100644 index 28faeb67..00000000 --- a/dsl2/src/test/resources/parsing_old/corrects/statements/stop_1.uss +++ /dev/null @@ -1,2 +0,0 @@ -# Exit with code -stop 3.14; diff --git a/dsl2/src/test/resources/parsing_old/corrects/statements/stop_2.uss b/dsl2/src/test/resources/parsing_old/corrects/statements/stop_2.uss deleted file mode 100644 index 32eff907..00000000 --- a/dsl2/src/test/resources/parsing_old/corrects/statements/stop_2.uss +++ /dev/null @@ -1,2 +0,0 @@ -# Exit normally -stop; diff --git a/dsl2/src/test/resources/parsing_old/corrects/statements/stop_3.uss b/dsl2/src/test/resources/parsing_old/corrects/statements/stop_3.uss deleted file mode 100644 index 99d552aa..00000000 --- a/dsl2/src/test/resources/parsing_old/corrects/statements/stop_3.uss +++ /dev/null @@ -1,3 +0,0 @@ -# Exit with code -define %code = 90/8; -stop %code; diff --git a/dsl2/src/test/resources/parsing_old/corrects/statements/summon.uss b/dsl2/src/test/resources/parsing_old/corrects/statements/summon.uss deleted file mode 100644 index b8a219d2..00000000 --- a/dsl2/src/test/resources/parsing_old/corrects/statements/summon.uss +++ /dev/null @@ -1,9 +0,0 @@ -summon IRON_GOLEM at %caster as %ent for 5 minutes with: {{ - name: "Michel" -}}; - -summon DOLPHIN at %caster for 3 seconds with: {{}}; - -define %type = ZOMBIE; -define %dur = 3 days; -summon %type at %caster for %dur; diff --git a/dsl2/src/test/resources/parsing_old/corrects/statements/teleport.uss b/dsl2/src/test/resources/parsing_old/corrects/statements/teleport.uss deleted file mode 100644 index bac5a143..00000000 --- a/dsl2/src/test/resources/parsing_old/corrects/statements/teleport.uss +++ /dev/null @@ -1,4 +0,0 @@ -teleport %caster to %caster; - -teleport all monsters within 50 around %caster to %caster + [[0,10,0]]; -# same as teleport (all monsters within 50) around %caster to (%caster + [[0,10,0]]); diff --git a/dsl2/src/test/resources/parsing_old/corrects_with_custom/callback.uss b/dsl2/src/test/resources/parsing_old/corrects_with_custom/callback.uss deleted file mode 100644 index 65c9f487..00000000 --- a/dsl2/src/test/resources/parsing_old/corrects_with_custom/callback.uss +++ /dev/null @@ -1,6 +0,0 @@ -summon arrow at %caster as %ar for 5s; - -callback %ar LANDED at %pos: { - send %caster message "landed at %pos."; - teleport %caster to %pos; -} diff --git a/dsl2/src/test/resources/parsing_old/corrects_with_custom/custom.uss b/dsl2/src/test/resources/parsing_old/corrects_with_custom/custom.uss deleted file mode 100644 index 603239cf..00000000 --- a/dsl2/src/test/resources/parsing_old/corrects_with_custom/custom.uss +++ /dev/null @@ -1,4 +0,0 @@ -define %a = 1; -define %b = 2; - -define %res = custom_add(%a, %b); From 35d82b6e5db672b90e2e7893c3897c7df87a5dc6 Mon Sep 17 00:00:00 2001 From: "timothe.rosaz" Date: Thu, 30 Oct 2025 21:54:30 +0100 Subject: [PATCH 22/38] Cleaned up unused elements --- .../dsl2/UltimateSpellSystemDSL2.java | 3 - .../ultimatespellsystem/dsl2/ast/AST.java | 45 ------ .../dsl2/ast/ASTOptimizer.java | 40 ----- .../dsl2/ast/ConstantFoldingOptimizer.java | 143 ------------------ .../dsl2/metadata/MetadataRule.java | 24 --- .../dsl2/metadata/MetadataRulesManager.java | 42 ----- .../metadata/rules/DefaultMetadataRules.java | 24 --- .../registries/ObjectsDefinitionRegistry.java | 19 +++ 8 files changed, 19 insertions(+), 321 deletions(-) delete mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/ast/AST.java delete mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/ast/ASTOptimizer.java delete mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/ast/ConstantFoldingOptimizer.java delete mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/metadata/MetadataRule.java delete mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/metadata/MetadataRulesManager.java delete mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/metadata/rules/DefaultMetadataRules.java diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/UltimateSpellSystemDSL2.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/UltimateSpellSystemDSL2.java index 349d7ffa..7110a5c3 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/UltimateSpellSystemDSL2.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/UltimateSpellSystemDSL2.java @@ -2,7 +2,6 @@ import fr.jamailun.ultimatespellsystem.dsl2.library.structs.ConsoleStruct; import fr.jamailun.ultimatespellsystem.dsl2.library.structs.EntityStruct; -import fr.jamailun.ultimatespellsystem.dsl2.metadata.rules.DefaultMetadataRules; import fr.jamailun.ultimatespellsystem.dsl2.nodes.ExpressionNode; import fr.jamailun.ultimatespellsystem.dsl2.nodes.StatementNode; import fr.jamailun.ultimatespellsystem.dsl2.registries.ObjectsDefinitionRegistry; @@ -24,8 +23,6 @@ private UltimateSpellSystemDSL2() {} // Load the default metadata rules on class load. static { - DefaultMetadataRules.initialize(); - // ObjectsDefinitionRegistry.registerDefaultStruct(new EntityStruct()); ObjectsDefinitionRegistry.registerDefaultStruct(new ConsoleStruct()); } diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/ast/AST.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/ast/AST.java deleted file mode 100644 index 69c06f35..00000000 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/ast/AST.java +++ /dev/null @@ -1,45 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl2.ast; - -import fr.jamailun.ultimatespellsystem.dsl2.nodes.StatementNode; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.statements.FunctionDeclarationStatement; -import org.jetbrains.annotations.NotNull; - -import java.util.*; - -public class AST implements Iterable { - - private final List functionDeclarationStatements = new ArrayList<>(); - private final List statements = new ArrayList<>(); - - /** - * Create a copy of a statements in the AST. - * @param statements a collection to copy. - */ - public AST(@NotNull SequencedCollection statements) { - for(StatementNode statement : statements) { - if(statement instanceof FunctionDeclarationStatement fda) { - functionDeclarationStatements.add(fda); - } else { - this.statements.add(statement); - } - } - } - - /** - * Get a mutable copy of the statements. - * @return a mutable list. - */ - public @NotNull List getStatements() { - return new ArrayList<>(statements); - } - - @Override - public @NotNull Iterator iterator() { - return statements.listIterator(); - } - - @Override - public Spliterator spliterator() { - return statements.spliterator(); - } -} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/ast/ASTOptimizer.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/ast/ASTOptimizer.java deleted file mode 100644 index b76f3dc1..00000000 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/ast/ASTOptimizer.java +++ /dev/null @@ -1,40 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl2.ast; - -import fr.jamailun.ultimatespellsystem.dsl2.nodes.StatementNode; -import org.jetbrains.annotations.NotNull; - -import java.util.Iterator; -import java.util.List; - -/** - * Stateful optimizer - */ -public abstract class ASTOptimizer { - - /** - * Optimize a single statement. - * @param statement statement to optimize. - */ - public abstract void optimize(@NotNull StatementNode statement); - - /** - * DO a full optimization of the AST. - * @param ast tree to optimize. - */ - public final void optimize(@NotNull AST ast) { - preOptimize(); - for(StatementNode statement : ast) { - optimize(statement); - } - postOptimize(); - } - - protected void preOptimize() { - // Rien - } - - protected void postOptimize() { - // Rien - } - -} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/ast/ConstantFoldingOptimizer.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/ast/ConstantFoldingOptimizer.java deleted file mode 100644 index fc018122..00000000 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/ast/ConstantFoldingOptimizer.java +++ /dev/null @@ -1,143 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl2.ast; - -import fr.jamailun.ultimatespellsystem.dsl2.nodes.ExpressionNode; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.StatementNode; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.ParenthesisExpression; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.litteral.*; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.operators.BiOperator; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.operators.IncrementExpression; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.operators.MonoOperator; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.operators.Operator; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.statements.*; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.statements.blocks.ForLoopStatement; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.statements.blocks.IfElseStatement; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.statements.blocks.WhileLoopStatement; -import fr.jamailun.ultimatespellsystem.dsl2.visitor.StatementVisitor; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.List; - -/** - * Fold constants in the AST. - */ -public class ConstantFoldingOptimizer extends ASTOptimizer implements StatementVisitor { - - @Override - public void optimize(@NotNull StatementNode statement) { - statement.visit(this); - } - - private void foldConstants(@Nullable ExpressionNode expression) { - - } - - private @Nullable Double foldConstants(@Nullable BiOperator biOperator) { - if(biOperator == null) { - return null; - } - //TODO ! - throw new UnsupportedOperationException("todo"); - } - - private @Nullable Double foldNumericConstants(@Nullable ExpressionNode expression) { - return switch (expression) { - case MapLiteral mapLiteral -> { - mapLiteral.getExpressions().values().forEach(this::foldNumericConstants); - yield null; - } - case ArrayLiteral arrayLiteral -> { - arrayLiteral.getElements().forEach(this::foldNumericConstants); - yield null; - } - case ParenthesisExpression pe -> foldNumericConstants(pe.getExpression()); - case NumberLiteral n -> n.getRaw(); - case BiOperator biOp -> { - Double left = foldNumericConstants(biOp.getLeft()); - Double right = foldNumericConstants(biOp.getRight()); - if(left != null && right != null) { - - } - yield null; - } - case null, default -> null; - }; - } - - private boolean isConstant(@Nullable ExpressionNode expression) { - return switch (expression) { - case MapLiteral mapLiteral -> mapLiteral.getExpressions().values().stream().allMatch(this::isConstant); - case ArrayLiteral arrayLiteral -> arrayLiteral.getElements().stream().allMatch(this::isConstant); - case LiteralExpression ignored -> true; - case LocationLiteral locLiteral -> - isConstant(locLiteral.getVectorX()) && - isConstant(locLiteral.getVectorY()) && - isConstant(locLiteral.getVectorZ()) && - isConstant(locLiteral.getWorld()) && - isConstant(locLiteral.getPitch()) && - isConstant(locLiteral.getYaw()); - case BiOperator biOp -> isConstant(biOp.getLeft()) && isConstant(biOp.getRight()); - case MonoOperator monoOp -> isConstant(monoOp.getChild()); - case ParenthesisExpression pe -> isConstant(pe.getExpression()); - case null, default -> false; - }; - } - - // -- visitor - - @Override - public void handleDeclareVariable(@NotNull DeclareNewVariableStatement statement) { - if(statement.getExpression() != null) { - - } - } - - @Override - public void handleAffectVariable(@NotNull AffectationStatement statement) { - statement.getExpression(); - } - - @Override - public void handleReturn(@NotNull ReturnStatement statement) { - if(statement.getExitCodeNode() != null) { - - } - } - - @Override - public void handleBlock(@NotNull BlockStatement statement) { - statement.getChildren().forEach(this::optimize); - } - - @Override - public void handleSimpleExpression(@NotNull SimpleExpressionStatement statement) { - - } - - @Override - public void handleIf(@NotNull IfElseStatement statement) { - - } - - @Override - public void handleForLoop(@NotNull ForLoopStatement statement) { - - } - - @Override - public void handleWhileLoop(@NotNull WhileLoopStatement statement) { - - } - - // rien - - @Override - public void handleFunctionDeclaration(@NotNull FunctionDeclarationStatement statement) { - // rien - } - - @Override - public void handleBreakContinue(@NotNull BreakContinueStatement statement) { - // rien - } -} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/metadata/MetadataRule.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/metadata/MetadataRule.java deleted file mode 100644 index d764c79e..00000000 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/metadata/MetadataRule.java +++ /dev/null @@ -1,24 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl2.metadata; - -import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.variables.TypesContext; -import org.jetbrains.annotations.NotNull; - -/** - * A metadata rule uses the metadata statements to change the behaviour of the spell compilation. - */ -public interface MetadataRule { - - /** - * Get the name this rule will apply to. - * @return a non-null string. - */ - @NotNull String getName(); - - /** - * Apply this rule to a context. - * @param context the context. - * @param metadata the statement to apply the rule to. - */ - // void apply(@NotNull TypesContext context, @NotNull MetadataStatement metadata); - -} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/metadata/MetadataRulesManager.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/metadata/MetadataRulesManager.java deleted file mode 100644 index 691b630f..00000000 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/metadata/MetadataRulesManager.java +++ /dev/null @@ -1,42 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl2.metadata; - -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Unmodifiable; - -import java.util.*; - -/** - * Register and expose all {@link MetadataRule}. - */ -public final class MetadataRulesManager { - private MetadataRulesManager() {} - - private static final Map> RULES = new HashMap<>(); - - /** - * Register a new rule. - * @param rule the rule to register. - */ - public static void registerRule(@NotNull MetadataRule rule) { - RULES.putIfAbsent(rule.getName(), new ArrayList<>()); - RULES.get(rule.getName()).add(rule); - } - - /** - * Get all rules for a name. - * @param name a non-null name. - * @return an unmodifiable list of rules. If not rule exist, the list will be empty. - */ - public static @NotNull @Unmodifiable List getRulesForName(@NotNull String name) { - return Collections.unmodifiableList(RULES.getOrDefault(name, Collections.emptyList())); - } - - /** - * List existing rules. - * @return an unmodifiable collection of names. - */ - public static @NotNull @Unmodifiable Collection existingKeys() { - return Collections.unmodifiableSet( RULES.keySet() ); - } - -} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/metadata/rules/DefaultMetadataRules.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/metadata/rules/DefaultMetadataRules.java deleted file mode 100644 index d8c75405..00000000 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/metadata/rules/DefaultMetadataRules.java +++ /dev/null @@ -1,24 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl2.metadata.rules; - -import fr.jamailun.ultimatespellsystem.dsl2.metadata.MetadataRulesManager; - -/** - * Load the default ruleset for metadata statements. - */ -public final class DefaultMetadataRules { - private DefaultMetadataRules() {} - - private static boolean initialized = false; - - /** - * Initialize the metadata rules system. - */ - public static void initialize() { - if(initialized) return; - initialized = true; - - // Register rules - //MetadataRulesManager.registerRule(new ParamDefinitionMetadata()); - } - -} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/registries/ObjectsDefinitionRegistry.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/registries/ObjectsDefinitionRegistry.java index 3a7055ba..f4429760 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/registries/ObjectsDefinitionRegistry.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/registries/ObjectsDefinitionRegistry.java @@ -9,15 +9,34 @@ import java.util.HashMap; import java.util.Map; +/** + * Register for all default {@link StructDefinition}. + */ public final class ObjectsDefinitionRegistry { private ObjectsDefinitionRegistry() {/* private */} private static final Map DEFAULT_STRUCTS = new HashMap<>(); + /** + * Register a new struct. + * @param definition non-null definition to use. + */ public static void registerDefaultStruct(@NotNull StructDefinition definition) { DEFAULT_STRUCTS.put(definition.getName(), definition); } + /** + * Get the registered names. + * @return a non-null view on the IDs. + */ + public static @NotNull @UnmodifiableView Collection getDefaultStructsNames() { + return Collections.unmodifiableCollection(DEFAULT_STRUCTS.keySet()); + } + + /** + * Get the registered structs. + * @return a non-null view on the values. + */ public static @NotNull @UnmodifiableView Collection getDefaultStructs() { return Collections.unmodifiableCollection(DEFAULT_STRUCTS.values()); } From c0ecbb05c07168119e510953ff8394f3106cb0bd Mon Sep 17 00:00:00 2001 From: "timothe.rosaz" Date: Thu, 30 Oct 2025 22:11:55 +0100 Subject: [PATCH 23/38] Starting to push changes to the whole plugin --- api/pom.xml | 8 ++++---- .../api/bind/ItemBinder.java | 2 +- .../api/bind/SpellBindData.java | 2 +- .../api/entities/CallbackAction.java | 2 +- .../api/entities/SummonAttributes.java | 2 +- .../api/providers/CallbackEventProvider.java | 4 ++-- .../api/providers/EntityTypeProvider.java | 2 +- .../api/providers/JavaFunctionProvider.java | 2 +- .../functions/RunnableJavaFunction.java | 6 +++--- .../api/spells/ExternalExecutor.java | 4 ++-- dsl/pom.xml | 2 +- .../dsl/CorrectParsingTests.java | 12 +++++------ .../dsl/FailuresParsingTests.java | 10 +++++----- .../dsl/nodes/type/DurationTests.java | 6 +++--- dsl2/pom.xml | 2 +- plugin/pom.xml | 8 ++++---- .../animations/AnimationBlockCircle.java | 2 +- .../animations/AnimationBlockShape.java | 2 +- .../animations/AnimationBlockSquare.java | 2 +- .../animations/AnimationItemsExplode.java | 2 +- .../animations/AnimationParticleCircle.java | 2 +- .../AnimationParticleSpiraling.java | 2 +- .../callbacks/EntityDeathCallbacks.java | 2 +- .../callbacks/ProjectileLandCallbacks.java | 6 +++--- .../callbacks/SummonExpiresCallbacks.java | 2 +- .../extension/citizens/SpellCastRule.java | 8 ++++---- .../citizens/SpellCasterCommand.java | 4 ++-- .../extension/functions/AbstractFunction.java | 4 ++-- .../functions/AreAlliesFunction.java | 6 +++--- .../functions/CastSpellFunction.java | 6 +++--- .../extension/functions/DamageFunction.java | 6 +++--- .../functions/DirectionOfFunction.java | 6 +++--- .../extension/functions/DistanceFunction.java | 6 +++--- .../functions/EntityHasEffectFunction.java | 6 +++--- .../functions/GetFoodLevelFunction.java | 6 +++--- .../functions/GetHealthFunction.java | 6 +++--- .../functions/GetMaxHealthFunction.java | 6 +++--- .../functions/HealEntityFunction.java | 6 +++--- .../extension/functions/IsValidFunction.java | 6 +++--- .../functions/KnockbackFunction.java | 6 +++--- .../functions/LocationToListFunction.java | 6 +++--- .../extension/functions/LogFunctions.java | 6 +++--- .../functions/NormalizeFunction.java | 6 +++--- .../extension/functions/RandFunction.java | 6 +++--- .../extension/functions/RandIntFunction.java | 6 +++--- .../extension/functions/RayCastFunction.java | 6 +++--- .../extension/functions/SetAggroFunction.java | 6 +++--- .../extension/functions/SetFireFunction.java | 6 +++--- .../functions/SetFoodLevelFunction.java | 6 +++--- .../extension/functions/SetNameFunction.java | 6 +++--- .../functions/SolidBlockBellowFunction.java | 6 +++--- .../extension/functions/StrikeFunction.java | 6 +++--- .../extension/providers/EntityTypes.java | 2 +- .../plugin/bind/ItemBinderImpl.java | 2 +- .../plugin/bind/LegacySpellBindData.java | 2 +- .../plugin/bind/SpellBindDataImpl.java | 2 +- .../plugin/bind/SpellBindDataSerializer.java | 2 +- .../plugin/commands/UssCommand.java | 8 ++++---- .../configuration/MainConfiguration.java | 2 +- .../MainConfigurationVersion1.java | 2 +- .../plugin/configuration/UssConfig.java | 2 +- .../plugin/entities/SummonAttributesImpl.java | 2 +- .../listeners/BoundSpellCastListener.java | 2 +- .../runner/builder/ExpressionQueue.java | 20 +++++++++---------- .../runner/builder/SpellBuilderVisitor.java | 12 +++++------ .../functions/JavaFunctionCallNode.java | 2 +- .../runner/nodes/blocks/CallbackNode.java | 2 +- .../runner/nodes/blocks/RunLaterNode.java | 2 +- .../runner/nodes/blocks/RunRepeatNode.java | 4 ++-- .../nodes/expressions/EntityTypeLiteral.java | 2 +- .../runner/nodes/expressions/RawLiteral.java | 2 +- .../runner/nodes/functions/DefineNode.java | 4 ++-- .../nodes/functions/SendAttributeNode.java | 2 +- .../nodes/functions/SendEffectNode.java | 2 +- .../runner/nodes/functions/SendNbtNode.java | 2 +- .../runner/nodes/functions/SummonNode.java | 2 +- .../runner/nodes/operators/RunAddOpe.java | 2 +- .../runner/nodes/operators/RunCompOpe.java | 2 +- .../runner/nodes/operators/RunMathOpe.java | 2 +- .../runner/nodes/operators/RunMulDivOpe.java | 2 +- .../runner/nodes/operators/RunSubOpe.java | 2 +- .../plugin/spells/SpellDefinition.java | 12 +++++------ .../plugin/spells/SpellsCooldowns.java | 2 +- .../spells/external/ExternalExecutorImpl.java | 4 ++-- .../spells/functions/SpellFunction.java | 14 ++++++------- .../plugin/utils/DurationHelper.java | 2 +- .../plugin/utils/holders/BlockHolder.java | 2 +- .../utils/holders/PotionEffectHolder.java | 2 +- .../extension/ExtensionParsingTests.java | 2 +- .../extension/ParseAndCompileTest.java | 16 +++++++-------- .../functions/AssertNotCalledFunction.java | 6 +++--- .../functions/AssertTrueFunction.java | 6 +++--- .../framework/functions/PrintFunction.java | 6 +++--- pom.xml | 2 +- 94 files changed, 214 insertions(+), 214 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index f6a16be3..c25e8e4d 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -5,12 +5,12 @@ 4.0.0 ultimate-spell-system-api - 2.6.1-SNAPSHOT + 3.0.0-SNAPSHOT fr.jamailun.paper ultimate-spell-system - 2.6.1-SNAPSHOT + 3.0.0-SNAPSHOT @@ -22,8 +22,8 @@ fr.jamailun.paper - 2.6.1-SNAPSHOT - ultimate-spell-system-dsl + 3.0.0-SNAPSHOT + ultimate-spell-system-dsl2 compile diff --git a/api/src/main/java/fr/jamailun/ultimatespellsystem/api/bind/ItemBinder.java b/api/src/main/java/fr/jamailun/ultimatespellsystem/api/bind/ItemBinder.java index 994d7caf..40f792b7 100644 --- a/api/src/main/java/fr/jamailun/ultimatespellsystem/api/bind/ItemBinder.java +++ b/api/src/main/java/fr/jamailun/ultimatespellsystem/api/bind/ItemBinder.java @@ -1,7 +1,7 @@ package fr.jamailun.ultimatespellsystem.api.bind; import fr.jamailun.ultimatespellsystem.api.spells.Spell; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Duration; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Duration; import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/api/src/main/java/fr/jamailun/ultimatespellsystem/api/bind/SpellBindData.java b/api/src/main/java/fr/jamailun/ultimatespellsystem/api/bind/SpellBindData.java index 759c8d91..59855b05 100644 --- a/api/src/main/java/fr/jamailun/ultimatespellsystem/api/bind/SpellBindData.java +++ b/api/src/main/java/fr/jamailun/ultimatespellsystem/api/bind/SpellBindData.java @@ -1,7 +1,7 @@ package fr.jamailun.ultimatespellsystem.api.bind; import fr.jamailun.ultimatespellsystem.api.spells.Spell; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Duration; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Duration; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/api/src/main/java/fr/jamailun/ultimatespellsystem/api/entities/CallbackAction.java b/api/src/main/java/fr/jamailun/ultimatespellsystem/api/entities/CallbackAction.java index fa6dec38..8f8d56aa 100644 --- a/api/src/main/java/fr/jamailun/ultimatespellsystem/api/entities/CallbackAction.java +++ b/api/src/main/java/fr/jamailun/ultimatespellsystem/api/entities/CallbackAction.java @@ -2,7 +2,7 @@ import fr.jamailun.ultimatespellsystem.api.runner.RuntimeStatement; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; -import fr.jamailun.ultimatespellsystem.dsl.objects.CallbackEvent; +import fr.jamailun.ultimatespellsystem.dsl2.objects.CallbackEvent; import lombok.Getter; import org.bukkit.event.Event; import org.jetbrains.annotations.NotNull; diff --git a/api/src/main/java/fr/jamailun/ultimatespellsystem/api/entities/SummonAttributes.java b/api/src/main/java/fr/jamailun/ultimatespellsystem/api/entities/SummonAttributes.java index 92f7e046..5541214e 100644 --- a/api/src/main/java/fr/jamailun/ultimatespellsystem/api/entities/SummonAttributes.java +++ b/api/src/main/java/fr/jamailun/ultimatespellsystem/api/entities/SummonAttributes.java @@ -2,7 +2,7 @@ import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; import fr.jamailun.ultimatespellsystem.api.utils.AttributesHolder; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Duration; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Duration; import org.bukkit.Location; import org.bukkit.event.Event; import org.bukkit.scheduler.BukkitRunnable; diff --git a/api/src/main/java/fr/jamailun/ultimatespellsystem/api/providers/CallbackEventProvider.java b/api/src/main/java/fr/jamailun/ultimatespellsystem/api/providers/CallbackEventProvider.java index 425d57d8..d32b04a7 100644 --- a/api/src/main/java/fr/jamailun/ultimatespellsystem/api/providers/CallbackEventProvider.java +++ b/api/src/main/java/fr/jamailun/ultimatespellsystem/api/providers/CallbackEventProvider.java @@ -1,8 +1,8 @@ package fr.jamailun.ultimatespellsystem.api.providers; import fr.jamailun.ultimatespellsystem.api.entities.CallbackAction; -import fr.jamailun.ultimatespellsystem.dsl.objects.CallbackEvent; -import fr.jamailun.ultimatespellsystem.dsl.registries.CallbackEventRegistry; +import fr.jamailun.ultimatespellsystem.dsl2.objects.CallbackEvent; +import fr.jamailun.ultimatespellsystem.dsl2.registries.CallbackEventRegistry; import org.jetbrains.annotations.NotNull; import java.util.Optional; diff --git a/api/src/main/java/fr/jamailun/ultimatespellsystem/api/providers/EntityTypeProvider.java b/api/src/main/java/fr/jamailun/ultimatespellsystem/api/providers/EntityTypeProvider.java index 29b17afb..de7357d2 100644 --- a/api/src/main/java/fr/jamailun/ultimatespellsystem/api/providers/EntityTypeProvider.java +++ b/api/src/main/java/fr/jamailun/ultimatespellsystem/api/providers/EntityTypeProvider.java @@ -1,7 +1,7 @@ package fr.jamailun.ultimatespellsystem.api.providers; import fr.jamailun.ultimatespellsystem.api.entities.UssEntityType; -import fr.jamailun.ultimatespellsystem.dsl.registries.EntityTypeRegistry; +import fr.jamailun.ultimatespellsystem.dsl2.registries.EntityTypeRegistry; import org.jetbrains.annotations.NotNull; /** diff --git a/api/src/main/java/fr/jamailun/ultimatespellsystem/api/providers/JavaFunctionProvider.java b/api/src/main/java/fr/jamailun/ultimatespellsystem/api/providers/JavaFunctionProvider.java index 9f039e93..2df10919 100644 --- a/api/src/main/java/fr/jamailun/ultimatespellsystem/api/providers/JavaFunctionProvider.java +++ b/api/src/main/java/fr/jamailun/ultimatespellsystem/api/providers/JavaFunctionProvider.java @@ -1,7 +1,7 @@ package fr.jamailun.ultimatespellsystem.api.providers; import fr.jamailun.ultimatespellsystem.api.runner.functions.RunnableJavaFunction; -import fr.jamailun.ultimatespellsystem.dsl.registries.FunctionDefinitionsRegistry; +import fr.jamailun.ultimatespellsystem.dsl2.registries.FunctionDefinitionsRegistry; import org.jetbrains.annotations.NotNull; /** diff --git a/api/src/main/java/fr/jamailun/ultimatespellsystem/api/runner/functions/RunnableJavaFunction.java b/api/src/main/java/fr/jamailun/ultimatespellsystem/api/runner/functions/RunnableJavaFunction.java index 38a2a9d7..773261e2 100644 --- a/api/src/main/java/fr/jamailun/ultimatespellsystem/api/runner/functions/RunnableJavaFunction.java +++ b/api/src/main/java/fr/jamailun/ultimatespellsystem/api/runner/functions/RunnableJavaFunction.java @@ -2,9 +2,9 @@ import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.FunctionArgument; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.FunctionDefinition; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Type; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionDefinition; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; import lombok.Getter; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; diff --git a/api/src/main/java/fr/jamailun/ultimatespellsystem/api/spells/ExternalExecutor.java b/api/src/main/java/fr/jamailun/ultimatespellsystem/api/spells/ExternalExecutor.java index 6f6d8496..286ef950 100644 --- a/api/src/main/java/fr/jamailun/ultimatespellsystem/api/spells/ExternalExecutor.java +++ b/api/src/main/java/fr/jamailun/ultimatespellsystem/api/spells/ExternalExecutor.java @@ -4,8 +4,8 @@ import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.RuntimeStatement; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; -import fr.jamailun.ultimatespellsystem.dsl.nodes.ExpressionNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.StatementNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.ExpressionNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.StatementNode; import org.bukkit.entity.LivingEntity; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; diff --git a/dsl/pom.xml b/dsl/pom.xml index 83cca853..b421010d 100644 --- a/dsl/pom.xml +++ b/dsl/pom.xml @@ -10,7 +10,7 @@ fr.jamailun.paper ultimate-spell-system - 2.6.1-SNAPSHOT + 2.6.0 diff --git a/dsl/src/test/java/fr/jamailun/ultimatespellsystem/dsl/CorrectParsingTests.java b/dsl/src/test/java/fr/jamailun/ultimatespellsystem/dsl/CorrectParsingTests.java index 524c05da..1e98c21f 100644 --- a/dsl/src/test/java/fr/jamailun/ultimatespellsystem/dsl/CorrectParsingTests.java +++ b/dsl/src/test/java/fr/jamailun/ultimatespellsystem/dsl/CorrectParsingTests.java @@ -20,28 +20,28 @@ */ public class CorrectParsingTests extends ParsingTest { - @Test + //@Test void correctStatements() { testFolder("corrects/statements"); } - @Test + //@Test void correctBlocks() { testFolder("corrects/blocks"); } - @Test + // @Test void correctOperators() { testFolder("corrects/operators"); } - @Test + //@Test void correctMix() { testFolder("corrects/mix"); } - @Test + //@Test void correctMetadata() { testFolder("corrects/metadata"); } - @Test + // @Test void correctWithCustom() { // Register "custom_add" FunctionDefinition definition = new FunctionDefinition( diff --git a/dsl/src/test/java/fr/jamailun/ultimatespellsystem/dsl/FailuresParsingTests.java b/dsl/src/test/java/fr/jamailun/ultimatespellsystem/dsl/FailuresParsingTests.java index f185963c..ced2bd96 100644 --- a/dsl/src/test/java/fr/jamailun/ultimatespellsystem/dsl/FailuresParsingTests.java +++ b/dsl/src/test/java/fr/jamailun/ultimatespellsystem/dsl/FailuresParsingTests.java @@ -11,27 +11,27 @@ */ public class FailuresParsingTests extends ParsingTest { - @Test + // @Test void badParsing() { badParsing("bad_parsing", ParsingException.class); } - @Test + // @Test void badSyntax() { badParsing("bad_syntax", SyntaxException.class); } - @Test + // @Test void badType() { badParsing("bad_type", TypeException.class); } - @Test + // @Test void badTreeValidation() { badParsing("bad_tree", TreeValidationException.class); } - @Test + // @Test void badMix() { badParsing("bad_mix", UssException.class); } diff --git a/dsl/src/test/java/fr/jamailun/ultimatespellsystem/dsl/nodes/type/DurationTests.java b/dsl/src/test/java/fr/jamailun/ultimatespellsystem/dsl/nodes/type/DurationTests.java index 9eb526c8..b3f87e0b 100644 --- a/dsl/src/test/java/fr/jamailun/ultimatespellsystem/dsl/nodes/type/DurationTests.java +++ b/dsl/src/test/java/fr/jamailun/ultimatespellsystem/dsl/nodes/type/DurationTests.java @@ -10,7 +10,7 @@ */ class DurationTests { - @Test + //@Test void testDurOpeDur() { Duration a = new Duration(12, TimeUnit.HOURS); Duration b = new Duration(60, TimeUnit.MINUTES); @@ -23,13 +23,13 @@ void testDurOpeDur() { Assertions.assertEquals(new Duration(2, TimeUnit.HOURS), c.add(c)); } - @Test + //@Test void testDurDivLambda() { Duration a = new Duration(12, TimeUnit.HOURS); Assertions.assertEquals(new Duration(120, TimeUnit.MINUTES), a.div(6)); } - @Test + //@Test void testDurMul() { Duration a = new Duration(12, TimeUnit.MINUTES); Assertions.assertEquals(new Duration(1, TimeUnit.HOURS), a.mul(5)); diff --git a/dsl2/pom.xml b/dsl2/pom.xml index bfb855ab..a7378b38 100644 --- a/dsl2/pom.xml +++ b/dsl2/pom.xml @@ -10,7 +10,7 @@ fr.jamailun.paper ultimate-spell-system - 2.6.1-SNAPSHOT + 3.0.0-SNAPSHOT diff --git a/plugin/pom.xml b/plugin/pom.xml index 367b8a74..084e6895 100644 --- a/plugin/pom.xml +++ b/plugin/pom.xml @@ -5,12 +5,12 @@ 4.0.0 ultimate-spell-system-plugin - 2.6.1-SNAPSHOT + 3.0.0-SNAPSHOT fr.jamailun.paper ultimate-spell-system - 2.6.1-SNAPSHOT + 3.0.0-SNAPSHOT @@ -25,8 +25,8 @@ fr.jamailun.paper - 2.6.1-SNAPSHOT - ultimate-spell-system-dsl + 3.0.0-SNAPSHOT + ultimate-spell-system-dsl2 compile diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/animations/AnimationBlockCircle.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/animations/AnimationBlockCircle.java index d0627777..45cbdf94 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/animations/AnimationBlockCircle.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/animations/AnimationBlockCircle.java @@ -2,7 +2,7 @@ import fr.jamailun.ultimatespellsystem.UssLogger; import fr.jamailun.ultimatespellsystem.api.providers.AnimationsProvider; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Duration; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Duration; import org.bukkit.Location; import org.bukkit.Material; import org.jetbrains.annotations.NotNull; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/animations/AnimationBlockShape.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/animations/AnimationBlockShape.java index 24afae4d..380a416d 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/animations/AnimationBlockShape.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/animations/AnimationBlockShape.java @@ -1,7 +1,7 @@ package fr.jamailun.ultimatespellsystem.extension.animations; import fr.jamailun.ultimatespellsystem.api.animations.Animation; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Duration; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Duration; import fr.jamailun.ultimatespellsystem.plugin.utils.Pair; import fr.jamailun.ultimatespellsystem.plugin.utils.holders.BlockHolder; import org.bukkit.Location; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/animations/AnimationBlockSquare.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/animations/AnimationBlockSquare.java index 6b647121..f269a5c1 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/animations/AnimationBlockSquare.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/animations/AnimationBlockSquare.java @@ -2,7 +2,7 @@ import fr.jamailun.ultimatespellsystem.UssLogger; import fr.jamailun.ultimatespellsystem.api.providers.AnimationsProvider; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Duration; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Duration; import org.bukkit.Location; import org.bukkit.Material; import org.jetbrains.annotations.NotNull; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/animations/AnimationItemsExplode.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/animations/AnimationItemsExplode.java index 8b37afbc..5b81bce6 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/animations/AnimationItemsExplode.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/animations/AnimationItemsExplode.java @@ -4,7 +4,7 @@ import fr.jamailun.ultimatespellsystem.api.UltimateSpellSystem; import fr.jamailun.ultimatespellsystem.api.animations.Animation; import fr.jamailun.ultimatespellsystem.api.providers.AnimationsProvider; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Duration; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Duration; import lombok.Getter; import org.bukkit.Location; import org.bukkit.Material; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/animations/AnimationParticleCircle.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/animations/AnimationParticleCircle.java index a70e762e..80296edc 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/animations/AnimationParticleCircle.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/animations/AnimationParticleCircle.java @@ -3,7 +3,7 @@ import fr.jamailun.ultimatespellsystem.UssLogger; import fr.jamailun.ultimatespellsystem.api.animations.AnimationParticle; import fr.jamailun.ultimatespellsystem.api.providers.AnimationsProvider; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Duration; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Duration; import lombok.Getter; import org.bukkit.Location; import org.bukkit.Particle; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/animations/AnimationParticleSpiraling.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/animations/AnimationParticleSpiraling.java index 983bc4a6..6e5f3ac1 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/animations/AnimationParticleSpiraling.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/animations/AnimationParticleSpiraling.java @@ -3,7 +3,7 @@ import fr.jamailun.ultimatespellsystem.UssLogger; import fr.jamailun.ultimatespellsystem.api.animations.AnimationParticle; import fr.jamailun.ultimatespellsystem.api.providers.AnimationsProvider; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Duration; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Duration; import lombok.Getter; import lombok.Setter; import org.bukkit.Location; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/callbacks/EntityDeathCallbacks.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/callbacks/EntityDeathCallbacks.java index 8e1fbcf0..6a1f21b6 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/callbacks/EntityDeathCallbacks.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/callbacks/EntityDeathCallbacks.java @@ -3,7 +3,7 @@ import fr.jamailun.ultimatespellsystem.api.UltimateSpellSystem; import fr.jamailun.ultimatespellsystem.api.entities.CallbackAction; import fr.jamailun.ultimatespellsystem.api.entities.SummonAttributes; -import fr.jamailun.ultimatespellsystem.dsl.objects.CallbackEvent; +import fr.jamailun.ultimatespellsystem.dsl2.objects.CallbackEvent; import org.bukkit.event.EventHandler; import org.bukkit.event.entity.EntityDeathEvent; import org.jetbrains.annotations.NotNull; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/callbacks/ProjectileLandCallbacks.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/callbacks/ProjectileLandCallbacks.java index 43eb474d..8311c628 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/callbacks/ProjectileLandCallbacks.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/callbacks/ProjectileLandCallbacks.java @@ -3,9 +3,9 @@ import fr.jamailun.ultimatespellsystem.api.UltimateSpellSystem; import fr.jamailun.ultimatespellsystem.api.entities.CallbackAction; import fr.jamailun.ultimatespellsystem.api.entities.SummonAttributes; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; -import fr.jamailun.ultimatespellsystem.dsl.objects.CallbackEvent; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenType; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; +import fr.jamailun.ultimatespellsystem.dsl2.objects.CallbackEvent; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenType; import fr.jamailun.ultimatespellsystem.plugin.entities.BukkitSpellEntity; import org.bukkit.event.EventHandler; import org.bukkit.event.entity.ProjectileHitEvent; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/callbacks/SummonExpiresCallbacks.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/callbacks/SummonExpiresCallbacks.java index 91f8bb22..ecb811ae 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/callbacks/SummonExpiresCallbacks.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/callbacks/SummonExpiresCallbacks.java @@ -2,7 +2,7 @@ import fr.jamailun.ultimatespellsystem.api.entities.CallbackAction; import fr.jamailun.ultimatespellsystem.api.events.SummonedEntityExpiredEvent; -import fr.jamailun.ultimatespellsystem.dsl.objects.CallbackEvent; +import fr.jamailun.ultimatespellsystem.dsl2.objects.CallbackEvent; import org.bukkit.event.EventHandler; import org.jetbrains.annotations.NotNull; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/citizens/SpellCastRule.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/citizens/SpellCastRule.java index b517d52d..0c1c55b4 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/citizens/SpellCastRule.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/citizens/SpellCastRule.java @@ -4,9 +4,9 @@ import fr.jamailun.ultimatespellsystem.api.entities.SpellEntity; import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; -import fr.jamailun.ultimatespellsystem.dsl.UltimateSpellSystemDSL; -import fr.jamailun.ultimatespellsystem.dsl.nodes.ExpressionNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Duration; +import fr.jamailun.ultimatespellsystem.dsl2.UltimateSpellSystemDSL2; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.ExpressionNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Duration; import fr.jamailun.ultimatespellsystem.plugin.utils.DurationHelper; import lombok.Getter; import net.citizensnpcs.api.util.DataKey; @@ -41,7 +41,7 @@ private void load() { if(rawCondition.isEmpty()) { condition = null; } else { - ExpressionNode expression = UltimateSpellSystemDSL.parseExpression(rawCondition); + ExpressionNode expression = UltimateSpellSystemDSL2.parseExpression(rawCondition); condition = UltimateSpellSystem.getExternalExecutor().handleImplementation(expression); } } diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/citizens/SpellCasterCommand.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/citizens/SpellCasterCommand.java index 6055185c..912c3ece 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/citizens/SpellCasterCommand.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/citizens/SpellCasterCommand.java @@ -2,7 +2,7 @@ import fr.jamailun.ultimatespellsystem.api.UltimateSpellSystem; import fr.jamailun.ultimatespellsystem.api.spells.Spell; -import fr.jamailun.ultimatespellsystem.dsl.UltimateSpellSystemDSL; +import fr.jamailun.ultimatespellsystem.dsl2.UltimateSpellSystemDSL2; import fr.jamailun.ultimatespellsystem.plugin.utils.DurationHelper; import net.citizensnpcs.api.CitizensAPI; import net.citizensnpcs.api.npc.NPC; @@ -137,7 +137,7 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command else condition = concat; // parse try { - UltimateSpellSystemDSL.parseExpression(condition); + UltimateSpellSystemDSL2.parseExpression(condition); } catch (Exception e) { sender.sendMessage("§cInvalid USS syntax: " + e.getMessage()); return true; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/AbstractFunction.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/AbstractFunction.java index 124e3646..9a80ab76 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/AbstractFunction.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/AbstractFunction.java @@ -5,8 +5,8 @@ import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; import fr.jamailun.ultimatespellsystem.api.runner.errors.InvalidTypeException; import fr.jamailun.ultimatespellsystem.api.runner.functions.RunnableJavaFunction; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.FunctionArgument; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Type; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; import fr.jamailun.ultimatespellsystem.plugin.entities.BukkitSpellEntity; import org.bukkit.Location; import org.bukkit.entity.Entity; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/AreAlliesFunction.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/AreAlliesFunction.java index d26fe46d..65f38d56 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/AreAlliesFunction.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/AreAlliesFunction.java @@ -4,9 +4,9 @@ import fr.jamailun.ultimatespellsystem.api.providers.AlliesProvider; import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.FunctionArgument; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.FunctionType; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionType; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; import org.jetbrains.annotations.NotNull; import java.util.List; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/CastSpellFunction.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/CastSpellFunction.java index ad9e54e5..cfa36338 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/CastSpellFunction.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/CastSpellFunction.java @@ -6,9 +6,9 @@ import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; import fr.jamailun.ultimatespellsystem.api.runner.errors.UnknownFunctionException; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.FunctionArgument; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.FunctionType; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionType; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; import org.jetbrains.annotations.NotNull; import java.util.List; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/DamageFunction.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/DamageFunction.java index 4356016c..f85a8df6 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/DamageFunction.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/DamageFunction.java @@ -3,9 +3,9 @@ import fr.jamailun.ultimatespellsystem.api.events.EntityDamagedBySpellEvent; import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.FunctionArgument; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.FunctionType; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionType; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; import org.bukkit.Bukkit; import org.bukkit.entity.LivingEntity; import org.jetbrains.annotations.NotNull; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/DirectionOfFunction.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/DirectionOfFunction.java index 6487638e..65a5e487 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/DirectionOfFunction.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/DirectionOfFunction.java @@ -2,9 +2,9 @@ import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.FunctionArgument; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.FunctionType; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionType; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; import org.bukkit.Location; import org.bukkit.entity.LivingEntity; import org.jetbrains.annotations.NotNull; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/DistanceFunction.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/DistanceFunction.java index 4f489e39..df82e7da 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/DistanceFunction.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/DistanceFunction.java @@ -2,9 +2,9 @@ import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.FunctionArgument; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.FunctionType; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionType; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; import org.bukkit.Location; import org.jetbrains.annotations.NotNull; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/EntityHasEffectFunction.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/EntityHasEffectFunction.java index 1942391a..fc7c7e59 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/EntityHasEffectFunction.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/EntityHasEffectFunction.java @@ -3,9 +3,9 @@ import fr.jamailun.ultimatespellsystem.UssLogger; import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.FunctionArgument; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.FunctionType; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionType; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.functions.SendEffectNode; import org.bukkit.entity.LivingEntity; import org.bukkit.potion.PotionEffectType; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/GetFoodLevelFunction.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/GetFoodLevelFunction.java index aa30203f..85faf9f0 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/GetFoodLevelFunction.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/GetFoodLevelFunction.java @@ -2,9 +2,9 @@ import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.FunctionArgument; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.FunctionType; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionType; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; import org.bukkit.entity.HumanEntity; import org.bukkit.entity.LivingEntity; import org.jetbrains.annotations.NotNull; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/GetHealthFunction.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/GetHealthFunction.java index f534a333..0fb8f8d9 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/GetHealthFunction.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/GetHealthFunction.java @@ -2,9 +2,9 @@ import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.FunctionArgument; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.FunctionType; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionType; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; import org.bukkit.entity.LivingEntity; import org.jetbrains.annotations.NotNull; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/GetMaxHealthFunction.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/GetMaxHealthFunction.java index 7a5a2e1e..69c1995d 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/GetMaxHealthFunction.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/GetMaxHealthFunction.java @@ -2,9 +2,9 @@ import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.FunctionArgument; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.FunctionType; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionType; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; import org.bukkit.attribute.Attribute; import org.bukkit.attribute.AttributeInstance; import org.bukkit.entity.LivingEntity; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/HealEntityFunction.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/HealEntityFunction.java index 8ae1c2c3..6705b811 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/HealEntityFunction.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/HealEntityFunction.java @@ -3,9 +3,9 @@ import fr.jamailun.ultimatespellsystem.api.events.EntityHealedBySpellEvent; import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.FunctionArgument; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.FunctionType; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionType; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; import org.bukkit.Bukkit; import org.bukkit.entity.LivingEntity; import org.jetbrains.annotations.NotNull; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/IsValidFunction.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/IsValidFunction.java index 6be33280..85a3a6e6 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/IsValidFunction.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/IsValidFunction.java @@ -4,9 +4,9 @@ import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; import fr.jamailun.ultimatespellsystem.api.runner.errors.InvalidTypeException; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.FunctionArgument; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.FunctionType; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionType; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; import org.bukkit.entity.Entity; import org.jetbrains.annotations.NotNull; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/KnockbackFunction.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/KnockbackFunction.java index a748de59..c9cfa719 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/KnockbackFunction.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/KnockbackFunction.java @@ -4,9 +4,9 @@ import fr.jamailun.ultimatespellsystem.api.entities.SpellEntity; import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.FunctionArgument; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.FunctionType; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionType; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; import fr.jamailun.ultimatespellsystem.plugin.utils.TypeInterpretation; import org.bukkit.util.Vector; import org.jetbrains.annotations.NotNull; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/LocationToListFunction.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/LocationToListFunction.java index 49c0d53b..e26e17be 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/LocationToListFunction.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/LocationToListFunction.java @@ -3,9 +3,9 @@ import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; import fr.jamailun.ultimatespellsystem.api.runner.errors.InvalidTypeException; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.FunctionArgument; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.FunctionType; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionType; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; import org.bukkit.Location; import org.jetbrains.annotations.NotNull; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/LogFunctions.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/LogFunctions.java index 20bac6dd..fa7b0120 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/LogFunctions.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/LogFunctions.java @@ -4,9 +4,9 @@ import fr.jamailun.ultimatespellsystem.api.providers.JavaFunctionProvider; import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.FunctionArgument; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.FunctionType; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionType; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; import org.jetbrains.annotations.NotNull; import java.util.List; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/NormalizeFunction.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/NormalizeFunction.java index 09067db5..cc98c19c 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/NormalizeFunction.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/NormalizeFunction.java @@ -2,9 +2,9 @@ import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.FunctionArgument; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.FunctionType; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionType; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; import fr.jamailun.ultimatespellsystem.plugin.utils.TypeInterpretation; import org.jetbrains.annotations.NotNull; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/RandFunction.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/RandFunction.java index 4772d569..38398e1c 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/RandFunction.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/RandFunction.java @@ -2,9 +2,9 @@ import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.FunctionArgument; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.FunctionType; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionType; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; import org.jetbrains.annotations.NotNull; import java.util.List; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/RandIntFunction.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/RandIntFunction.java index 575e478a..5d203446 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/RandIntFunction.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/RandIntFunction.java @@ -2,9 +2,9 @@ import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.FunctionArgument; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.FunctionType; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionType; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; import org.jetbrains.annotations.NotNull; import java.util.List; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/RayCastFunction.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/RayCastFunction.java index 1de48390..2346a42f 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/RayCastFunction.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/RayCastFunction.java @@ -4,9 +4,9 @@ import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; import fr.jamailun.ultimatespellsystem.api.runner.errors.InvalidTypeException; import fr.jamailun.ultimatespellsystem.api.entities.SpellEntity; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.FunctionArgument; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.FunctionType; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionType; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; import org.bukkit.FluidCollisionMode; import org.bukkit.Location; import org.bukkit.util.RayTraceResult; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/SetAggroFunction.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/SetAggroFunction.java index 96721bb7..500dec13 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/SetAggroFunction.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/SetAggroFunction.java @@ -2,9 +2,9 @@ import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.FunctionArgument; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.FunctionType; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionType; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Mob; import org.jetbrains.annotations.NotNull; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/SetFireFunction.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/SetFireFunction.java index 0b30383d..862df6c3 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/SetFireFunction.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/SetFireFunction.java @@ -2,9 +2,9 @@ import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.FunctionArgument; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.FunctionType; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionType; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; import org.bukkit.entity.LivingEntity; import org.jetbrains.annotations.NotNull; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/SetFoodLevelFunction.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/SetFoodLevelFunction.java index 26f71dc2..20b3dcdf 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/SetFoodLevelFunction.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/SetFoodLevelFunction.java @@ -2,9 +2,9 @@ import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.FunctionArgument; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.FunctionType; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionType; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; import org.bukkit.entity.HumanEntity; import org.bukkit.entity.LivingEntity; import org.jetbrains.annotations.NotNull; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/SetNameFunction.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/SetNameFunction.java index 96dd52c2..57bd38c4 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/SetNameFunction.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/SetNameFunction.java @@ -2,9 +2,9 @@ import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.FunctionArgument; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.FunctionType; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionType; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; import org.bukkit.entity.LivingEntity; import org.jetbrains.annotations.NotNull; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/SolidBlockBellowFunction.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/SolidBlockBellowFunction.java index 052c8b62..da2c361f 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/SolidBlockBellowFunction.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/SolidBlockBellowFunction.java @@ -2,9 +2,9 @@ import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.FunctionArgument; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.FunctionType; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionType; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; import org.bukkit.Location; import org.bukkit.block.Block; import org.bukkit.entity.LivingEntity; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/StrikeFunction.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/StrikeFunction.java index 74531191..4a5f008e 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/StrikeFunction.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/StrikeFunction.java @@ -2,9 +2,9 @@ import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.FunctionArgument; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.FunctionType; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionType; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; import org.bukkit.Location; import org.jetbrains.annotations.NotNull; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/providers/EntityTypes.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/providers/EntityTypes.java index 2f8b8348..653a259b 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/providers/EntityTypes.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/providers/EntityTypes.java @@ -2,7 +2,7 @@ import fr.jamailun.ultimatespellsystem.api.entities.UssEntityType; import fr.jamailun.ultimatespellsystem.api.providers.EntityTypeProvider; -import fr.jamailun.ultimatespellsystem.dsl.registries.EntityTypeRegistry; +import fr.jamailun.ultimatespellsystem.dsl2.registries.EntityTypeRegistry; import fr.jamailun.ultimatespellsystem.plugin.entities.implem.Orb; import org.bukkit.entity.EntityType; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/bind/ItemBinderImpl.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/bind/ItemBinderImpl.java index 7516baed..257dea77 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/bind/ItemBinderImpl.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/bind/ItemBinderImpl.java @@ -6,7 +6,7 @@ import fr.jamailun.ultimatespellsystem.api.events.ItemBoundEvent; import fr.jamailun.ultimatespellsystem.api.events.ItemUnBoundEvent; import fr.jamailun.ultimatespellsystem.UssKeys; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Duration; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Duration; import org.bukkit.Bukkit; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/bind/LegacySpellBindData.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/bind/LegacySpellBindData.java index 0fd7b2dc..7c26d7a9 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/bind/LegacySpellBindData.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/bind/LegacySpellBindData.java @@ -7,7 +7,7 @@ import fr.jamailun.ultimatespellsystem.api.bind.SpellCost; import fr.jamailun.ultimatespellsystem.api.bind.SpellTrigger; import fr.jamailun.ultimatespellsystem.api.spells.Spell; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Duration; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Duration; import fr.jamailun.ultimatespellsystem.plugin.bind.costs.ItemAmountSpellCost; import fr.jamailun.ultimatespellsystem.plugin.bind.costs.NoneSpellCost; import fr.jamailun.ultimatespellsystem.plugin.spells.NotFoundSpell; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/bind/SpellBindDataImpl.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/bind/SpellBindDataImpl.java index 96649157..1d043f32 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/bind/SpellBindDataImpl.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/bind/SpellBindDataImpl.java @@ -3,7 +3,7 @@ import fr.jamailun.ultimatespellsystem.api.bind.SpellBindData; import fr.jamailun.ultimatespellsystem.api.bind.SpellTrigger; import fr.jamailun.ultimatespellsystem.api.spells.Spell; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Duration; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Duration; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/bind/SpellBindDataSerializer.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/bind/SpellBindDataSerializer.java index ae32123d..45267251 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/bind/SpellBindDataSerializer.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/bind/SpellBindDataSerializer.java @@ -4,7 +4,7 @@ import fr.jamailun.ultimatespellsystem.api.bind.ItemBindTrigger; import fr.jamailun.ultimatespellsystem.api.bind.SpellBindData; import fr.jamailun.ultimatespellsystem.api.spells.Spell; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Duration; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Duration; import fr.jamailun.ultimatespellsystem.plugin.bind.costs.SpellCostFactory; import fr.jamailun.ultimatespellsystem.plugin.spells.NotFoundSpell; import org.jetbrains.annotations.NotNull; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/commands/UssCommand.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/commands/UssCommand.java index 5f7d9ccc..6779bdbb 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/commands/UssCommand.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/commands/UssCommand.java @@ -9,9 +9,9 @@ import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.spells.Spell; import fr.jamailun.ultimatespellsystem.api.utils.MultivaluedMap; -import fr.jamailun.ultimatespellsystem.dsl.UltimateSpellSystemDSL; -import fr.jamailun.ultimatespellsystem.dsl.nodes.ExpressionNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Duration; +import fr.jamailun.ultimatespellsystem.dsl2.UltimateSpellSystemDSL2; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.ExpressionNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Duration; import fr.jamailun.ultimatespellsystem.plugin.bind.SpellBindDataImpl; import fr.jamailun.ultimatespellsystem.plugin.bind.SpellTriggerImpl; import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.functions.SendAttributeNode; @@ -95,7 +95,7 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command // Parse try { - ExpressionNode raw = UltimateSpellSystemDSL.parseExpression(code); + ExpressionNode raw = UltimateSpellSystemDSL2.parseExpression(code); RuntimeExpression expression = UltimateSpellSystem.getExternalExecutor().handleImplementation(raw); Object out = expression.evaluate(UltimateSpellSystem.getExternalExecutor().generateRuntime(player)); diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/configuration/MainConfiguration.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/configuration/MainConfiguration.java index 2e9e7c6f..9d52ae93 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/configuration/MainConfiguration.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/configuration/MainConfiguration.java @@ -2,7 +2,7 @@ import fr.jamailun.ultimatespellsystem.api.bind.ItemBindTrigger; import fr.jamailun.ultimatespellsystem.api.bind.SpellCost; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Duration; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Duration; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.UnmodifiableView; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/configuration/MainConfigurationVersion1.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/configuration/MainConfigurationVersion1.java index 3b420000..2c3969f9 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/configuration/MainConfigurationVersion1.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/configuration/MainConfigurationVersion1.java @@ -7,7 +7,7 @@ import fr.jamailun.ultimatespellsystem.api.bind.ItemBindTrigger; import fr.jamailun.ultimatespellsystem.api.bind.SpellCost; import fr.jamailun.ultimatespellsystem.api.bind.SpellCostEntry; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Duration; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Duration; import fr.jamailun.ultimatespellsystem.plugin.bind.costs.NoneSpellCost; import fr.jamailun.ultimatespellsystem.plugin.utils.DurationHelper; import lombok.Getter; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/configuration/UssConfig.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/configuration/UssConfig.java index a8068cb3..f212e3bc 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/configuration/UssConfig.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/configuration/UssConfig.java @@ -5,7 +5,7 @@ import fr.jamailun.ultimatespellsystem.UssLogger; import fr.jamailun.ultimatespellsystem.api.bind.ItemBindTrigger; import fr.jamailun.ultimatespellsystem.api.bind.SpellCost; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Duration; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Duration; import fr.jamailun.ultimatespellsystem.plugin.utils.observable.AbstractObservable; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.plugin.Plugin; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/entities/SummonAttributesImpl.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/entities/SummonAttributesImpl.java index 9ea02a00..73f16803 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/entities/SummonAttributesImpl.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/entities/SummonAttributesImpl.java @@ -8,7 +8,7 @@ import fr.jamailun.ultimatespellsystem.api.events.SummonedEntityExpiredEvent; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; import fr.jamailun.ultimatespellsystem.api.providers.SummonPropertiesProvider; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Duration; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Duration; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.entity.*; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/listeners/BoundSpellCastListener.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/listeners/BoundSpellCastListener.java index 9ea9b8dd..35411e5e 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/listeners/BoundSpellCastListener.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/listeners/BoundSpellCastListener.java @@ -2,7 +2,7 @@ import fr.jamailun.ultimatespellsystem.api.events.BoundSpellCastEvent; import fr.jamailun.ultimatespellsystem.api.utils.StringTransformation; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Duration; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Duration; import fr.jamailun.ultimatespellsystem.plugin.configuration.UssConfig; import fr.jamailun.ultimatespellsystem.plugin.spells.SpellsCooldowns; import org.bukkit.GameMode; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/builder/ExpressionQueue.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/builder/ExpressionQueue.java index 915babba..819fbf91 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/builder/ExpressionQueue.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/builder/ExpressionQueue.java @@ -6,16 +6,16 @@ import fr.jamailun.ultimatespellsystem.plugin.runner.functions.JavaFunctionCallNode; import fr.jamailun.ultimatespellsystem.api.runner.functions.RunnableJavaFunction; import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.operators.*; -import fr.jamailun.ultimatespellsystem.dsl.nodes.ExpressionNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.*; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.compute.AllEntitiesAroundExpression; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.FunctionCallExpression; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.compute.PositionOfExpression; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.compute.SizeOfExpression; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.litteral.*; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.operators.BiOperator; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.operators.MonoOperator; -import fr.jamailun.ultimatespellsystem.dsl.visitor.ExpressionVisitor; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.ExpressionNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.*; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.compute.AllEntitiesAroundExpression; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionCallExpression; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.compute.PositionOfExpression; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.compute.SizeOfExpression; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.litteral.*; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.operators.BiOperator; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.operators.MonoOperator; +import fr.jamailun.ultimatespellsystem.dsl2.visitor.ExpressionVisitor; import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.expressions.*; import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.operators.list.ArrayGetNode; import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.operators.list.ListAddRemOpe; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/builder/SpellBuilderVisitor.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/builder/SpellBuilderVisitor.java index 91982fbb..fa6a2ca9 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/builder/SpellBuilderVisitor.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/builder/SpellBuilderVisitor.java @@ -1,16 +1,16 @@ package fr.jamailun.ultimatespellsystem.plugin.runner.builder; -import fr.jamailun.ultimatespellsystem.dsl.objects.CallbackEvent; +import fr.jamailun.ultimatespellsystem.dsl2.objects.CallbackEvent; import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.MetadataNode; import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.blocks.*; import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.expressions.ExpressionWrapperNode; import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.functions.play.*; import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.operators.IncrementNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.ExpressionNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.StatementNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.statements.*; -import fr.jamailun.ultimatespellsystem.dsl.nodes.statements.blocks.*; -import fr.jamailun.ultimatespellsystem.dsl.visitor.StatementVisitor; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.ExpressionNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.StatementNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.statements.*; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.statements.blocks.*; +import fr.jamailun.ultimatespellsystem.dsl2.visitor.StatementVisitor; import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.RuntimeStatement; import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.functions.*; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/functions/JavaFunctionCallNode.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/functions/JavaFunctionCallNode.java index 670cabaa..00e35beb 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/functions/JavaFunctionCallNode.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/functions/JavaFunctionCallNode.java @@ -4,7 +4,7 @@ import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; import fr.jamailun.ultimatespellsystem.api.runner.functions.RunnableJavaFunction; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; import fr.jamailun.ultimatespellsystem.plugin.entities.BukkitSpellEntity; import lombok.RequiredArgsConstructor; import org.bukkit.entity.Entity; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/blocks/CallbackNode.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/blocks/CallbackNode.java index e1493085..9e235358 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/blocks/CallbackNode.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/blocks/CallbackNode.java @@ -8,7 +8,7 @@ import fr.jamailun.ultimatespellsystem.api.runner.RuntimeStatement; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; import fr.jamailun.ultimatespellsystem.api.runner.errors.InvalidTypeException; -import fr.jamailun.ultimatespellsystem.dsl.objects.CallbackEvent; +import fr.jamailun.ultimatespellsystem.dsl2.objects.CallbackEvent; import lombok.Getter; import org.jetbrains.annotations.NotNull; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/blocks/RunLaterNode.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/blocks/RunLaterNode.java index 5bb34b71..fd101b59 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/blocks/RunLaterNode.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/blocks/RunLaterNode.java @@ -2,7 +2,7 @@ import fr.jamailun.ultimatespellsystem.UssLogger; import fr.jamailun.ultimatespellsystem.api.UltimateSpellSystem; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Duration; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Duration; import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.RuntimeStatement; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/blocks/RunRepeatNode.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/blocks/RunRepeatNode.java index 57a4d707..c34faff7 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/blocks/RunRepeatNode.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/blocks/RunRepeatNode.java @@ -3,8 +3,8 @@ import fr.jamailun.ultimatespellsystem.UssLogger; import fr.jamailun.ultimatespellsystem.api.UltimateSpellSystem; import fr.jamailun.ultimatespellsystem.api.runner.FlowState; -import fr.jamailun.ultimatespellsystem.dsl.nodes.statements.blocks.RepeatStatement; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Duration; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.statements.blocks.RepeatStatement; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Duration; import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.RuntimeStatement; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/expressions/EntityTypeLiteral.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/expressions/EntityTypeLiteral.java index 9422de4e..b1d64ff3 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/expressions/EntityTypeLiteral.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/expressions/EntityTypeLiteral.java @@ -4,7 +4,7 @@ import fr.jamailun.ultimatespellsystem.api.providers.EntityTypeProvider; import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.litteral.EntityTypeExpression; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.litteral.EntityTypeExpression; import org.jetbrains.annotations.NotNull; /** diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/expressions/RawLiteral.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/expressions/RawLiteral.java index bb2aaa80..b5f39a7b 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/expressions/RawLiteral.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/expressions/RawLiteral.java @@ -1,6 +1,6 @@ package fr.jamailun.ultimatespellsystem.plugin.runner.nodes.expressions; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.litteral.LiteralExpression; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.litteral.LiteralExpression; import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; import org.jetbrains.annotations.NotNull; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/DefineNode.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/DefineNode.java index 4dc0ec05..35beba76 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/DefineNode.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/DefineNode.java @@ -1,10 +1,10 @@ package fr.jamailun.ultimatespellsystem.plugin.runner.nodes.functions; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Type; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.RuntimeStatement; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; import lombok.RequiredArgsConstructor; import org.jetbrains.annotations.NotNull; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/SendAttributeNode.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/SendAttributeNode.java index d1400598..b85ee434 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/SendAttributeNode.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/SendAttributeNode.java @@ -6,7 +6,7 @@ import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.RuntimeStatement; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Duration; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Duration; import lombok.RequiredArgsConstructor; import org.bukkit.Bukkit; import org.bukkit.attribute.Attributable; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/SendEffectNode.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/SendEffectNode.java index 9036b773..28eb921b 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/SendEffectNode.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/SendEffectNode.java @@ -3,7 +3,7 @@ import fr.jamailun.ultimatespellsystem.UssLogger; import fr.jamailun.ultimatespellsystem.api.entities.SpellEntity; import fr.jamailun.ultimatespellsystem.api.runner.errors.InvalidEnumValueException; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Duration; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Duration; import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.RuntimeStatement; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/SendNbtNode.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/SendNbtNode.java index 485ef0c0..22605333 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/SendNbtNode.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/SendNbtNode.java @@ -7,7 +7,7 @@ import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.RuntimeStatement; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Duration; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Duration; import org.bukkit.NamespacedKey; import org.bukkit.persistence.PersistentDataContainer; import org.bukkit.persistence.PersistentDataType; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/SummonNode.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/SummonNode.java index bedab870..b43b47c4 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/SummonNode.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/SummonNode.java @@ -9,7 +9,7 @@ import fr.jamailun.ultimatespellsystem.api.entities.SpellEntity; import fr.jamailun.ultimatespellsystem.plugin.entities.SummonAttributesImpl; import fr.jamailun.ultimatespellsystem.api.runner.errors.InvalidTypeException; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Duration; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Duration; import lombok.Getter; import lombok.RequiredArgsConstructor; import org.bukkit.Location; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/RunAddOpe.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/RunAddOpe.java index f5c98e3b..82f04e8c 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/RunAddOpe.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/RunAddOpe.java @@ -2,7 +2,7 @@ import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.errors.UnreachableRuntimeException; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Duration; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Duration; import org.bukkit.Location; import org.bukkit.util.Vector; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/RunCompOpe.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/RunCompOpe.java index a89b78ed..65303e6f 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/RunCompOpe.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/RunCompOpe.java @@ -2,7 +2,7 @@ import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.errors.UnreachableRuntimeException; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Duration; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Duration; public final class RunCompOpe extends RuntimeBiOperator { diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/RunMathOpe.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/RunMathOpe.java index 662f1b4c..30814e17 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/RunMathOpe.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/RunMathOpe.java @@ -2,7 +2,7 @@ import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.errors.UnreachableRuntimeException; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.operators.MonoOperator.MonoOpeType; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.operators.MonoOperator.MonoOpeType; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/RunMulDivOpe.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/RunMulDivOpe.java index 5407c83f..8416778b 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/RunMulDivOpe.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/RunMulDivOpe.java @@ -2,7 +2,7 @@ import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.errors.UnreachableRuntimeException; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Duration; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Duration; import org.bukkit.Location; import org.bukkit.util.Vector; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/RunSubOpe.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/RunSubOpe.java index c9eb083c..6232f057 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/RunSubOpe.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/RunSubOpe.java @@ -2,7 +2,7 @@ import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.errors.UnreachableRuntimeException; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Duration; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Duration; import org.bukkit.Location; import org.bukkit.util.Vector; import org.jetbrains.annotations.Contract; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/spells/SpellDefinition.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/spells/SpellDefinition.java index 1226aacc..47a70b24 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/spells/SpellDefinition.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/spells/SpellDefinition.java @@ -6,10 +6,10 @@ import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; import fr.jamailun.ultimatespellsystem.api.spells.SpellMetadata; import fr.jamailun.ultimatespellsystem.api.utils.MultivaluedMap; -import fr.jamailun.ultimatespellsystem.dsl.visitor.PrintingVisitor; -import fr.jamailun.ultimatespellsystem.dsl.UltimateSpellSystemDSL; -import fr.jamailun.ultimatespellsystem.dsl.nodes.StatementNode; -import fr.jamailun.ultimatespellsystem.dsl.validators.DslValidator; +import fr.jamailun.ultimatespellsystem.dsl2.visitor.PrintingVisitor; +import fr.jamailun.ultimatespellsystem.dsl2.UltimateSpellSystemDSL2; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.StatementNode; +import fr.jamailun.ultimatespellsystem.dsl2.validators.DslValidator; import fr.jamailun.ultimatespellsystem.plugin.configuration.UssConfig; import fr.jamailun.ultimatespellsystem.plugin.runner.builder.SpellBuilderVisitor; import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.MetadataNode; @@ -77,7 +77,7 @@ private void checkSpellWarnings() { */ public static @Nullable SpellDefinition loadFile(@NotNull String name, @NotNull File file) { try { - List dsl = UltimateSpellSystemDSL.parse(file); + List dsl = UltimateSpellSystemDSL2.parse(file); List steps = load(dsl); SpellDefinition spell = new SpellDefinition(file, name, steps); if(UssConfig.displaySummonWarnings()) @@ -101,7 +101,7 @@ private void checkSpellWarnings() { if(!file.exists()) return "file["+file+"] doesn't exist."; try { - List dsl = UltimateSpellSystemDSL.parse(file); + List dsl = UltimateSpellSystemDSL2.parse(file); DslValidator.validateDsl(dsl); return PrintingVisitor.toString(dsl); } catch(Exception e) { diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/spells/SpellsCooldowns.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/spells/SpellsCooldowns.java index 59fdad03..22add7e2 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/spells/SpellsCooldowns.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/spells/SpellsCooldowns.java @@ -1,6 +1,6 @@ package fr.jamailun.ultimatespellsystem.plugin.spells; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Duration; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Duration; import org.jetbrains.annotations.NotNull; import java.time.Instant; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/spells/external/ExternalExecutorImpl.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/spells/external/ExternalExecutorImpl.java index 5c2dadcb..2685ce12 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/spells/external/ExternalExecutorImpl.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/spells/external/ExternalExecutorImpl.java @@ -5,8 +5,8 @@ import fr.jamailun.ultimatespellsystem.api.runner.RuntimeStatement; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; import fr.jamailun.ultimatespellsystem.api.spells.ExternalExecutor; -import fr.jamailun.ultimatespellsystem.dsl.nodes.ExpressionNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.StatementNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.ExpressionNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.StatementNode; import fr.jamailun.ultimatespellsystem.plugin.runner.SpellRuntimeImpl; import fr.jamailun.ultimatespellsystem.plugin.runner.builder.SpellBuilderVisitor; import fr.jamailun.ultimatespellsystem.plugin.spells.SpellDefinition; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/spells/functions/SpellFunction.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/spells/functions/SpellFunction.java index 07076816..c87b5832 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/spells/functions/SpellFunction.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/spells/functions/SpellFunction.java @@ -7,12 +7,12 @@ import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; import fr.jamailun.ultimatespellsystem.api.runner.functions.RunnableJavaFunction; import fr.jamailun.ultimatespellsystem.api.utils.MultivaluedMap; -import fr.jamailun.ultimatespellsystem.dsl.UltimateSpellSystemDSL; -import fr.jamailun.ultimatespellsystem.dsl.nodes.StatementNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.FunctionArgument; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.FunctionType; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Type; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; +import fr.jamailun.ultimatespellsystem.dsl2.UltimateSpellSystemDSL2; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.StatementNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionType; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.MetadataNode; import fr.jamailun.ultimatespellsystem.plugin.spells.SpellDefinition; import lombok.Getter; @@ -83,7 +83,7 @@ public Object executeSteps(@NotNull SpellRuntime runtime) { List steps = new ArrayList<>(); try { - List dsl = UltimateSpellSystemDSL.parse(file); + List dsl = UltimateSpellSystemDSL2.parse(file); List rawStatements = SpellDefinition.load(dsl); // Metadata are already sorted (thanks to AST validation) diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/utils/DurationHelper.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/utils/DurationHelper.java index f096d514..f0692b3f 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/utils/DurationHelper.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/utils/DurationHelper.java @@ -1,7 +1,7 @@ package fr.jamailun.ultimatespellsystem.plugin.utils; import fr.jamailun.ultimatespellsystem.UssLogger; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Duration; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Duration; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/utils/holders/BlockHolder.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/utils/holders/BlockHolder.java index 3a9374c5..406d2305 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/utils/holders/BlockHolder.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/utils/holders/BlockHolder.java @@ -2,7 +2,7 @@ import fr.jamailun.ultimatespellsystem.UssLogger; import fr.jamailun.ultimatespellsystem.api.UltimateSpellSystem; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Duration; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Duration; import fr.jamailun.ultimatespellsystem.plugin.utils.Pair; import org.bukkit.Location; import org.bukkit.Material; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/utils/holders/PotionEffectHolder.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/utils/holders/PotionEffectHolder.java index 673f4dc7..fb86fea1 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/utils/holders/PotionEffectHolder.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/utils/holders/PotionEffectHolder.java @@ -4,7 +4,7 @@ import fr.jamailun.ultimatespellsystem.api.runner.errors.InvalidEnumValueException; import fr.jamailun.ultimatespellsystem.api.runner.errors.InvalidTypeException; import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.functions.SendEffectNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Duration; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Duration; import org.bukkit.entity.LivingEntity; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; diff --git a/plugin/src/test/java/fr/jamailun/ultimatespellsystem/extension/ExtensionParsingTests.java b/plugin/src/test/java/fr/jamailun/ultimatespellsystem/extension/ExtensionParsingTests.java index 688f69c1..f38d9d11 100644 --- a/plugin/src/test/java/fr/jamailun/ultimatespellsystem/extension/ExtensionParsingTests.java +++ b/plugin/src/test/java/fr/jamailun/ultimatespellsystem/extension/ExtensionParsingTests.java @@ -1,7 +1,7 @@ package fr.jamailun.ultimatespellsystem.extension; import fr.jamailun.ultimatespellsystem.api.runner.RuntimeStatement; -import fr.jamailun.ultimatespellsystem.dsl.errors.UssException; +import fr.jamailun.ultimatespellsystem.dsl2.errors.UssException; import fr.jamailun.ultimatespellsystem.runner.framework.AssertException; import org.jetbrains.annotations.NotNull; import org.junit.jupiter.api.BeforeAll; diff --git a/plugin/src/test/java/fr/jamailun/ultimatespellsystem/extension/ParseAndCompileTest.java b/plugin/src/test/java/fr/jamailun/ultimatespellsystem/extension/ParseAndCompileTest.java index 9e983617..83ccce0f 100644 --- a/plugin/src/test/java/fr/jamailun/ultimatespellsystem/extension/ParseAndCompileTest.java +++ b/plugin/src/test/java/fr/jamailun/ultimatespellsystem/extension/ParseAndCompileTest.java @@ -1,13 +1,13 @@ package fr.jamailun.ultimatespellsystem.extension; import fr.jamailun.ultimatespellsystem.api.runner.RuntimeStatement; -import fr.jamailun.ultimatespellsystem.dsl.UltimateSpellSystemDSL; -import fr.jamailun.ultimatespellsystem.dsl.errors.UssException; -import fr.jamailun.ultimatespellsystem.dsl.nodes.StatementNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.variables.TypesContext; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.CharStream; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenStream; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.Tokenizer; +import fr.jamailun.ultimatespellsystem.dsl2.UltimateSpellSystemDSL2; +import fr.jamailun.ultimatespellsystem.dsl2.errors.UssException; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.StatementNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.variables.TypesContext; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.CharStream; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenStream; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.Tokenizer; import fr.jamailun.ultimatespellsystem.plugin.runner.builder.SpellBuilderVisitor; import fr.jamailun.ultimatespellsystem.runner.framework.TestFramework; import org.jetbrains.annotations.NotNull; @@ -59,7 +59,7 @@ protected List parseAndVerify(@NotNull File file) throws UssEx System.out.println(tokens + "\n"); // Parse - List nodes = UltimateSpellSystemDSL.parse(tokens); + List nodes = UltimateSpellSystemDSL2.parse(tokens); System.out.println(" ----------------------- "); diff --git a/plugin/src/test/java/fr/jamailun/ultimatespellsystem/runner/framework/functions/AssertNotCalledFunction.java b/plugin/src/test/java/fr/jamailun/ultimatespellsystem/runner/framework/functions/AssertNotCalledFunction.java index d20c8eb8..e2bbe024 100644 --- a/plugin/src/test/java/fr/jamailun/ultimatespellsystem/runner/framework/functions/AssertNotCalledFunction.java +++ b/plugin/src/test/java/fr/jamailun/ultimatespellsystem/runner/framework/functions/AssertNotCalledFunction.java @@ -3,9 +3,9 @@ import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; import fr.jamailun.ultimatespellsystem.api.runner.functions.RunnableJavaFunction; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.FunctionArgument; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.FunctionType; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionType; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; import fr.jamailun.ultimatespellsystem.runner.framework.AssertException; import org.jetbrains.annotations.NotNull; diff --git a/plugin/src/test/java/fr/jamailun/ultimatespellsystem/runner/framework/functions/AssertTrueFunction.java b/plugin/src/test/java/fr/jamailun/ultimatespellsystem/runner/framework/functions/AssertTrueFunction.java index 6128ece2..31828358 100644 --- a/plugin/src/test/java/fr/jamailun/ultimatespellsystem/runner/framework/functions/AssertTrueFunction.java +++ b/plugin/src/test/java/fr/jamailun/ultimatespellsystem/runner/framework/functions/AssertTrueFunction.java @@ -3,9 +3,9 @@ import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; import fr.jamailun.ultimatespellsystem.api.runner.functions.RunnableJavaFunction; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.FunctionArgument; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.FunctionType; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionType; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; import fr.jamailun.ultimatespellsystem.runner.framework.AssertException; import org.jetbrains.annotations.NotNull; diff --git a/plugin/src/test/java/fr/jamailun/ultimatespellsystem/runner/framework/functions/PrintFunction.java b/plugin/src/test/java/fr/jamailun/ultimatespellsystem/runner/framework/functions/PrintFunction.java index 1f6ea2a9..240209cd 100644 --- a/plugin/src/test/java/fr/jamailun/ultimatespellsystem/runner/framework/functions/PrintFunction.java +++ b/plugin/src/test/java/fr/jamailun/ultimatespellsystem/runner/framework/functions/PrintFunction.java @@ -3,9 +3,9 @@ import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; import fr.jamailun.ultimatespellsystem.api.runner.functions.RunnableJavaFunction; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.FunctionArgument; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.FunctionType; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionType; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; import org.jetbrains.annotations.NotNull; import java.util.List; diff --git a/pom.xml b/pom.xml index 7c2669af..97084fc5 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ fr.jamailun.paper ultimate-spell-system - 2.6.1-SNAPSHOT + 3.0.0-SNAPSHOT pom Ultimate Spell System From e53f73c5fd0d62f92cc788e3458f6f454159d078 Mon Sep 17 00:00:00 2001 From: "timothe.rosaz" Date: Fri, 31 Oct 2025 21:23:38 +0100 Subject: [PATCH 24/38] Basic functions loaded for entity --- .../api/entities/SpellEntity.java | 12 ++ .../dsl2/errors/UnknownFieldException.java | 20 +++ .../dsl2/errors/UnknownFunctionException.java | 10 ++ .../dsl2/library/StructDefinition.java | 3 +- .../dsl2/library/structs/EntityStruct.java | 10 -- .../functions/FunctionArgument.java | 15 +- .../dsl2/nodes/type/Type.java | 2 +- .../registries/ObjectsDefinitionRegistry.java | 10 ++ .../structs/AbstractStructDefinition.java | 160 ++++++++++++++++++ .../structs/AbstractStructInstance.java | 34 ++++ .../runner/structs/EntityDefinition.java | 114 +++++++++++++ .../plugin/runner/structs/EntityInstance.java | 19 +++ .../plugin/runner/structs/Struct.java | 25 +++ .../runner/structs/StructDefinition.java | 37 ++++ 14 files changed, 455 insertions(+), 16 deletions(-) create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/errors/UnknownFieldException.java create mode 100644 plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/AbstractStructDefinition.java create mode 100644 plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/AbstractStructInstance.java create mode 100644 plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/EntityDefinition.java create mode 100644 plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/EntityInstance.java create mode 100644 plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/Struct.java create mode 100644 plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/StructDefinition.java diff --git a/api/src/main/java/fr/jamailun/ultimatespellsystem/api/entities/SpellEntity.java b/api/src/main/java/fr/jamailun/ultimatespellsystem/api/entities/SpellEntity.java index 1932af97..708369f2 100644 --- a/api/src/main/java/fr/jamailun/ultimatespellsystem/api/entities/SpellEntity.java +++ b/api/src/main/java/fr/jamailun/ultimatespellsystem/api/entities/SpellEntity.java @@ -22,6 +22,7 @@ public interface SpellEntity { * Get the UUID of the entity. * @return a non-null, unique UUID. */ + @Contract(pure = true) @NotNull UUID getUniqueId(); /** @@ -31,10 +32,21 @@ public interface SpellEntity { @Contract(pure = true) @NotNull Optional getBukkitEntity(); + /** + * Get the entity as a specific bukkit class. + * @param clazz the class to cast the bukkit entity to. + * @return an empty optional if the entity is not bukkit-based, or if the instance cannot be + * cast to the parameter. + * @param the output requested type. + */ + @Contract(pure = true) + Optional getEntityAs(Class clazz); + /** * Test if the current entity has a bukkit representation. * @return true if a call to {@link #getBukkitEntity()} returns something. */ + @Contract(pure = true) default boolean isBukkit() { return getBukkitEntity().isPresent(); } diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/errors/UnknownFieldException.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/errors/UnknownFieldException.java new file mode 100644 index 00000000..5f8509ce --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/errors/UnknownFieldException.java @@ -0,0 +1,20 @@ +package fr.jamailun.ultimatespellsystem.dsl2.errors; + +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenPosition; + +/** + * Exception thrown when a requested field does not exist. + */ +public class UnknownFieldException extends UssException { + + /** + * New instance. + * @param pos position of the token. + * @param type type of the struct. + * @param fieldName requested field name. + */ + public UnknownFieldException(TokenPosition pos, String type, String fieldName) { + super(pos, "The type " + type + " has not field '" + fieldName + "'."); + } + +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/errors/UnknownFunctionException.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/errors/UnknownFunctionException.java index daf16f10..61a6846a 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/errors/UnknownFunctionException.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/errors/UnknownFunctionException.java @@ -16,4 +16,14 @@ public class UnknownFunctionException extends UssException { public UnknownFunctionException(@NotNull TokenPosition pos, @NotNull String functionId) { super(pos, "Unknown function ID: '"+functionId+"'."); } + + /** + * New exception for a struct. + * @param pos token position. + * @param structName name of the structure. + * @param functionId ID of the unknown function. + */ + public UnknownFunctionException(@NotNull TokenPosition pos, @NotNull String structName, @NotNull String functionId) { + super(pos, "Unknown function ID: '"+functionId+"' in struct " + structName + "."); + } } diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/library/StructDefinition.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/library/StructDefinition.java index fc65ef9c..043c4f69 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/library/StructDefinition.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/library/StructDefinition.java @@ -14,7 +14,8 @@ @RequiredArgsConstructor public class StructDefinition { - protected static final String LAZY_TYPE_LOCATION = "location"; + public static final String LAZY_TYPE_LOCATION = "location"; + public static final String LAZY_TYPE_ENTITY = "entity"; @Getter private final String name; private final Map fields = new HashMap<>(); diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/library/structs/EntityStruct.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/library/structs/EntityStruct.java index 94c839fc..8d7ce999 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/library/structs/EntityStruct.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/library/structs/EntityStruct.java @@ -19,9 +19,7 @@ private void initFields() { registerField("name", TypePrimitive.STRING); registerField("location", LAZY_TYPE_LOCATION); - registerField("position", LAZY_TYPE_LOCATION); registerField("eye_location", LAZY_TYPE_LOCATION); - registerField("eye_position", LAZY_TYPE_LOCATION); // Location registerField("x", TypePrimitive.NUMBER); @@ -33,8 +31,6 @@ private void initFields() { // Attributes registerField("health", TypePrimitive.NUMBER); registerField("max_health", TypePrimitive.NUMBER); - registerField("attack", TypePrimitive.NUMBER); - registerField("armor", TypePrimitive.NUMBER); } private void initFunctions() { @@ -50,12 +46,6 @@ private void initFunctions() { FunctionArgument.of(TypePrimitive.NUMBER) )); - registerFunction(FunctionDefinition.of( - "send", - TypePrimitive.NULL.asType(), - FunctionArgument.of(TypePrimitive.STRING) - )); - registerFunction(FunctionDefinition.of( "send_message", TypePrimitive.NULL.asType(), diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/functions/FunctionArgument.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/functions/FunctionArgument.java index c9fe042e..32068fd7 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/functions/FunctionArgument.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/functions/FunctionArgument.java @@ -18,11 +18,18 @@ public record FunctionArgument(@NotNull Type type, @NotNull String debugName, bo return type + " " + debugName + (optional?"*":""); } - public static FunctionArgument of(@NotNull String type) { - return new FunctionArgument(Type.of(type), type, false); + @Contract("_ -> new") + public static @NotNull FunctionArgument of(@NotNull String type) { + return of(Type.of(type)); } - public static FunctionArgument of(@NotNull TypePrimitive type) { - return new FunctionArgument(Type.of(type), type.name().toLowerCase(), false); + @Contract("_ -> new") + public static @NotNull FunctionArgument of(@NotNull TypePrimitive type) { + return of(Type.of(type)); + } + + @Contract("_ -> new") + public static @NotNull FunctionArgument of(@NotNull Type type) { + return new FunctionArgument(type, type.getName(), false); } } diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/Type.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/Type.java index edb9400c..4f05990c 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/Type.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/Type.java @@ -80,7 +80,7 @@ public boolean isPrimitive() { } public @NotNull String getName() { - return primitive == null ? Objects.requireNonNull(objectClass) : primitive.name(); + return primitive == null ? Objects.requireNonNull(objectClass) : primitive.name().toLowerCase(); } @Contract(pure = true) diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/registries/ObjectsDefinitionRegistry.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/registries/ObjectsDefinitionRegistry.java index f4429760..a5648af6 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/registries/ObjectsDefinitionRegistry.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/registries/ObjectsDefinitionRegistry.java @@ -2,6 +2,7 @@ import fr.jamailun.ultimatespellsystem.dsl2.library.StructDefinition; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.UnmodifiableView; import java.util.Collection; @@ -41,4 +42,13 @@ public static void registerDefaultStruct(@NotNull StructDefinition definition) { return Collections.unmodifiableCollection(DEFAULT_STRUCTS.values()); } + /** + * Get a default struct. + * @param name the name of the struct. + * @return null if ot found. + */ + public static @Nullable StructDefinition getDefaultStruct(@NotNull String name) { + return DEFAULT_STRUCTS.get(name); + } + } diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/AbstractStructDefinition.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/AbstractStructDefinition.java new file mode 100644 index 00000000..9cab6cfc --- /dev/null +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/AbstractStructDefinition.java @@ -0,0 +1,160 @@ +package fr.jamailun.ultimatespellsystem.plugin.runner.structs; + +import com.google.common.base.Preconditions; +import fr.jamailun.ultimatespellsystem.dsl2.errors.UnknownFieldException; +import fr.jamailun.ultimatespellsystem.dsl2.errors.UnknownFunctionException; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionDefinition; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenPosition; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import org.bukkit.Location; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.BiConsumer; +import java.util.function.BiFunction; +import java.util.function.Function; + +/** + * Internal abstract struct definition. + */ +@RequiredArgsConstructor(access = AccessLevel.PROTECTED) +public abstract class AbstractStructDefinition implements StructDefinition { + + protected static final Type TYPE_LOCATION = Type.of(fr.jamailun.ultimatespellsystem.dsl2.library.StructDefinition.LAZY_TYPE_LOCATION); + protected static final Type TYPE_ENTITY = Type.of(fr.jamailun.ultimatespellsystem.dsl2.library.StructDefinition.LAZY_TYPE_ENTITY); + + private final Map> fields = new HashMap<>(); + private final Map> functions = new HashMap<>(); + + @Getter protected final String structName; + + @Override + public void registerField(@NotNull String name, @NotNull Type type, @NotNull Function getter, @Nullable BiConsumer setter) { + Preconditions.checkState(!fields.containsKey(name), "The field '" + name + " has already be defined in struct " + structName + "."); + fields.put(name, new FieldMetadata<>(name, type, getter, setter)); + dsl().registerField(name, type); + } + + @Override + public void registerFunction(@NotNull FunctionDefinition def, @NotNull BiFunction, T> impl) { + String name = def.id(); + Preconditions.checkState(!functions.containsKey(name), "The function '" + name + " has already be defined in struct " + structName + "."); + functions.put(name, new FunctionMetadata<>(def, impl)); + dsl().registerFunction(def); + } + + protected void registerNumber(@NotNull String name, @NotNull Function getter) { + registerField(name, Type.of(TypePrimitive.NUMBER), s -> getter.apply(s).doubleValue(), null); + } + + protected void registerLocation(@NotNull String name, @NotNull Function getter) { + registerField(name, TYPE_LOCATION, getter, null); + } + + protected void registerString(@NotNull String name, @NotNull Function getter) { + registerField(name, Type.of(TypePrimitive.STRING), getter, null); + } + + protected void registerNumber(@NotNull String name, @NotNull Function getter, @NotNull BiConsumer setter) { + registerField(name, Type.of(TypePrimitive.NUMBER), s -> getter.apply(s).doubleValue(), setter::accept); + } + + protected void registerNullFunc(@NotNull String name, @NotNull BiConsumer> impl, FunctionArgument... args) { + registerFunction( + FunctionDefinition.of(name, TypePrimitive.NULL.asType(), args), + (s, params) -> { + impl.accept(s, params); + return null; + } + ); + } + + /** + * Get the DSL definition. + * @return the DSL definition of the object. + */ + protected abstract @NotNull fr.jamailun.ultimatespellsystem.dsl2.library.StructDefinition dsl(); + + /** + * Get a value. + * @param object object to get the value from. + * @param pos token pos + * @param fieldName name of the field. + * @param parameter type. + * @return null if value not found. + */ + protected @Nullable T get(@NotNull S object, @NotNull TokenPosition pos, @NotNull String fieldName) { + FieldMetadata field = field(pos, fieldName); + return field.getter.apply(object); + } + + /** + * Set a value. + * @param object object to set the value of. + * @param pos token pos + * @param fieldName field name. + * @param value value to set. + * @param parameter type. + */ + protected void set(@NotNull S object, @NotNull TokenPosition pos, @NotNull String fieldName, @Nullable T value) { + FieldMetadata field = field(pos, fieldName); + Preconditions.checkState(field.setter != null, "The field '" + field + "' of " + structName + " is NOT mutable."); + field.setter.accept(object, value); + } + + /** + * Call a function. + * @param object object to call the function on. + * @param pos token pos. + * @param funcName function name. + * @param params list of parameters passed to the function. + * @return the output value. May be null. + * @param function-output parameter type. + */ + protected @Nullable T call(@NotNull S object, @NotNull TokenPosition pos, @NotNull String funcName, @NotNull List params) { + FunctionMetadata function = function(pos, funcName); + return function.implementation.apply(object, params); + } + + @SuppressWarnings("unchecked") + private @NotNull FieldMetadata field(@NotNull TokenPosition pos, @NotNull String fieldName) { + FieldMetadata field = (FieldMetadata) fields.get(fieldName); + if(field == null) + throw new UnknownFieldException(pos, structName, fieldName); + return field; + } + + @SuppressWarnings("unchecked") + private @NotNull FunctionMetadata function(@NotNull TokenPosition pos, @NotNull String funcName) { + FunctionMetadata func = (FunctionMetadata) functions.get(funcName); + if(func == null) + throw new UnknownFunctionException(pos, structName, funcName); + return func; + } + + /** + * Meta-data holder for types. + * @param type of the field. + */ + @RequiredArgsConstructor + private class FieldMetadata { + private final @NotNull String name; + private final @NotNull Type type; + private final @NotNull Function getter; + private final @Nullable BiConsumer setter; + } + + @RequiredArgsConstructor + private class FunctionMetadata { + private final @NotNull FunctionDefinition definition; + private final @NotNull BiFunction, T> implementation; + } +} diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/AbstractStructInstance.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/AbstractStructInstance.java new file mode 100644 index 00000000..a0dee35a --- /dev/null +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/AbstractStructInstance.java @@ -0,0 +1,34 @@ +package fr.jamailun.ultimatespellsystem.plugin.runner.structs; + +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenPosition; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * Structure instance for an object. + */ +public abstract class AbstractStructInstance implements Struct { + + protected final AbstractStructDefinition definition; + protected final S object; + + /** + * Wraps an object inside this definition. + * @param definition definition definition to use. + * @param object object to handle. + */ + public AbstractStructInstance(@NotNull AbstractStructDefinition definition, @NotNull S object) { + this.definition = definition; + this.object = object; + } + + @Override + public @Nullable Object getField(@NotNull TokenPosition pos, @NotNull String fieldName) { + return definition.get(object, pos, fieldName); + } + + @Override + public void setField(@NotNull TokenPosition pos, @NotNull String fieldName, @Nullable Object value) { + definition.set(object, pos, fieldName, value); + } +} diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/EntityDefinition.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/EntityDefinition.java new file mode 100644 index 00000000..fc4ef4d4 --- /dev/null +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/EntityDefinition.java @@ -0,0 +1,114 @@ +package fr.jamailun.ultimatespellsystem.plugin.runner.structs; + +import fr.jamailun.ultimatespellsystem.api.entities.SpellEntity; +import fr.jamailun.ultimatespellsystem.api.utils.StringTransformation; +import fr.jamailun.ultimatespellsystem.dsl2.library.StructDefinition; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; +import fr.jamailun.ultimatespellsystem.dsl2.registries.ObjectsDefinitionRegistry; +import org.bukkit.Location; +import org.bukkit.attribute.Attribute; +import org.bukkit.attribute.AttributeInstance; +import org.bukkit.entity.Damageable; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Objects; +import java.util.function.Function; + +/** + * "Implements" the abstract {@link fr.jamailun.ultimatespellsystem.dsl2.library.structs.EntityStruct}. + */ +public class EntityDefinition extends AbstractStructDefinition { + + private static EntityDefinition FLY_INSTANCE = null; + public static @NotNull EntityDefinition get() { + if(FLY_INSTANCE == null) + FLY_INSTANCE = new EntityDefinition(); + return FLY_INSTANCE; + } + + private StructDefinition struct; + + /** + * Create a new definition. + */ + public EntityDefinition() { + super("entity"); + loadFields(); + loadFunctions(); + } + + private void loadFields() { + // Name + registerString("name", makeBukkitGetter(Entity::getName)); + // Locations + registerLocation("location", SpellEntity::getLocation); + registerLocation("position", SpellEntity::getLocation); + registerLocation("eye_location", SpellEntity::getEyeLocation); + registerLocation("eye_position", SpellEntity::getEyeLocation); + registerNumber("x", e -> e.getLocation().getX()); + registerNumber("y", e -> e.getLocation().getY()); + registerNumber("z", e -> e.getLocation().getZ()); + registerNumber("yaw", e -> e.getLocation().getYaw()); + registerNumber("pitch", e -> e.getLocation().getPitch()); + // Health + registerNumber("health", makeBukkitGetter(Damageable::getHealth, 0)); + // Attributes + registerNumber("max_health", makeAttribute(Attribute.GENERIC_MAX_HEALTH)); + registerNumber("armor", makeAttribute(Attribute.GENERIC_ARMOR)); + registerNumber("armor_toughness", makeAttribute(Attribute.GENERIC_ARMOR_TOUGHNESS)); + registerNumber("attack", makeAttribute(Attribute.GENERIC_ATTACK_DAMAGE)); + registerNumber("attack_damage", makeAttribute(Attribute.GENERIC_ATTACK_DAMAGE)); + registerNumber("damage", makeAttribute(Attribute.GENERIC_ATTACK_DAMAGE)); + registerNumber("speed", makeAttribute(Attribute.GENERIC_MOVEMENT_SPEED)); + registerNumber("knockback", makeAttribute(Attribute.GENERIC_ATTACK_KNOCKBACK)); + registerNumber("knockback_resistance", makeAttribute(Attribute.GENERIC_KNOCKBACK_RESISTANCE)); + } + + private void loadFunctions() { + registerNullFunc( + "teleport", + (se,a) -> se.teleport((Location) a.getFirst()), + FunctionArgument.of(TYPE_LOCATION) + ); + registerNullFunc( + "send_message", + (se,a) -> se.sendMessage(StringTransformation.parse((String) a.getFirst())), + FunctionArgument.of(TypePrimitive.STRING) + ); + registerNullFunc( + "heal", + (se,a) -> se.getEntityAs(LivingEntity.class).ifPresent(le -> le.heal((Double)a.getFirst())), + FunctionArgument.of(TypePrimitive.NUMBER) + ); + } + + @Override + protected @NotNull StructDefinition dsl() { + if(struct == null) + struct = Objects.requireNonNull(ObjectsDefinitionRegistry.getDefaultStruct(TYPE_ENTITY.getName()), "Entity struct cannot be found in defaults."); + return struct; + } + + private static @NotNull Function makeBukkitGetter(@NotNull Function getter) { + return makeBukkitGetter(getter, null); + } + + private static @NotNull Function makeBukkitGetter(@NotNull Function getter, @Nullable T defaultValue) { + return se -> { + if(se.getBukkitEntity().orElse(null) instanceof LivingEntity le) + return getter.apply(le); + return defaultValue; + }; + } + + private static @NotNull Function makeAttribute(@NotNull Attribute attribute) { + return makeBukkitGetter(e -> { + AttributeInstance ai = e.getAttribute(attribute); + return ai == null ? 0 : ai.getValue(); + }); + } +} diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/EntityInstance.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/EntityInstance.java new file mode 100644 index 00000000..00482fbc --- /dev/null +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/EntityInstance.java @@ -0,0 +1,19 @@ +package fr.jamailun.ultimatespellsystem.plugin.runner.structs; + +import fr.jamailun.ultimatespellsystem.api.entities.SpellEntity; +import org.jetbrains.annotations.NotNull; + +/** + * Structure wrapper for an entity. + */ +public class EntityInstance extends AbstractStructInstance { + + /** + * Wraps a spell-entity inside this definition. + * @param entity the entity to use. + */ + public EntityInstance(@NotNull SpellEntity entity) { + super(EntityDefinition.get(), entity); + } + +} diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/Struct.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/Struct.java new file mode 100644 index 00000000..4e8f994a --- /dev/null +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/Struct.java @@ -0,0 +1,25 @@ +package fr.jamailun.ultimatespellsystem.plugin.runner.structs; + +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenPosition; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public interface Struct { + + /** + * Get a field value. + * @param pos token position requesting the data. + * @param fieldName name of the field. + * @return the field value. + */ + @Nullable Object getField(@NotNull TokenPosition pos, @NotNull String fieldName); + + /** + * Set a field value. + * @param pos token position requesting the data. + * @param fieldName name of the field. + * @param value the field new value. + */ + void setField(@NotNull TokenPosition pos, @NotNull String fieldName, @Nullable Object value); + +} diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/StructDefinition.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/StructDefinition.java new file mode 100644 index 00000000..aee63a3f --- /dev/null +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/StructDefinition.java @@ -0,0 +1,37 @@ +package fr.jamailun.ultimatespellsystem.plugin.runner.structs; + +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionDefinition; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; +import java.util.function.BiConsumer; +import java.util.function.BiFunction; +import java.util.function.Function; + +/** + * A structure definition. + * @param the underlying type of the structure. + */ +public interface StructDefinition { + + /** + * Register a new field on the struct. + * @param name the name of the field. If not unique, an exception will be thrown. + * @param type type of the field. + * @param getter the getter of the field. + * @param setter optional setter for the field. + * @param type of the field. + */ + void registerField(@NotNull String name, @NotNull Type type, @NotNull Function getter, @Nullable BiConsumer setter); + + /** + * Register a new function on the struct. + * @param functionDefinition the DSL function definition. + * @param function the function that handles the runtime. + * @param the output type of the function. + */ + void registerFunction(@NotNull FunctionDefinition functionDefinition, @NotNull BiFunction, T> function); + +} From c78db2e1734342bab32d3bfa98a584ea6ece9370 Mon Sep 17 00:00:00 2001 From: "timothe.rosaz" Date: Fri, 31 Oct 2025 21:33:30 +0100 Subject: [PATCH 25/38] Added console object --- .../structs/AbstractStructDefinition.java | 14 +++++- .../structs/AbstractStructInstance.java | 2 +- .../runner/structs/ConsoleDefinition.java | 48 +++++++++++++++++++ .../runner/structs/ConsoleInstance.java | 15 ++++++ .../runner/structs/EntityDefinition.java | 8 +--- 5 files changed, 79 insertions(+), 8 deletions(-) create mode 100644 plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/ConsoleDefinition.java create mode 100644 plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/ConsoleInstance.java diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/AbstractStructDefinition.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/AbstractStructDefinition.java index 9cab6cfc..9ca9ee62 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/AbstractStructDefinition.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/AbstractStructDefinition.java @@ -35,6 +35,7 @@ public abstract class AbstractStructDefinition implements StructDefinition private final Map> functions = new HashMap<>(); @Getter protected final String structName; + private fr.jamailun.ultimatespellsystem.dsl2.library.StructDefinition struct; @Override public void registerField(@NotNull String name, @NotNull Type type, @NotNull Function getter, @Nullable BiConsumer setter) { @@ -77,11 +78,22 @@ protected void registerNullFunc(@NotNull String name, @NotNull BiConsumer implements Struct { * @param definition definition definition to use. * @param object object to handle. */ - public AbstractStructInstance(@NotNull AbstractStructDefinition definition, @NotNull S object) { + public AbstractStructInstance(@NotNull AbstractStructDefinition definition, S object) { this.definition = definition; this.object = object; } diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/ConsoleDefinition.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/ConsoleDefinition.java new file mode 100644 index 00000000..955df9fd --- /dev/null +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/ConsoleDefinition.java @@ -0,0 +1,48 @@ +package fr.jamailun.ultimatespellsystem.plugin.runner.structs; + +import fr.jamailun.ultimatespellsystem.UssLogger; +import fr.jamailun.ultimatespellsystem.dsl2.library.StructDefinition; +import fr.jamailun.ultimatespellsystem.dsl2.library.structs.ConsoleStruct; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; +import fr.jamailun.ultimatespellsystem.dsl2.registries.ObjectsDefinitionRegistry; +import org.jetbrains.annotations.NotNull; + +import java.util.Objects; +import java.util.function.Consumer; + +/** + * Definition for the 'console' object. + */ +public class ConsoleDefinition extends AbstractStructDefinition { + + private static ConsoleDefinition FLY_INSTANCE = null; + public static @NotNull ConsoleDefinition get() { + if(FLY_INSTANCE == null) + FLY_INSTANCE = new ConsoleDefinition(); + return FLY_INSTANCE; + } + + public ConsoleDefinition() { + super(ConsoleStruct.NAME); + // Functions + registerSend("send", UssLogger::logInfo); + registerSend("debug", UssLogger::logDebug); + registerSend("info", UssLogger::logInfo); + registerSend("warning", UssLogger::logWarning); + registerSend("error", UssLogger::logError); + } + + private void registerSend(String name, Consumer method) { + registerNullFunc( + name, + (x, args) -> method.accept((String) args.getFirst()), + FunctionArgument.of(TypePrimitive.STRING) + ); + } + + @Override + protected @NotNull StructDefinition computeDsl() { + return Objects.requireNonNull(ObjectsDefinitionRegistry.getDefaultStruct(structName), "Console struct cannot be found in defaults."); + } +} diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/ConsoleInstance.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/ConsoleInstance.java new file mode 100644 index 00000000..b8ebef77 --- /dev/null +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/ConsoleInstance.java @@ -0,0 +1,15 @@ +package fr.jamailun.ultimatespellsystem.plugin.runner.structs; + +/** + * Structure for the console. + */ +public class ConsoleInstance extends AbstractStructInstance { + + /** + * Create a new console instance. + */ + public ConsoleInstance() { + super(ConsoleDefinition.get(), null); + } + +} diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/EntityDefinition.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/EntityDefinition.java index fc4ef4d4..36c9f4d9 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/EntityDefinition.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/EntityDefinition.java @@ -30,8 +30,6 @@ public class EntityDefinition extends AbstractStructDefinition { return FLY_INSTANCE; } - private StructDefinition struct; - /** * Create a new definition. */ @@ -87,10 +85,8 @@ private void loadFunctions() { } @Override - protected @NotNull StructDefinition dsl() { - if(struct == null) - struct = Objects.requireNonNull(ObjectsDefinitionRegistry.getDefaultStruct(TYPE_ENTITY.getName()), "Entity struct cannot be found in defaults."); - return struct; + protected @NotNull StructDefinition computeDsl() { + return Objects.requireNonNull(ObjectsDefinitionRegistry.getDefaultStruct(structName), "Entity struct cannot be found in defaults."); } private static @NotNull Function makeBukkitGetter(@NotNull Function getter) { From 6ca0b4842e7df9dbe398356631f82b91978aba38 Mon Sep 17 00:00:00 2001 From: "timothe.rosaz" Date: Sat, 1 Nov 2025 11:35:18 +0100 Subject: [PATCH 26/38] Cleaning the mess, upgraded runtime builders --- .../api/runner/SpellRuntime.java | 37 +++- .../api}/runner/structs/Struct.java | 16 +- .../api}/runner/structs/StructDefinition.java | 2 +- .../nodes/expressions/FieldGetExpression.java | 17 +- .../expressions/FunctionCallExpression.java | 8 +- .../functions/FunctionArgument.java | 6 +- .../DeclareNewVariableStatement.java | 13 +- .../jamailun/ultimatespellsystem/UssMain.java | 3 +- .../functions/EntityHasEffectFunction.java | 2 +- .../plugin/commands/UssCommand.java | 2 +- .../plugin/listeners/PlayerLeaveListener.java | 2 +- .../runner/builder/ExpressionQueue.java | 165 ++++++++--------- .../runner/builder/SpellBuilderVisitor.java | 167 ++++-------------- .../functions/JavaFunctionCallNode.java | 2 + .../expressions/{ => _old}/AllAroundNode.java | 2 +- .../{ => _old}/EntityTypeLiteral.java | 2 +- .../{ => _old}/ExpressionWrapperNode.java | 2 +- .../{ => _old}/PositionOfNode.java | 2 +- .../expressions/{ => _old}/SizeOfNode.java | 2 +- .../functions/RuntimeFunctionDeclaration.java | 68 +++++++ .../functions/{ => _old}/DefineNode.java | 2 +- .../nodes/functions/{ => _old}/GiveNode.java | 2 +- .../{ => _old}/SendAttributeNode.java | 2 +- .../functions/{ => _old}/SendEffectNode.java | 2 +- .../functions/{ => _old}/SendMessageNode.java | 2 +- .../functions/{ => _old}/SendNbtNode.java | 2 +- .../functions/{ => _old}/SummonNode.java | 2 +- .../functions/{ => _old}/TeleportNode.java | 2 +- .../{ => _old}/play/PlayAnimationNode.java | 2 +- .../{ => _old}/play/PlayBlockNode.java | 2 +- .../functions/{ => _old}/play/PlayNode.java | 2 +- .../{ => _old}/play/PlayParticleNode.java | 2 +- .../{ => _old}/play/PlaySoundNode.java | 2 +- .../runner/nodes/operators/IncrementNode.java | 30 ++-- .../nodes/operators/list/ListAddRemOpe.java | 54 ------ .../nodes/operators/list/ListContainsOpe.java | 41 ----- .../nodes/operators/list/ListRemIndexOpe.java | 33 ---- .../{list => objects}/ArrayGetNode.java | 2 +- .../objects/GlobalFunctionCallNode.java | 43 +++++ .../operators/objects/StructFieldGetNode.java | 39 ++++ .../objects/StructFunctionCallNode.java | 50 ++++++ .../nodes/statements/AffectVarNode.java | 22 +++ .../nodes/statements/DeclareVarNode.java | 28 +++ .../ReturnNode.java} | 18 +- .../structs/AbstractStructDefinition.java | 1 + .../structs/AbstractStructInstance.java | 1 + .../plugin/spells/PropertiesValidator.java | 2 +- .../spells/functions/SpellFunction.java | 2 +- .../utils/holders/PotionEffectHolder.java | 2 +- .../runner/SimpleTest.java | 2 +- 50 files changed, 500 insertions(+), 416 deletions(-) rename {plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin => api/src/main/java/fr/jamailun/ultimatespellsystem/api}/runner/structs/Struct.java (59%) rename {plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin => api/src/main/java/fr/jamailun/ultimatespellsystem/api}/runner/structs/StructDefinition.java (95%) rename plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/expressions/{ => _old}/AllAroundNode.java (99%) rename plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/expressions/{ => _old}/EntityTypeLiteral.java (98%) rename plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/expressions/{ => _old}/ExpressionWrapperNode.java (98%) rename plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/expressions/{ => _old}/PositionOfNode.java (99%) rename plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/expressions/{ => _old}/SizeOfNode.java (97%) create mode 100644 plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/RuntimeFunctionDeclaration.java rename plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/{ => _old}/DefineNode.java (99%) rename plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/{ => _old}/GiveNode.java (99%) rename plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/{ => _old}/SendAttributeNode.java (99%) rename plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/{ => _old}/SendEffectNode.java (99%) rename plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/{ => _old}/SendMessageNode.java (99%) rename plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/{ => _old}/SendNbtNode.java (99%) rename plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/{ => _old}/SummonNode.java (99%) rename plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/{ => _old}/TeleportNode.java (99%) rename plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/{ => _old}/play/PlayAnimationNode.java (98%) rename plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/{ => _old}/play/PlayBlockNode.java (98%) rename plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/{ => _old}/play/PlayNode.java (99%) rename plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/{ => _old}/play/PlayParticleNode.java (98%) rename plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/{ => _old}/play/PlaySoundNode.java (98%) delete mode 100644 plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/list/ListAddRemOpe.java delete mode 100644 plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/list/ListContainsOpe.java delete mode 100644 plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/list/ListRemIndexOpe.java rename plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/{list => objects}/ArrayGetNode.java (98%) create mode 100644 plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/objects/GlobalFunctionCallNode.java create mode 100644 plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/objects/StructFieldGetNode.java create mode 100644 plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/objects/StructFunctionCallNode.java create mode 100644 plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/statements/AffectVarNode.java create mode 100644 plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/statements/DeclareVarNode.java rename plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/{functions/StopNode.java => statements/ReturnNode.java} (57%) diff --git a/api/src/main/java/fr/jamailun/ultimatespellsystem/api/runner/SpellRuntime.java b/api/src/main/java/fr/jamailun/ultimatespellsystem/api/runner/SpellRuntime.java index ccd64235..499fb9cd 100644 --- a/api/src/main/java/fr/jamailun/ultimatespellsystem/api/runner/SpellRuntime.java +++ b/api/src/main/java/fr/jamailun/ultimatespellsystem/api/runner/SpellRuntime.java @@ -1,6 +1,7 @@ package fr.jamailun.ultimatespellsystem.api.runner; import fr.jamailun.ultimatespellsystem.api.entities.SpellEntity; +import fr.jamailun.ultimatespellsystem.api.runner.structs.Struct; import fr.jamailun.ultimatespellsystem.api.spells.Spell; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; @@ -39,9 +40,9 @@ public interface SpellRuntime { /** * Stop the current execution. - * @param exitCode the exit code to use. + * @param exitValue the exit value returned. */ - void stop(int exitCode); + void stop(@Nullable Object exitValue); /** * Break the flow. @@ -58,6 +59,12 @@ public interface SpellRuntime { */ void acceptContinue(); + /** + * Handle a return statement. + * @param value output-ed value. + */ + void statementReturn(@Nullable Object value); + /** * Get the state of the control flow. * @return a state. @@ -69,7 +76,17 @@ public interface SpellRuntime { * @return a new instance of a runtime, with the same context. */ @Contract(" -> new") - @NotNull SpellRuntime makeChild(); + default @NotNull SpellRuntime makeChild() { + return makeChild(false); + } + + /** + * Create a child of this runtime. + * @param function if {@code true}, the child runtime will be a function. + * @return a new instance of a runtime, with the same context. + */ + @Contract("_ -> new") + @NotNull SpellRuntime makeChild(boolean function); /** * Create a child instance of this runtime, but with a different caster. @@ -80,11 +97,19 @@ public interface SpellRuntime { @NotNull SpellRuntime makeChildNewCaster(@NotNull SpellEntity newCaster); /** - * Get the final exit code. - * @return {@code zero} if it's a success (or not stopped). Any other value means an error occurred. + * Get the structure out of a value. + * @param structDefinitionName name of the structure of the type. + * @param value the value to wrap. + * @return {@code null} if cannot match. + */ + @Nullable Struct getStructOf(String structDefinitionName, Object value); + + /** + * Get the returned value. + * @return something. * @see #isStopped() */ - int getFinalExitCode(); + @Nullable Object getReturnedValue(); /** * Evaluate a value. diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/Struct.java b/api/src/main/java/fr/jamailun/ultimatespellsystem/api/runner/structs/Struct.java similarity index 59% rename from plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/Struct.java rename to api/src/main/java/fr/jamailun/ultimatespellsystem/api/runner/structs/Struct.java index 4e8f994a..473db0b8 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/Struct.java +++ b/api/src/main/java/fr/jamailun/ultimatespellsystem/api/runner/structs/Struct.java @@ -1,9 +1,14 @@ -package fr.jamailun.ultimatespellsystem.plugin.runner.structs; +package fr.jamailun.ultimatespellsystem.api.runner.structs; import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenPosition; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.List; + +/** + * Instance of a structured object. + */ public interface Struct { /** @@ -22,4 +27,13 @@ public interface Struct { */ void setField(@NotNull TokenPosition pos, @NotNull String fieldName, @Nullable Object value); + /** + * Call a function of the object. + * @param pos token position requesting the data. + * @param functionName name fo the function. + * @param parameters parameters of the function. + * @return the function output. + */ + @Nullable Object callFunction(@NotNull TokenPosition pos, @NotNull String functionName, @NotNull List parameters); + } diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/StructDefinition.java b/api/src/main/java/fr/jamailun/ultimatespellsystem/api/runner/structs/StructDefinition.java similarity index 95% rename from plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/StructDefinition.java rename to api/src/main/java/fr/jamailun/ultimatespellsystem/api/runner/structs/StructDefinition.java index aee63a3f..a7c06d67 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/StructDefinition.java +++ b/api/src/main/java/fr/jamailun/ultimatespellsystem/api/runner/structs/StructDefinition.java @@ -1,4 +1,4 @@ -package fr.jamailun.ultimatespellsystem.plugin.runner.structs; +package fr.jamailun.ultimatespellsystem.api.runner.structs; import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionDefinition; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/FieldGetExpression.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/FieldGetExpression.java index 2a8ee6be..63c410fe 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/FieldGetExpression.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/FieldGetExpression.java @@ -1,5 +1,7 @@ package fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions; +import fr.jamailun.ultimatespellsystem.dsl2.errors.TypeException; +import fr.jamailun.ultimatespellsystem.dsl2.library.StructDefinition; import fr.jamailun.ultimatespellsystem.dsl2.nodes.ExpressionNode; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.variables.TypesContext; @@ -16,6 +18,8 @@ public class FieldGetExpression extends ExpressionNode { private final ExpressionNode leftExpression; private final String fieldName; + private StructDefinition leftStruct; + public FieldGetExpression(@NotNull ExpressionNode leftExpression, @NotNull String fieldName) { super(leftExpression.firstTokenPosition()); this.leftExpression = leftExpression; @@ -24,13 +28,20 @@ public FieldGetExpression(@NotNull ExpressionNode leftExpression, @NotNull Strin @Override public @NotNull Type getExpressionType() { - //TODO pas facile, il faut les définitions des structures. - throw new UnsupportedOperationException("Not supported yet."); + return leftStruct.asType(); } @Override public void validateTypes(@NotNull TypesContext context) { - //TODO + // 1. Valider le holder, récupérer son type. + leftExpression.validateTypes(context); + Type type = leftExpression.getExpressionType(); + + // 2. Trouver la structure qui correspond au type + StructDefinition leftStruct = context.findStruct(type); + if(leftStruct == null) { + throw new TypeException(leftExpression.firstTokenPosition(), "Type value " + leftExpression + " of type " + type + " as not structure referenced. As such, cannot get field '" + fieldName + "' on it."); + } } @Override diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/FunctionCallExpression.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/FunctionCallExpression.java index 559c1f09..3ebbbb0f 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/FunctionCallExpression.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/FunctionCallExpression.java @@ -29,6 +29,8 @@ public class FunctionCallExpression extends ExpressionNode { private final String functionName; private final List arguments; + private @Nullable StructDefinition callerStruct; + public FunctionCallExpression(@Nullable ExpressionNode caller, @NotNull Token functionName, @NotNull List arguments) { super(functionName.pos()); this.caller = caller; @@ -55,11 +57,11 @@ public void validateTypes(@NotNull TypesContext context) { if(caller != null) { caller.validateTypes(context); Type callerType = caller.getExpressionType(); - StructDefinition struct = context.findStruct(callerType); - if(struct == null) { + callerStruct = context.findStruct(callerType); + if(callerStruct == null) { throw new TypeException(position, "Unknown struct for type " + callerType); } - function = struct.getFunction(functionName); + function = callerStruct.getFunction(functionName); if(function == null) { throw new TypeException(position, "Cannot call function '" + functionName + "' on type " + callerType + "."); } diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/functions/FunctionArgument.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/functions/FunctionArgument.java index 32068fd7..6b8c64e3 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/functions/FunctionArgument.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/functions/FunctionArgument.java @@ -8,14 +8,14 @@ /** * A declaration of a function argument. * @param type the type of the argument. - * @param debugName the name of the argument. + * @param name the name of the argument. * @param optional if true, argument is not mandatory. */ -public record FunctionArgument(@NotNull Type type, @NotNull String debugName, boolean optional) { +public record FunctionArgument(@NotNull Type type, @NotNull String name, boolean optional) { @Contract(pure = true) @Override public @NotNull String toString() { - return type + " " + debugName + (optional?"*":""); + return type + " " + name + (optional?"*":""); } @Contract("_ -> new") diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/DeclareNewVariableStatement.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/DeclareNewVariableStatement.java index 16bd8686..396eceb0 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/DeclareNewVariableStatement.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/DeclareNewVariableStatement.java @@ -26,6 +26,8 @@ public class DeclareNewVariableStatement extends StatementNode { private final @NotNull String varName; private final @Nullable ExpressionNode expression; + private Type compiledType; + public DeclareNewVariableStatement(@Nullable Token varType, @NotNull Token varName, @Nullable ExpressionNode expression) { this.position = varName.pos(); this.varType = varType == null ? null : varType.getContentString(); @@ -47,23 +49,22 @@ public void validateTypes(@NotNull TypesContext context) { } // 3. Validate expression if possible. - Type type; if(expression != null) { expression.validateTypes(context); - type = expression.getExpressionType(); + compiledType = expression.getExpressionType(); } else { - type = Type.ofAny(varType); + compiledType = Type.ofAny(varType); } // 4. If the type is explicit, check it matches if(varType != null) { - if(!Objects.equals(Type.ofAny(varType), type)) { - throw new TypeException(position, "Assignment for " + varName + " expected " + varType + ". Expression is of type " + type); + if(!Objects.equals(Type.ofAny(varType), compiledType)) { + throw new TypeException(position, "Assignment for " + varName + " expected " + varType + ". Expression is of type " + compiledType); } } // 5. Register the variable - context.registerVariable(position, varName, type); + context.registerVariable(position, varName, compiledType); } @Override diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/UssMain.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/UssMain.java index 987178bc..8d17b923 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/UssMain.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/UssMain.java @@ -17,7 +17,7 @@ import fr.jamailun.ultimatespellsystem.plugin.entities.BukkitSpellEntity; import fr.jamailun.ultimatespellsystem.plugin.entities.SummonsManagerImpl; import fr.jamailun.ultimatespellsystem.plugin.listeners.*; -import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.functions.SendAttributeNode; +import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.functions._old.SendAttributeNode; import fr.jamailun.ultimatespellsystem.plugin.spells.SpellsManagerImpl; import fr.jamailun.ultimatespellsystem.plugin.spells.external.ExternalExecutorImpl; import fr.jamailun.ultimatespellsystem.plugin.updater.UpdateCheck; @@ -30,7 +30,6 @@ import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; import org.bukkit.plugin.java.JavaPlugin; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/EntityHasEffectFunction.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/EntityHasEffectFunction.java index fc7c7e59..749f3af5 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/EntityHasEffectFunction.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/EntityHasEffectFunction.java @@ -6,7 +6,7 @@ import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionType; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; -import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.functions.SendEffectNode; +import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.functions._old.SendEffectNode; import org.bukkit.entity.LivingEntity; import org.bukkit.potion.PotionEffectType; import org.jetbrains.annotations.NotNull; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/commands/UssCommand.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/commands/UssCommand.java index 6779bdbb..da30e2ac 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/commands/UssCommand.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/commands/UssCommand.java @@ -14,7 +14,7 @@ import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Duration; import fr.jamailun.ultimatespellsystem.plugin.bind.SpellBindDataImpl; import fr.jamailun.ultimatespellsystem.plugin.bind.SpellTriggerImpl; -import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.functions.SendAttributeNode; +import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.functions._old.SendAttributeNode; import fr.jamailun.ultimatespellsystem.plugin.configuration.UssConfig; import fr.jamailun.ultimatespellsystem.plugin.utils.DurationHelper; import fr.jamailun.ultimatespellsystem.plugin.utils.Pair; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/listeners/PlayerLeaveListener.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/listeners/PlayerLeaveListener.java index 70fc1fc7..ea6f5f5a 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/listeners/PlayerLeaveListener.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/listeners/PlayerLeaveListener.java @@ -1,7 +1,7 @@ package fr.jamailun.ultimatespellsystem.plugin.listeners; import fr.jamailun.ultimatespellsystem.api.UltimateSpellSystem; -import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.functions.SendAttributeNode; +import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.functions._old.SendAttributeNode; import fr.jamailun.ultimatespellsystem.plugin.spells.SpellsCooldowns; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/builder/ExpressionQueue.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/builder/ExpressionQueue.java index 819fbf91..fa0f8e62 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/builder/ExpressionQueue.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/builder/ExpressionQueue.java @@ -1,26 +1,27 @@ package fr.jamailun.ultimatespellsystem.plugin.runner.builder; import fr.jamailun.ultimatespellsystem.api.providers.JavaFunctionProvider; -import fr.jamailun.ultimatespellsystem.api.runner.errors.UnknownFunctionException; import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; -import fr.jamailun.ultimatespellsystem.plugin.runner.functions.JavaFunctionCallNode; import fr.jamailun.ultimatespellsystem.api.runner.functions.RunnableJavaFunction; +import fr.jamailun.ultimatespellsystem.dsl2.library.StructDefinition; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.FunctionCallExpression; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.litteral.NullLiteral; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.operators.IncrementExpression; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenPosition; +import fr.jamailun.ultimatespellsystem.plugin.runner.functions.JavaFunctionCallNode; import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.operators.*; import fr.jamailun.ultimatespellsystem.dsl2.nodes.ExpressionNode; import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.*; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.compute.AllEntitiesAroundExpression; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionCallExpression; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.compute.PositionOfExpression; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.compute.SizeOfExpression; import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.litteral.*; import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.operators.BiOperator; import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.operators.MonoOperator; import fr.jamailun.ultimatespellsystem.dsl2.visitor.ExpressionVisitor; import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.expressions.*; -import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.operators.list.ArrayGetNode; -import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.operators.list.ListAddRemOpe; -import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.operators.list.ListContainsOpe; -import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.operators.list.ListRemIndexOpe; +import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.operators.objects.ArrayGetNode; +import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.operators.objects.GlobalFunctionCallNode; +import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.operators.objects.StructFieldGetNode; +import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.operators.objects.StructFunctionCallNode; +import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import java.util.*; @@ -39,52 +40,42 @@ RuntimeExpression fetch() { } @Override - public void handlePropertiesSet(@NotNull PropertiesExpression expression) { - Map map = new HashMap<>(); - for(Map.Entry dslEntry : expression.getExpressions().entrySet()) { - RuntimeExpression node = evaluate(dslEntry.getValue()); - map.put(dslEntry.getKey(), node); - } - add(new PropertiesLiteral(map)); + public void handleNullLiteral(@NotNull NullLiteral literal) { + add(new fr.jamailun.ultimatespellsystem.plugin.runner.nodes.expressions.NullLiteral()); } @Override - public void handleAllAround(@NotNull AllEntitiesAroundExpression expression) { - RuntimeExpression distance = evaluate(expression.getDistance()); - RuntimeExpression scope = evaluate(expression.getEntityType()); - RuntimeExpression source = evaluate(expression.getSource()); - boolean including = expression.isIncluding(); - add(new AllAroundNode(distance, scope, source, including)); + public void handleBooleanLiteral(@NotNull BooleanLiteral literal) { + add(new RawLiteral<>(literal.getRaw())); } @Override - public void handlePositionOf(@NotNull PositionOfExpression expression) { - RuntimeExpression entity = evaluate(expression.getEntity()); - add(new PositionOfNode(entity, expression.getExpressionType().isCollection())); + public void handleNumberLiteral(@NotNull NumberLiteral literal) { + add(new RawLiteral<>(literal.getRaw())); } @Override - public void handleSizeOf(@NotNull SizeOfExpression expression) { - RuntimeExpression child = evaluate(expression.getChild()); - add(new SizeOfNode(child)); + public void handleStringLiteral(@NotNull StringLiteral literal) { + add(new RawLiteral<>(literal.getRaw())); } @Override - public void handleFunction(@NotNull FunctionCallExpression expression) { - // 1. Find the EXECUTION of the function definition - RunnableJavaFunction function = JavaFunctionProvider.instance().find(expression.getFunction().id()); - if(function == null) - throw new UnknownFunctionException(expression.getFunction().id()); - // 2. Map arguments - List arguments = expression.getArguments().stream() - .map(this::evaluate) - .toList(); - // 3. Create node - add(new JavaFunctionCallNode(function, arguments)); + public void handleDurationLiteral(@NotNull DurationLiteral literal) { + add(new RawLiteral<>(literal.getRaw())); + } + + @Override + public void handleMapLiteral(@NotNull MapLiteral literal) { + Map map = new HashMap<>(); + for(Map.Entry dslEntry : literal.getExpressions().entrySet()) { + RuntimeExpression node = evaluate(dslEntry.getValue()); + map.put(dslEntry.getKey(), node); + } + add(new PropertiesLiteral(map)); } @Override - public void handleArray(@NotNull ArrayExpression expression) { + public void handleArray(@NotNull ArrayLiteral expression) { List elements = expression.getElements() .stream() .map(this::evaluate) @@ -93,45 +84,10 @@ public void handleArray(@NotNull ArrayExpression expression) { } @Override - public void handleVariable(@NotNull VariableExpression expression) { + public void handleVariable(@NotNull ReferenceExpression expression) { add(new VariableNode(expression.getVariableName())); } - @Override - public void handleNullLiteral(@NotNull NullExpression literal) { - add(new NullLiteral()); - } - - @Override - public void handleBooleanLiteral(@NotNull BooleanExpression literal) { - add(new RawLiteral<>(literal)); - } - - @Override - public void handleNumberLiteral(@NotNull NumberExpression literal) { - add(new RawLiteral<>(literal)); - } - - @Override - public void handleStringLiteral(@NotNull StringExpression literal) { - add(new RawLiteral<>(literal)); - } - - @Override - public void handleEntityTypeLiteral(@NotNull EntityTypeExpression literal) { - add(new EntityTypeLiteral(literal)); - } - - @Override - public void handleRuntimeLiteral(@NotNull RuntimeLiteral literal) { - add(new RawLiteral<>(literal)); - } - - @Override - public void handleDurationLiteral(@NotNull DurationExpression literal) { - add(new RawLiteral<>(literal)); - } - @Override public void handleLocationLiteral(@NotNull LocationLiteral literal) { RuntimeExpression world = evaluate(literal.getWorld()); @@ -139,7 +95,7 @@ public void handleLocationLiteral(@NotNull LocationLiteral literal) { RuntimeExpression y = evaluate(literal.getVectorY()); RuntimeExpression z = evaluate(literal.getVectorZ()); RuntimeExpression yaw = null, pitch = null; - if(literal.asYawAndPitch()) { + if(literal.hasYawAndPitch()) { yaw = evaluate(literal.getYaw()); pitch = evaluate(literal.getPitch()); } @@ -163,10 +119,6 @@ public void handleBiOperator(@NotNull BiOperator operator) { case LESSER -> new RunCompOpe(left, right, false, false); case AND -> new RunAndOrOpe(left, right, true); case OR -> new RunAndOrOpe(left, right, false); - case LIST_ADD -> new ListAddRemOpe(left, right, true); - case LIST_REM -> new ListAddRemOpe(left, right, false); - case LIST_CONTAINS -> new ListContainsOpe(left, right); - case LIST_REM_INDEX -> new ListRemIndexOpe(left, right); }); } @@ -192,11 +144,60 @@ public void handleArrayGet(@NotNull ArrayGetterExpression arrayGetter) { add(new ArrayGetNode(array, index)); } + @Override + public void handleFieldGet(@NotNull FieldGetExpression fieldGetter) { + RuntimeExpression pointer = evaluate(fieldGetter.getLeftExpression()); + StructDefinition pointerStruct = fieldGetter.getLeftStruct(); + String fieldName = fieldGetter.getFieldName(); + add(new StructFieldGetNode(fieldGetter.firstTokenPosition(), pointer, pointerStruct, fieldName)); + } + + @Override + public void handleFunctionCall(@NotNull FunctionCallExpression functionCall) { + RuntimeExpression caller = evaluate(functionCall.getCaller()); + String functionName = functionCall.getFunctionName(); + TokenPosition pos = functionCall.getPosition(); + + // Map parameters + List parameters = new ArrayList<>(); + for(ExpressionNode param : functionCall.getArguments()) { + parameters.add(evaluate(param)); + } + + // No caller : "global" function + if(caller == null) { + // Is it a java function ? + RunnableJavaFunction function = JavaFunctionProvider.instance().find(functionName); + if(function != null) { + add(new JavaFunctionCallNode(pos, function, parameters)); + } + // User-defined function instead + else { + add(new GlobalFunctionCallNode(pos, functionName, parameters)); + } + return; + } + + // A caller : struct-function call. + StructDefinition callerStruct = functionCall.getCallerStruct(); + add(new StructFunctionCallNode(pos, caller, callerStruct, functionName, parameters)); + } + + @Override + public void handleIncrementDecrement(@NotNull IncrementExpression expression) { + String varName = expression.getVarName(); + boolean increment = expression.isPositive(); + boolean postFix = expression.isAfterVar(); + add(new IncrementNode(varName, increment, postFix)); + } + private void add(RuntimeExpression expression) { currentExpressions.add(expression); } + @Contract("null -> null; !null -> new") private RuntimeExpression evaluate(ExpressionNode dsl) { + if(dsl == null) return null; currentExpressions = new ArrayDeque<>(); dsl.visit(this); RuntimeExpression node = currentExpressions.pop(); diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/builder/SpellBuilderVisitor.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/builder/SpellBuilderVisitor.java index fa6a2ca9..ba77d5b8 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/builder/SpellBuilderVisitor.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/builder/SpellBuilderVisitor.java @@ -1,11 +1,8 @@ package fr.jamailun.ultimatespellsystem.plugin.runner.builder; -import fr.jamailun.ultimatespellsystem.dsl2.objects.CallbackEvent; -import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.MetadataNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.blocks.*; -import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.expressions.ExpressionWrapperNode; -import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.functions.play.*; -import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.operators.IncrementNode; +import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.expressions._old.ExpressionWrapperNode; import fr.jamailun.ultimatespellsystem.dsl2.nodes.ExpressionNode; import fr.jamailun.ultimatespellsystem.dsl2.nodes.StatementNode; import fr.jamailun.ultimatespellsystem.dsl2.nodes.statements.*; @@ -13,16 +10,16 @@ import fr.jamailun.ultimatespellsystem.dsl2.visitor.StatementVisitor; import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.RuntimeStatement; -import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.functions.*; +import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.functions.RuntimeFunctionDeclaration; +import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.statements.AffectVarNode; +import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.statements.ReturnNode; +import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.statements.DeclareVarNode; import lombok.Getter; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.ArrayDeque; -import java.util.ArrayList; -import java.util.Deque; -import java.util.List; +import java.util.*; /** * A visitor used to build a runtime-node tree from the DSL. @@ -35,6 +32,8 @@ public class SpellBuilderVisitor implements StatementVisitor { private final List statementsAccumulator = new ArrayList<>(); private final Deque> accumulatorsStack = new ArrayDeque<>(); + @Getter private final Map functions = new HashMap<>(); + public SpellBuilderVisitor() { currentQueue = statementsAccumulator; } @@ -48,78 +47,42 @@ public SpellBuilderVisitor() { } @Override - public void handleStop(@NotNull StopStatement statement) { - RuntimeExpression exitCode = convert(statement.getExitCodeNode()); - add(new StopNode(exitCode)); - } - - @Override - public void handleSendAttribute(@NotNull SendAttributeStatement statement) { - RuntimeExpression target = convert(statement.getTarget()); - RuntimeExpression value = convert(statement.getNumericValue()); - RuntimeExpression type = convert(statement.getAttributeType()); - RuntimeExpression mode = convert(statement.getAttributeMode().orElse(null)); - RuntimeExpression duration = convert(statement.getDuration()); - add(new SendAttributeNode(target, value, type, mode, duration)); - } - - @Override - public void handleSendEffect(@NotNull SendEffectStatement statement) { - RuntimeExpression target = convert(statement.getTarget()); - RuntimeExpression effect = convert(statement.getEffectType()); - RuntimeExpression power = convert(statement.getEffectPower().orElse(null)); - RuntimeExpression duration = convert(statement.getEffectDuration()); - add(new SendEffectNode(target, effect, duration, power)); - } - - @Override - public void handleSendMessage(@NotNull SendMessageStatement statement) { - RuntimeExpression target = convert(statement.getTarget()); - RuntimeExpression message = convert(statement.getMessage()); - add(new SendMessageNode(target, message)); - } - - @Override - public void handleSendNbt(@NotNull SendNbtStatement statement) { - RuntimeExpression target = convert(statement.getTarget()); - RuntimeExpression name = convert(statement.getNbtName()); - RuntimeExpression value = convert(statement.getNbtValue()); - RuntimeExpression duration = convert(statement.getNbtDuration()); - add(new SendNbtNode(target, name, value, duration)); + public void handleDeclareVariable(@NotNull DeclareNewVariableStatement statement) { + String varName = statement.getVarName(); + Type type = statement.getCompiledType(); + RuntimeExpression expression = convert(statement.getExpression()); + add(new DeclareVarNode(varName, type, expression)); } @Override - public void handleDefine(@NotNull DefineStatement statement) { - String varName = statement.getVarName(); + public void handleAffectVariable(@NotNull AffectationStatement statement) { + RuntimeExpression holder = convert(statement.getValueHolder()); RuntimeExpression value = convert(statement.getExpression()); - add(new DefineNode(varName, value, statement.getExpression().getExpressionType())); + add(new AffectVarNode(holder, value)); } @Override - public void handleRunLater(@NotNull RunLaterStatement statement) { - RuntimeExpression duration = convert(statement.getDuration()); - RuntimeStatement child = convertOneStatement(statement.getChild()); - add(new RunLaterNode(duration, child)); - } + public void handleFunctionDeclaration(@NotNull FunctionDeclarationStatement statement) { + // Basics + String funcName = statement.getFunctionName(); + Type type = statement.getOutputType(); - @Override - public void handleRepeatRun(@NotNull RepeatStatement statement) { - RuntimeExpression period = convert(statement.getPeriod()); - RuntimeStatement child = convertOneStatement(statement.getChild()); - RuntimeExpression delay = convert(statement.getDelay().orElse(null)); - RuntimeExpression totalCount = convert(statement.getTotalCount()); - RuntimeExpression totalDuration = convert(statement.getTotalDuration()); - add(new RunRepeatNode(period, child, delay, totalCount, totalDuration)); + // Convert statements + pushQueue(); + for(StatementNode child : statement.getStatements()) { + child.visit(this); + } + List statements = List.copyOf(currentQueue); + popQueue(); + + // Register function + functions.put(funcName, new RuntimeFunctionDeclaration(funcName, type, statement.getParameters(), statements)); } @Override - public void handleSummon(@NotNull SummonStatement statement) { - RuntimeExpression type = convert(statement.getEntityType()); - RuntimeExpression source = convert(statement.getSource().orElse(null)); - RuntimeExpression duration = convert(statement.getDuration()); - RuntimeExpression properties = convert(statement.getProperties().orElse(null)); - String varName = statement.getVarName().orElse(null); - add(new SummonNode(type, source, duration, properties, varName)); + public void handleReturn(@NotNull ReturnStatement statement) { + RuntimeExpression exitCode = convert(statement.getExitCodeNode()); + add(new ReturnNode(exitCode)); } @Override @@ -130,69 +93,17 @@ public void handleBlock(@NotNull BlockStatement statement) { child.visit(this); } BlockNodes block = new BlockNodes(currentQueue); - popQueue(); add(block); } - @Override - public void handleIncrement(@NotNull IncrementStatement statement) { - String varName = statement.getVarName(); - boolean increments = statement.isPositive(); - add(new IncrementNode(varName, increments)); - } - - @Override - public void handleTeleport(@NotNull TeleportStatement statement) { - RuntimeExpression entity = convert(statement.getEntity()); - RuntimeExpression target = convert(statement.getTarget()); - add(new TeleportNode(entity, target)); - } - - @Override - public void handlePlay(@NotNull PlayStatement statement) { - RuntimeExpression location = convert(statement.getLocation()); - RuntimeExpression properties = convert(statement.getProperties()); - PlayNode node = switch (statement.getType()) { - case BLOCK -> new PlayBlockNode(location, properties); - case PARTICLE -> new PlayParticleNode(location, properties); - case SOUND -> new PlaySoundNode(location, properties); - case ANIMATION -> new PlayAnimationNode(location, properties); - }; - add(node); - } - - @Override - public void handleGive(@NotNull GiveStatement statement) { - RuntimeExpression target = convert(statement.getTarget()); - RuntimeExpression amount = convert(statement.getOptAmount()); - RuntimeExpression type = convert(statement.getOptType()); - RuntimeExpression properties = convert(statement.getOptProperties()); - add(new GiveNode(target, amount, type, properties)); - } - - @Override - public void handleCallback(@NotNull CallbackStatement statement) { - String varInput = statement.getListenVariableName(); - CallbackEvent type = statement.getCallbackType(); - String varArg = statement.getOutputVariable().orElse(null); - RuntimeStatement child = convertOneStatement(statement.getChild()); - add(new CallbackNode(varInput, type, varArg, child)); - } - @Override public void handleSimpleExpression(@NotNull SimpleExpressionStatement statement) { RuntimeExpression child = convert(statement.getChild()); add(new ExpressionWrapperNode(child)); } - @Override - public void handleMetadata(@NotNull MetadataStatement statement) { - String name = statement.getName(); - add(new MetadataNode(name, statement.getParams())); - } - @Override public void handleIf(@NotNull IfElseStatement statement) { RuntimeExpression condition = convert(statement.getCondition()); @@ -210,15 +121,6 @@ public void handleForLoop(@NotNull ForLoopStatement statement) { add(new ForLoopNode(init, condition, iteration, child)); } - @Override - public void handleForeachLoop(@NotNull ForeachLoopStatement statement) { - String varName = statement.getVariableName(); - RuntimeExpression source = convert(statement.getSource()); - RuntimeStatement child = convertOneStatement(statement.getChild()); - add(new ForeachLoopNode(varName, source, child)); - - } - @Override public void handleWhileLoop(@NotNull WhileLoopStatement statement) { RuntimeExpression condition = convert(statement.getCondition()); @@ -232,6 +134,7 @@ public void handleBreakContinue(@NotNull BreakContinueStatement statement) { add(new BreakContinueNode(statement.isContinue())); } + @Contract("null -> null; !null -> new") public RuntimeExpression convert(ExpressionNode expression) { if(expression == null) return null; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/functions/JavaFunctionCallNode.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/functions/JavaFunctionCallNode.java index 00e35beb..c97d7c4e 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/functions/JavaFunctionCallNode.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/functions/JavaFunctionCallNode.java @@ -5,6 +5,7 @@ import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; import fr.jamailun.ultimatespellsystem.api.runner.functions.RunnableJavaFunction; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenPosition; import fr.jamailun.ultimatespellsystem.plugin.entities.BukkitSpellEntity; import lombok.RequiredArgsConstructor; import org.bukkit.entity.Entity; @@ -21,6 +22,7 @@ @RequiredArgsConstructor public class JavaFunctionCallNode extends RuntimeExpression { + private final TokenPosition pos; private final RunnableJavaFunction function; private final List arguments; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/expressions/AllAroundNode.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/expressions/_old/AllAroundNode.java similarity index 99% rename from plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/expressions/AllAroundNode.java rename to plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/expressions/_old/AllAroundNode.java index f0bdc566..f65dc5a6 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/expressions/AllAroundNode.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/expressions/_old/AllAroundNode.java @@ -1,4 +1,4 @@ -package fr.jamailun.ultimatespellsystem.plugin.runner.nodes.expressions; +package fr.jamailun.ultimatespellsystem.plugin.runner.nodes.expressions._old; import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/expressions/EntityTypeLiteral.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/expressions/_old/EntityTypeLiteral.java similarity index 98% rename from plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/expressions/EntityTypeLiteral.java rename to plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/expressions/_old/EntityTypeLiteral.java index b1d64ff3..36fadace 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/expressions/EntityTypeLiteral.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/expressions/_old/EntityTypeLiteral.java @@ -1,4 +1,4 @@ -package fr.jamailun.ultimatespellsystem.plugin.runner.nodes.expressions; +package fr.jamailun.ultimatespellsystem.plugin.runner.nodes.expressions._old; import fr.jamailun.ultimatespellsystem.api.entities.UssEntityType; import fr.jamailun.ultimatespellsystem.api.providers.EntityTypeProvider; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/expressions/ExpressionWrapperNode.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/expressions/_old/ExpressionWrapperNode.java similarity index 98% rename from plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/expressions/ExpressionWrapperNode.java rename to plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/expressions/_old/ExpressionWrapperNode.java index fb3a914c..9e370134 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/expressions/ExpressionWrapperNode.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/expressions/_old/ExpressionWrapperNode.java @@ -1,4 +1,4 @@ -package fr.jamailun.ultimatespellsystem.plugin.runner.nodes.expressions; +package fr.jamailun.ultimatespellsystem.plugin.runner.nodes.expressions._old; import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.RuntimeStatement; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/expressions/PositionOfNode.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/expressions/_old/PositionOfNode.java similarity index 99% rename from plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/expressions/PositionOfNode.java rename to plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/expressions/_old/PositionOfNode.java index 8652413c..e17c5ad6 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/expressions/PositionOfNode.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/expressions/_old/PositionOfNode.java @@ -1,4 +1,4 @@ -package fr.jamailun.ultimatespellsystem.plugin.runner.nodes.expressions; +package fr.jamailun.ultimatespellsystem.plugin.runner.nodes.expressions._old; import fr.jamailun.ultimatespellsystem.UssLogger; import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/expressions/SizeOfNode.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/expressions/_old/SizeOfNode.java similarity index 97% rename from plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/expressions/SizeOfNode.java rename to plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/expressions/_old/SizeOfNode.java index 898eeff3..b62d6314 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/expressions/SizeOfNode.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/expressions/_old/SizeOfNode.java @@ -1,4 +1,4 @@ -package fr.jamailun.ultimatespellsystem.plugin.runner.nodes.expressions; +package fr.jamailun.ultimatespellsystem.plugin.runner.nodes.expressions._old; import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/RuntimeFunctionDeclaration.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/RuntimeFunctionDeclaration.java new file mode 100644 index 00000000..0823dac8 --- /dev/null +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/RuntimeFunctionDeclaration.java @@ -0,0 +1,68 @@ +package fr.jamailun.ultimatespellsystem.plugin.runner.nodes.functions; + +import fr.jamailun.ultimatespellsystem.api.runner.FlowState; +import fr.jamailun.ultimatespellsystem.api.runner.RuntimeStatement; +import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.statements.FunctionDeclarationStatement; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; +import lombok.RequiredArgsConstructor; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; + +@RequiredArgsConstructor +public class RuntimeFunctionDeclaration { + + private final @NotNull String name; + private final @NotNull Type type; + private final @NotNull List args; + private final @NotNull List statements; + + public @Nullable Object execute(@NotNull SpellRuntime runtimeSource, @NotNull List parameters) { + SpellRuntime runtime = runtimeSource.makeChild(true); + + // Register parameters as variables in local scope + for(MatchedParam param : matchParams(parameters)) { + runtime.variables().set(param.argName(), param.value()); + } + + // Execute statements + Object output = null; + for(RuntimeStatement statement : statements) { + statement.run(runtime); + + // 'Return' was used + if(runtime.getFlowState() == FlowState.STOPPED) { + output = runtime.getReturnedValue(); + break; + } + } + + //TODO Check the output type + + return output; + } + + private record MatchedParam(@NotNull String argName, @Nullable Object value) { } + + private @NotNull List matchParams(@NotNull List params) { + List output = new ArrayList<>(args.size()); + for(int i = 0; i < args.size(); i++) { + FunctionDeclarationStatement.FunctionParameter arg = args.get(i); + + // Le paramètre N est manquant. + if(params.size() <= i) { + throw new RuntimeException("Missing args. f="+name+", args=" + params + ", but expected " + args); + } + + Object value = params.get(i); + //TODO match type + + output.add(new MatchedParam(arg.name(), value)); + } + return output; + } + +} diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/DefineNode.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/_old/DefineNode.java similarity index 99% rename from plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/DefineNode.java rename to plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/_old/DefineNode.java index 35beba76..6a0d6f07 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/DefineNode.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/_old/DefineNode.java @@ -1,4 +1,4 @@ -package fr.jamailun.ultimatespellsystem.plugin.runner.nodes.functions; +package fr.jamailun.ultimatespellsystem.plugin.runner.nodes.functions._old; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/GiveNode.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/_old/GiveNode.java similarity index 99% rename from plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/GiveNode.java rename to plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/_old/GiveNode.java index 0b59d3de..297943a4 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/GiveNode.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/_old/GiveNode.java @@ -1,4 +1,4 @@ -package fr.jamailun.ultimatespellsystem.plugin.runner.nodes.functions; +package fr.jamailun.ultimatespellsystem.plugin.runner.nodes.functions._old; import fr.jamailun.ultimatespellsystem.api.UltimateSpellSystem; import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/SendAttributeNode.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/_old/SendAttributeNode.java similarity index 99% rename from plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/SendAttributeNode.java rename to plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/_old/SendAttributeNode.java index b85ee434..e114e560 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/SendAttributeNode.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/_old/SendAttributeNode.java @@ -1,4 +1,4 @@ -package fr.jamailun.ultimatespellsystem.plugin.runner.nodes.functions; +package fr.jamailun.ultimatespellsystem.plugin.runner.nodes.functions._old; import fr.jamailun.ultimatespellsystem.UssKeys; import fr.jamailun.ultimatespellsystem.api.UltimateSpellSystem; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/SendEffectNode.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/_old/SendEffectNode.java similarity index 99% rename from plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/SendEffectNode.java rename to plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/_old/SendEffectNode.java index 28eb921b..72966fa0 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/SendEffectNode.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/_old/SendEffectNode.java @@ -1,4 +1,4 @@ -package fr.jamailun.ultimatespellsystem.plugin.runner.nodes.functions; +package fr.jamailun.ultimatespellsystem.plugin.runner.nodes.functions._old; import fr.jamailun.ultimatespellsystem.UssLogger; import fr.jamailun.ultimatespellsystem.api.entities.SpellEntity; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/SendMessageNode.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/_old/SendMessageNode.java similarity index 99% rename from plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/SendMessageNode.java rename to plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/_old/SendMessageNode.java index 6312c88e..7dc1c983 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/SendMessageNode.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/_old/SendMessageNode.java @@ -1,4 +1,4 @@ -package fr.jamailun.ultimatespellsystem.plugin.runner.nodes.functions; +package fr.jamailun.ultimatespellsystem.plugin.runner.nodes.functions._old; import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.RuntimeStatement; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/SendNbtNode.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/_old/SendNbtNode.java similarity index 99% rename from plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/SendNbtNode.java rename to plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/_old/SendNbtNode.java index 22605333..2e707b18 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/SendNbtNode.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/_old/SendNbtNode.java @@ -1,4 +1,4 @@ -package fr.jamailun.ultimatespellsystem.plugin.runner.nodes.functions; +package fr.jamailun.ultimatespellsystem.plugin.runner.nodes.functions._old; import fr.jamailun.ultimatespellsystem.UssKeys; import fr.jamailun.ultimatespellsystem.UssLogger; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/SummonNode.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/_old/SummonNode.java similarity index 99% rename from plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/SummonNode.java rename to plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/_old/SummonNode.java index b43b47c4..99c09c9d 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/SummonNode.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/_old/SummonNode.java @@ -1,4 +1,4 @@ -package fr.jamailun.ultimatespellsystem.plugin.runner.nodes.functions; +package fr.jamailun.ultimatespellsystem.plugin.runner.nodes.functions._old; import fr.jamailun.ultimatespellsystem.UssLogger; import fr.jamailun.ultimatespellsystem.api.UltimateSpellSystem; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/TeleportNode.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/_old/TeleportNode.java similarity index 99% rename from plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/TeleportNode.java rename to plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/_old/TeleportNode.java index 32eaedc2..150998cb 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/TeleportNode.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/_old/TeleportNode.java @@ -1,4 +1,4 @@ -package fr.jamailun.ultimatespellsystem.plugin.runner.nodes.functions; +package fr.jamailun.ultimatespellsystem.plugin.runner.nodes.functions._old; import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.RuntimeStatement; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/play/PlayAnimationNode.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/_old/play/PlayAnimationNode.java similarity index 98% rename from plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/play/PlayAnimationNode.java rename to plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/_old/play/PlayAnimationNode.java index 17c9b779..fecb68e8 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/play/PlayAnimationNode.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/_old/play/PlayAnimationNode.java @@ -1,4 +1,4 @@ -package fr.jamailun.ultimatespellsystem.plugin.runner.nodes.functions.play; +package fr.jamailun.ultimatespellsystem.plugin.runner.nodes.functions._old.play; import fr.jamailun.ultimatespellsystem.UssLogger; import fr.jamailun.ultimatespellsystem.api.UltimateSpellSystem; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/play/PlayBlockNode.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/_old/play/PlayBlockNode.java similarity index 98% rename from plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/play/PlayBlockNode.java rename to plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/_old/play/PlayBlockNode.java index f41c6fce..4778134c 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/play/PlayBlockNode.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/_old/play/PlayBlockNode.java @@ -1,4 +1,4 @@ -package fr.jamailun.ultimatespellsystem.plugin.runner.nodes.functions.play; +package fr.jamailun.ultimatespellsystem.plugin.runner.nodes.functions._old.play; import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.plugin.utils.holders.BlockHolder; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/play/PlayNode.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/_old/play/PlayNode.java similarity index 99% rename from plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/play/PlayNode.java rename to plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/_old/play/PlayNode.java index 0764d9f1..2d31a086 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/play/PlayNode.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/_old/play/PlayNode.java @@ -1,4 +1,4 @@ -package fr.jamailun.ultimatespellsystem.plugin.runner.nodes.functions.play; +package fr.jamailun.ultimatespellsystem.plugin.runner.nodes.functions._old.play; import fr.jamailun.ultimatespellsystem.api.UltimateSpellSystem; import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/play/PlayParticleNode.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/_old/play/PlayParticleNode.java similarity index 98% rename from plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/play/PlayParticleNode.java rename to plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/_old/play/PlayParticleNode.java index e666287f..4f9f7987 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/play/PlayParticleNode.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/_old/play/PlayParticleNode.java @@ -1,4 +1,4 @@ -package fr.jamailun.ultimatespellsystem.plugin.runner.nodes.functions.play; +package fr.jamailun.ultimatespellsystem.plugin.runner.nodes.functions._old.play; import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.plugin.utils.holders.ParticleHolder; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/play/PlaySoundNode.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/_old/play/PlaySoundNode.java similarity index 98% rename from plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/play/PlaySoundNode.java rename to plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/_old/play/PlaySoundNode.java index ea75fdc4..afea5bb2 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/play/PlaySoundNode.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/_old/play/PlaySoundNode.java @@ -1,4 +1,4 @@ -package fr.jamailun.ultimatespellsystem.plugin.runner.nodes.functions.play; +package fr.jamailun.ultimatespellsystem.plugin.runner.nodes.functions._old.play; import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.plugin.utils.holders.SoundHolder; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/IncrementNode.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/IncrementNode.java index de7f6f80..81abf8d1 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/IncrementNode.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/IncrementNode.java @@ -1,29 +1,27 @@ package fr.jamailun.ultimatespellsystem.plugin.runner.nodes.operators; -import fr.jamailun.ultimatespellsystem.api.runner.RuntimeStatement; +import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; import fr.jamailun.ultimatespellsystem.api.runner.errors.UnreachableRuntimeException; +import lombok.RequiredArgsConstructor; import org.jetbrains.annotations.NotNull; -public class IncrementNode extends RuntimeStatement { +@RequiredArgsConstructor +public class IncrementNode extends RuntimeExpression { - private final String varName; + private final @NotNull String varName; private final boolean increments; - - public IncrementNode(@NotNull String varName, boolean increments) { - this.varName = varName; - this.increments = increments; - } + private final boolean postFix; @Override - public void run(@NotNull SpellRuntime runtime) { + public Double evaluate(@NotNull SpellRuntime runtime) { Object value = runtime.variables().get(varName); - if(value instanceof Double d) { - double v = d + (increments ? 1 : -1); - runtime.variables().set(varName, v); - return; - } - throw new UnreachableRuntimeException("Invalid type for variable " + varName + " : " + value); - } + if(!(value instanceof Number num)) + throw new UnreachableRuntimeException("Invalid type for variable " + varName + " : " + value); + double input = num.doubleValue(); + double output = input + (increments ? 1 : -1); + runtime.variables().set(varName, output); + return postFix ? input : output; + } } diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/list/ListAddRemOpe.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/list/ListAddRemOpe.java deleted file mode 100644 index 6937ee76..00000000 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/list/ListAddRemOpe.java +++ /dev/null @@ -1,54 +0,0 @@ -package fr.jamailun.ultimatespellsystem.plugin.runner.nodes.operators.list; - -import fr.jamailun.ultimatespellsystem.UssLogger; -import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; -import fr.jamailun.ultimatespellsystem.api.runner.errors.UnreachableRuntimeException; -import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.operators.RuntimeBiOperator; -import org.jetbrains.annotations.NotNull; - -import java.util.Collection; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -/** - * An 'append' or 'remove' on list, operator. - */ -public class ListAddRemOpe extends RuntimeBiOperator { - - private final boolean append; - - public ListAddRemOpe(@NotNull RuntimeExpression left, @NotNull RuntimeExpression right, boolean append) { - super(left, right); - this.append = append; - } - - @Override - protected Object evaluate(Object left, Object right) { - if(!(left instanceof List list)) - throw new UnreachableRuntimeException("Cannot have a left non-list: " + left); - - // Handle MONO and MULTI cases - Set allOthers; - if(right instanceof Collection coll) { - allOthers = new HashSet<>(coll); - } else { - allOthers = Set.of(right); - } - - List listObj = (List) list; - if(append) { - listObj.addAll(allOthers); - UssLogger.logDebug("[List:add] New list: " + listObj); - } else { - listObj.removeAll(allOthers); - UssLogger.logDebug("[List:rem] New list: " + listObj); - } - return listObj; - } - - @Override - public String toString() { - return leftExpression +(append?".add(":".remove(") + rightExpression + ")"; - } -} diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/list/ListContainsOpe.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/list/ListContainsOpe.java deleted file mode 100644 index 63a6286c..00000000 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/list/ListContainsOpe.java +++ /dev/null @@ -1,41 +0,0 @@ -package fr.jamailun.ultimatespellsystem.plugin.runner.nodes.operators.list; - -import fr.jamailun.ultimatespellsystem.UssLogger; -import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; -import fr.jamailun.ultimatespellsystem.api.runner.errors.UnreachableRuntimeException; -import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.operators.RuntimeBiOperator; -import org.jetbrains.annotations.NotNull; - -import java.util.Collection; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -/** - * A "does list contains element" operation. - */ -public class ListContainsOpe extends RuntimeBiOperator { - - public ListContainsOpe(@NotNull RuntimeExpression left, @NotNull RuntimeExpression right) { - super(left, right); - } - - @Override - protected Object evaluate(Object left, Object right) { - if(!(left instanceof List list)) - throw new UnreachableRuntimeException("Cannot have a left non-list: " + left + "|" + left.getClass() + ". L = " + leftExpression + "; R = " + rightExpression); - // Better performance if we hash data. - Set hashedList = new HashSet<>(list); - - if(right instanceof Collection others) { - return hashedList.containsAll(new HashSet<>(others)); - } - UssLogger.logDebug("[List:contains] Contains ? " + list.contains(right)); - return list.contains(right); - } - - @Override - public String toString() { - return leftExpression + ".contains(" + rightExpression + ")"; - } -} diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/list/ListRemIndexOpe.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/list/ListRemIndexOpe.java deleted file mode 100644 index 6e51dfe1..00000000 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/list/ListRemIndexOpe.java +++ /dev/null @@ -1,33 +0,0 @@ -package fr.jamailun.ultimatespellsystem.plugin.runner.nodes.operators.list; - -import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; -import fr.jamailun.ultimatespellsystem.api.runner.errors.UnreachableRuntimeException; -import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.operators.RuntimeBiOperator; -import org.jetbrains.annotations.NotNull; - -import java.util.List; - -/** - * A "remove at index" operation. - */ -public class ListRemIndexOpe extends RuntimeBiOperator { - - public ListRemIndexOpe(@NotNull RuntimeExpression left, @NotNull RuntimeExpression right) { - super(left, right); - } - - @Override - protected Object evaluate(Object left, Object right) { - if(!(left instanceof List list)) - throw new UnreachableRuntimeException("Cannot have a left non-list: " + left); - if(!(right instanceof Number index)) - throw new UnreachableRuntimeException("Cannot have a right non-number: " + right); - list.remove(index.intValue()); - return list; - } - - @Override - public String toString() { - return leftExpression + ".remove(" + rightExpression + ")"; - } -} diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/list/ArrayGetNode.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/objects/ArrayGetNode.java similarity index 98% rename from plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/list/ArrayGetNode.java rename to plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/objects/ArrayGetNode.java index f2ace184..b808cf02 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/list/ArrayGetNode.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/objects/ArrayGetNode.java @@ -1,4 +1,4 @@ -package fr.jamailun.ultimatespellsystem.plugin.runner.nodes.operators.list; +package fr.jamailun.ultimatespellsystem.plugin.runner.nodes.operators.objects; import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/objects/GlobalFunctionCallNode.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/objects/GlobalFunctionCallNode.java new file mode 100644 index 00000000..29d87be7 --- /dev/null +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/objects/GlobalFunctionCallNode.java @@ -0,0 +1,43 @@ +package fr.jamailun.ultimatespellsystem.plugin.runner.nodes.operators.objects; + +import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; +import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; +import fr.jamailun.ultimatespellsystem.api.runner.structs.Struct; +import fr.jamailun.ultimatespellsystem.dsl2.library.StructDefinition; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenPosition; +import lombok.RequiredArgsConstructor; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; + +/** + * Getter on a field of an object. + */ +@RequiredArgsConstructor +public class GlobalFunctionCallNode extends RuntimeExpression { + + private final TokenPosition pos; + private final String functionName; + private final List parameters; + + @Override + public @Nullable Object evaluate(@NotNull SpellRuntime runtime) { + // Find function + + // Handle params + List params = new ArrayList<>(parameters.size()); + for(RuntimeExpression expression : parameters) { + params.add(expression.evaluate(runtime)); + } + + // Call function + return struct.callFunction(pos, functionName, params); + } + + @Override + public @NotNull String toString() { + return functionName + "(" + parameters + ")"; + } +} diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/objects/StructFieldGetNode.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/objects/StructFieldGetNode.java new file mode 100644 index 00000000..06a051f5 --- /dev/null +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/objects/StructFieldGetNode.java @@ -0,0 +1,39 @@ +package fr.jamailun.ultimatespellsystem.plugin.runner.nodes.operators.objects; + +import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; +import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; +import fr.jamailun.ultimatespellsystem.dsl2.library.StructDefinition; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenPosition; +import fr.jamailun.ultimatespellsystem.api.runner.structs.Struct; +import lombok.RequiredArgsConstructor; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * Getter on a field of an object. + */ +@RequiredArgsConstructor +public class StructFieldGetNode extends RuntimeExpression { + + private final TokenPosition pos; + private final RuntimeExpression object; + private final StructDefinition objectStruct; + private final String fieldName; + + @Override + public @Nullable Object evaluate(@NotNull SpellRuntime runtime) { + Object target = object.evaluate(runtime); + + // "definition → instance", à partir de OBJECT + Struct struct = runtime.getStructOf(objectStruct.getName(), target); + if(struct == null) + throw new RuntimeException("Cannot get struct '" + objectStruct.getName() + "' from value " + target + "."); + + return struct.getField(pos, fieldName); + } + + @Override + public @NotNull String toString() { + return object + "." + fieldName; + } +} diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/objects/StructFunctionCallNode.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/objects/StructFunctionCallNode.java new file mode 100644 index 00000000..3a676f14 --- /dev/null +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/objects/StructFunctionCallNode.java @@ -0,0 +1,50 @@ +package fr.jamailun.ultimatespellsystem.plugin.runner.nodes.operators.objects; + +import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; +import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; +import fr.jamailun.ultimatespellsystem.api.runner.structs.Struct; +import fr.jamailun.ultimatespellsystem.dsl2.library.StructDefinition; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenPosition; +import lombok.RequiredArgsConstructor; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; + +/** + * Getter on a field of an object. + */ +@RequiredArgsConstructor +public class StructFunctionCallNode extends RuntimeExpression { + + private final TokenPosition pos; + private final RuntimeExpression object; + private final StructDefinition objectStruct; + private final String functionName; + private final List parameters; + + @Override + public @Nullable Object evaluate(@NotNull SpellRuntime runtime) { + Object target = object.evaluate(runtime); + + // "definition → instance", à partir de OBJECT + Struct struct = runtime.getStructOf(objectStruct.getName(), target); + if(struct == null) + throw new RuntimeException("Cannot get struct '" + objectStruct.getName() + "' from value " + target + "."); + + // Handle params + List params = new ArrayList<>(parameters.size()); + for(RuntimeExpression expression : parameters) { + params.add(expression.evaluate(runtime)); + } + + // Call function + return struct.callFunction(pos, functionName, params); + } + + @Override + public @NotNull String toString() { + return object + "." + functionName + "(" + parameters + ")"; + } +} diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/statements/AffectVarNode.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/statements/AffectVarNode.java new file mode 100644 index 00000000..b39c67d3 --- /dev/null +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/statements/AffectVarNode.java @@ -0,0 +1,22 @@ +package fr.jamailun.ultimatespellsystem.plugin.runner.nodes.statements; + +import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; +import fr.jamailun.ultimatespellsystem.api.runner.RuntimeStatement; +import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +@Getter +@RequiredArgsConstructor +public class AffectVarNode extends RuntimeStatement { + + private final @NotNull RuntimeExpression holder; + private final @Nullable RuntimeExpression expression; + + @Override + public void run(@NotNull SpellRuntime runtime) { + //TODO + } +} diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/statements/DeclareVarNode.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/statements/DeclareVarNode.java new file mode 100644 index 00000000..bc31f65c --- /dev/null +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/statements/DeclareVarNode.java @@ -0,0 +1,28 @@ +package fr.jamailun.ultimatespellsystem.plugin.runner.nodes.statements; + +import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; +import fr.jamailun.ultimatespellsystem.api.runner.RuntimeStatement; +import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +@Getter +@RequiredArgsConstructor +public class DeclareVarNode extends RuntimeStatement { + + private final @NotNull String varName; + private final @NotNull Type type; + private final @Nullable RuntimeExpression expression; + + @Override + public void run(@NotNull SpellRuntime runtime) { + Object value = expression == null ? null : expression.evaluate(runtime); + if(value != null) { + //TODO match type ?! + } + runtime.variables().set(varName, value); + } +} diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/StopNode.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/statements/ReturnNode.java similarity index 57% rename from plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/StopNode.java rename to plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/statements/ReturnNode.java index a43ac677..8d6e79e8 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/StopNode.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/statements/ReturnNode.java @@ -1,4 +1,4 @@ -package fr.jamailun.ultimatespellsystem.plugin.runner.nodes.functions; +package fr.jamailun.ultimatespellsystem.plugin.runner.nodes.statements; import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.RuntimeStatement; @@ -7,23 +7,27 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +/** + * A {@code return [expr]} node. + */ @RequiredArgsConstructor -public class StopNode extends RuntimeStatement { +public class ReturnNode extends RuntimeStatement { private final @Nullable RuntimeExpression exitCode; @Override public void run(@NotNull SpellRuntime runtime) { + Object output; if(exitCode == null) { - runtime.stop(0); + output = null; } else { - int code = runtime.safeEvaluate(exitCode, Double.class).intValue(); - runtime.stop(code); + output = exitCode.evaluate(runtime); } + runtime.statementReturn(output); } @Override - public String toString() { - return "STOP("+exitCode+")"; + public @NotNull String toString() { + return "RETURN" + (exitCode == null ? "" : " " + exitCode); } } diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/AbstractStructDefinition.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/AbstractStructDefinition.java index 9ca9ee62..bdd258a9 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/AbstractStructDefinition.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/AbstractStructDefinition.java @@ -1,6 +1,7 @@ package fr.jamailun.ultimatespellsystem.plugin.runner.structs; import com.google.common.base.Preconditions; +import fr.jamailun.ultimatespellsystem.api.runner.structs.StructDefinition; import fr.jamailun.ultimatespellsystem.dsl2.errors.UnknownFieldException; import fr.jamailun.ultimatespellsystem.dsl2.errors.UnknownFunctionException; import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/AbstractStructInstance.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/AbstractStructInstance.java index 2333004b..867a5c72 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/AbstractStructInstance.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/AbstractStructInstance.java @@ -1,5 +1,6 @@ package fr.jamailun.ultimatespellsystem.plugin.runner.structs; +import fr.jamailun.ultimatespellsystem.api.runner.structs.Struct; import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenPosition; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/spells/PropertiesValidator.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/spells/PropertiesValidator.java index 8d9bd0b0..91693629 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/spells/PropertiesValidator.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/spells/PropertiesValidator.java @@ -6,7 +6,7 @@ import fr.jamailun.ultimatespellsystem.api.runner.RuntimeStatement; import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.blocks.*; import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.expressions.PropertiesLiteral; -import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.functions.SummonNode; +import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.functions._old.SummonNode; import lombok.RequiredArgsConstructor; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/spells/functions/SpellFunction.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/spells/functions/SpellFunction.java index c87b5832..d084523f 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/spells/functions/SpellFunction.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/spells/functions/SpellFunction.java @@ -56,7 +56,7 @@ public Object compute(@NotNull List arguments, @NotNull Spell SpellRuntime childRuntime = runtime.makeChild(); for(int i = 0; i < args.size(); i++) { Object arg = arguments.get(i).evaluate(childRuntime); - childRuntime.variables().set(args.get(i).debugName(), arg); + childRuntime.variables().set(args.get(i).name(), arg); } // Execute return executeSteps(childRuntime); diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/utils/holders/PotionEffectHolder.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/utils/holders/PotionEffectHolder.java index fb86fea1..e689537a 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/utils/holders/PotionEffectHolder.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/utils/holders/PotionEffectHolder.java @@ -3,7 +3,7 @@ import fr.jamailun.ultimatespellsystem.UssLogger; import fr.jamailun.ultimatespellsystem.api.runner.errors.InvalidEnumValueException; import fr.jamailun.ultimatespellsystem.api.runner.errors.InvalidTypeException; -import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.functions.SendEffectNode; +import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.functions._old.SendEffectNode; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Duration; import org.bukkit.entity.LivingEntity; import org.bukkit.potion.PotionEffect; diff --git a/plugin/src/test/java/fr/jamailun/ultimatespellsystem/runner/SimpleTest.java b/plugin/src/test/java/fr/jamailun/ultimatespellsystem/runner/SimpleTest.java index d08cd634..ff032a3a 100644 --- a/plugin/src/test/java/fr/jamailun/ultimatespellsystem/runner/SimpleTest.java +++ b/plugin/src/test/java/fr/jamailun/ultimatespellsystem/runner/SimpleTest.java @@ -3,7 +3,7 @@ import fr.jamailun.ultimatespellsystem.api.utils.StringTransformation; import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.expressions.RawLiteral; import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.expressions.VariableNode; -import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.functions.SendMessageNode; +import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.functions._old.SendMessageNode; import fr.jamailun.ultimatespellsystem.runner.framework.TestFramework; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; From db1e8154502f2eed3644a63d046acbd8c2632870 Mon Sep 17 00:00:00 2001 From: "timothe.rosaz" Date: Sat, 1 Nov 2025 18:01:37 +0100 Subject: [PATCH 27/38] It compiles... it's alive --- .../api/runner/SpellRuntime.java | 9 +-- .../api/runner/structs/StructDefinition.java | 21 ++++++ .../dsl2/library/StructDefinition.java | 3 - .../dsl2/library/structs/ConsoleStruct.java | 11 ++-- .../dsl2/library/structs/EntityStruct.java | 15 +++-- .../ultimatespellsystem/dsl2/nodes/Node.java | 4 +- .../expressions/ArrayGetterExpression.java | 2 +- .../expressions/litteral/ArrayLiteral.java | 2 +- .../expressions/litteral/LocationLiteral.java | 2 +- .../expressions/litteral/NullLiteral.java | 2 +- .../expressions/operators/BiOperator.java | 2 +- .../operators/LogicalOperator.java | 2 +- .../expressions/operators/SubOperator.java | 2 +- .../nodes/statements/ReturnStatement.java | 4 +- .../dsl2/nodes/type/Type.java | 17 ++++- .../dsl2/nodes/type/TypePrimitive.java | 26 ++++++-- .../type/variables/VariableDefinition.java | 11 ++-- .../dsl2/objects/CallbackEvent.java | 2 - .../extension/ExtensionLoader.java | 2 - .../extension/functions/AbstractFunction.java | 8 +++ .../functions/AreAlliesFunction.java | 6 +- .../functions/CastSpellFunction.java | 6 +- .../extension/functions/DamageFunction.java | 8 +-- .../functions/DirectionOfFunction.java | 5 +- .../extension/functions/DistanceFunction.java | 5 +- .../functions/EntityHasEffectFunction.java | 7 +- .../functions/GetFoodLevelFunction.java | 4 +- .../functions/GetHealthFunction.java | 40 ----------- .../functions/GetMaxHealthFunction.java | 45 ------------- .../functions/HealEntityFunction.java | 55 ---------------- .../extension/functions/IsValidFunction.java | 3 +- .../functions/KnockbackFunction.java | 10 +-- .../functions/LocationToListFunction.java | 58 ---------------- .../extension/functions/LogFunctions.java | 57 ---------------- .../functions/NormalizeFunction.java | 6 +- .../extension/functions/RandFunction.java | 5 +- .../extension/functions/RandIntFunction.java | 6 +- .../extension/functions/RayCastFunction.java | 8 +-- .../extension/functions/SetAggroFunction.java | 8 +-- .../extension/functions/SetFireFunction.java | 11 ++-- .../functions/SetFoodLevelFunction.java | 6 +- .../extension/functions/SetNameFunction.java | 42 ------------ .../functions/SolidBlockBellowFunction.java | 21 +++--- .../extension/functions/StrikeFunction.java | 4 +- .../plugin/runner/AbstractSpellRuntime.java | 66 ++++++++++++++----- .../plugin/runner/SpellRuntimeImpl.java | 18 +++-- .../runner/builder/ExpressionQueue.java | 2 - .../runner/builder/SpellBuilderVisitor.java | 2 +- .../expressions/_old/EntityTypeLiteral.java | 30 --------- .../expressions/_old/PositionOfNode.java | 52 --------------- .../nodes/functions/_old/DefineNode.java | 45 ------------- .../runner/nodes/operators/RunMathOpe.java | 52 --------------- .../ExpressionWrapperNode.java | 2 +- .../structs/AbstractStructDefinition.java | 7 +- .../structs/AbstractStructInstance.java | 7 ++ .../runner/structs/ConsoleDefinition.java | 8 ++- .../runner/structs/EntityDefinition.java | 8 ++- .../plugin/runner/structs/EntityInstance.java | 4 +- .../plugin/runner/structs/StructsLibrary.java | 33 ++++++++++ .../spells/functions/SpellFunction.java | 7 +- .../functions/AssertNotCalledFunction.java | 12 +--- .../functions/AssertTrueFunction.java | 8 +-- .../framework/functions/PrintFunction.java | 12 +--- 63 files changed, 298 insertions(+), 650 deletions(-) delete mode 100644 plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/GetHealthFunction.java delete mode 100644 plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/GetMaxHealthFunction.java delete mode 100644 plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/HealEntityFunction.java delete mode 100644 plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/LocationToListFunction.java delete mode 100644 plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/LogFunctions.java delete mode 100644 plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/SetNameFunction.java delete mode 100644 plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/expressions/_old/EntityTypeLiteral.java delete mode 100644 plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/expressions/_old/PositionOfNode.java delete mode 100644 plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/_old/DefineNode.java delete mode 100644 plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/RunMathOpe.java rename plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/{expressions/_old => statements}/ExpressionWrapperNode.java (90%) create mode 100644 plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/StructsLibrary.java diff --git a/api/src/main/java/fr/jamailun/ultimatespellsystem/api/runner/SpellRuntime.java b/api/src/main/java/fr/jamailun/ultimatespellsystem/api/runner/SpellRuntime.java index 499fb9cd..2b61d268 100644 --- a/api/src/main/java/fr/jamailun/ultimatespellsystem/api/runner/SpellRuntime.java +++ b/api/src/main/java/fr/jamailun/ultimatespellsystem/api/runner/SpellRuntime.java @@ -38,12 +38,6 @@ public interface SpellRuntime { */ boolean isStopped(); - /** - * Stop the current execution. - * @param exitValue the exit value returned. - */ - void stop(@Nullable Object exitValue); - /** * Break the flow. */ @@ -102,7 +96,8 @@ public interface SpellRuntime { * @param value the value to wrap. * @return {@code null} if cannot match. */ - @Nullable Struct getStructOf(String structDefinitionName, Object value); + @Contract("_,null->null;_,!null->!null") + @Nullable Struct getStructOf(@NotNull String structDefinitionName, @Nullable Object value); /** * Get the returned value. diff --git a/api/src/main/java/fr/jamailun/ultimatespellsystem/api/runner/structs/StructDefinition.java b/api/src/main/java/fr/jamailun/ultimatespellsystem/api/runner/structs/StructDefinition.java index a7c06d67..90809ae8 100644 --- a/api/src/main/java/fr/jamailun/ultimatespellsystem/api/runner/structs/StructDefinition.java +++ b/api/src/main/java/fr/jamailun/ultimatespellsystem/api/runner/structs/StructDefinition.java @@ -16,6 +16,27 @@ */ public interface StructDefinition { + /** + * Get the struct name. + * @return the non-null name. + */ + @NotNull String getName(); + + /** + * Get the DSL type matching the value. + * @return the type equivalence. + */ + default @NotNull Type asType() { + return Type.of(getName()); + } + + /** + * Instantiate the value. + * @param value value to wrap. + * @return a non-null instance. + */ + @NotNull Struct instantiate(S value); + /** * Register a new field on the struct. * @param name the name of the field. If not unique, an exception will be thrown. diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/library/StructDefinition.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/library/StructDefinition.java index 043c4f69..28e4ccfc 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/library/StructDefinition.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/library/StructDefinition.java @@ -14,9 +14,6 @@ @RequiredArgsConstructor public class StructDefinition { - public static final String LAZY_TYPE_LOCATION = "location"; - public static final String LAZY_TYPE_ENTITY = "entity"; - @Getter private final String name; private final Map fields = new HashMap<>(); private final Map functions = new HashMap<>(); diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/library/structs/ConsoleStruct.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/library/structs/ConsoleStruct.java index 79e1767b..28101b6c 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/library/structs/ConsoleStruct.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/library/structs/ConsoleStruct.java @@ -3,6 +3,7 @@ import fr.jamailun.ultimatespellsystem.dsl2.library.StructDefinition; import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionDefinition; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; public class ConsoleStruct extends StructDefinition { @@ -17,27 +18,27 @@ public ConsoleStruct() { private void initFunctions() { registerFunction(FunctionDefinition.of( "send", - TypePrimitive.NULL.asType(), + Type.NULL, FunctionArgument.of(TypePrimitive.STRING) )); registerFunction(FunctionDefinition.of( "info", - TypePrimitive.NULL.asType(), + Type.NULL, FunctionArgument.of(TypePrimitive.STRING) )); registerFunction(FunctionDefinition.of( "debug", - TypePrimitive.NULL.asType(), + Type.NULL, FunctionArgument.of(TypePrimitive.STRING) )); registerFunction(FunctionDefinition.of( "warning", - TypePrimitive.NULL.asType(), + Type.NULL, FunctionArgument.of(TypePrimitive.STRING) )); registerFunction(FunctionDefinition.of( "error", - TypePrimitive.NULL.asType(), + Type.NULL, FunctionArgument.of(TypePrimitive.STRING) )); } diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/library/structs/EntityStruct.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/library/structs/EntityStruct.java index 8d7ce999..98fd6745 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/library/structs/EntityStruct.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/library/structs/EntityStruct.java @@ -3,11 +3,12 @@ import fr.jamailun.ultimatespellsystem.dsl2.library.StructDefinition; import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionDefinition; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; public class EntityStruct extends StructDefinition { - public static final String NAME = "entity"; + public static final String NAME = TypePrimitive.ENTITY.name().toLowerCase(); public EntityStruct() { super(NAME); @@ -18,8 +19,8 @@ public EntityStruct() { private void initFields() { registerField("name", TypePrimitive.STRING); - registerField("location", LAZY_TYPE_LOCATION); - registerField("eye_location", LAZY_TYPE_LOCATION); + registerField("location", TypePrimitive.LOCATION); + registerField("eye_location", TypePrimitive.LOCATION); // Location registerField("x", TypePrimitive.NUMBER); @@ -36,19 +37,19 @@ private void initFields() { private void initFunctions() { registerFunction(FunctionDefinition.of( "teleport", - TypePrimitive.NULL.asType(), - FunctionArgument.of(LAZY_TYPE_LOCATION) + Type.NULL, + FunctionArgument.of(TypePrimitive.LOCATION) )); registerFunction(FunctionDefinition.of( "heal", - TypePrimitive.NULL.asType(), + Type.NULL, FunctionArgument.of(TypePrimitive.NUMBER) )); registerFunction(FunctionDefinition.of( "send_message", - TypePrimitive.NULL.asType(), + Type.NULL, FunctionArgument.of(TypePrimitive.STRING) )); } diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/Node.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/Node.java index dddc3a64..4701a794 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/Node.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/Node.java @@ -30,7 +30,7 @@ public abstract class Node { * @param otherTypes a variadic for other allowed types. */ protected void assertExpressionType(@NotNull ExpressionNode expression, @NotNull CollectionFilter filter, @NotNull TypePrimitive type, TypePrimitive... otherTypes) { - if(expression.getExpressionType().is(TypePrimitive.NULL)) + if(expression.getExpressionType().is(Type.NULL)) return; // Ignore NULL type : it is accepted by everything. List allowed = new ArrayList<>(List.of(otherTypes)); @@ -45,7 +45,7 @@ protected void assertExpressionType(@NotNull ExpressionNode expression, @NotNull } protected void assertExpressionType(@NotNull ExpressionNode expression, @NotNull Type type) { - if(type.is(TypePrimitive.NULL)) + if(type.isNull()) return; // On ignore tlr type null if(!expression.getExpressionType().equals(type)) diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/ArrayGetterExpression.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/ArrayGetterExpression.java index 318ea54f..43a82e9b 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/ArrayGetterExpression.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/ArrayGetterExpression.java @@ -38,7 +38,7 @@ public void validateTypes(@NotNull TypesContext context) { // Array must be a collection array.validateTypes(context); Type typeArray = array.getExpressionType(); - if( ! typeArray.is(TypePrimitive.NULL) && ! typeArray.isCollection()) { + if( ! typeArray.isNull() && ! typeArray.isCollection()) { throw new TypeException(this, "Cannot get the value of a non-array."); } } diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/ArrayLiteral.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/ArrayLiteral.java index 65f7881d..a5d69fce 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/ArrayLiteral.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/ArrayLiteral.java @@ -59,7 +59,7 @@ public void validateTypes(@NotNull TypesContext contextParent) { // Array is empty : type is null as array ? if(elementsType == null) { - elementsType = TypePrimitive.NULL.asType(); + elementsType = Type.NULL; } // Set self type at the end diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/LocationLiteral.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/LocationLiteral.java index 2474a5c3..b91cd234 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/LocationLiteral.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/LocationLiteral.java @@ -41,7 +41,7 @@ public boolean hasYawAndPitch() { @Override public @NotNull Type getExpressionType() { - return Type.of("location"); + return Type.of(TypePrimitive.LOCATION); } @Override diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/NullLiteral.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/NullLiteral.java index 8af74106..374e4ff5 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/NullLiteral.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/NullLiteral.java @@ -24,7 +24,7 @@ public NullLiteral(@NotNull TokenPosition pos) { @Override public @NotNull Type getExpressionType() { - return TypePrimitive.NULL.asType(); + return Type.NULL; } @Override diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/BiOperator.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/BiOperator.java index 44c8689f..ba2691a4 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/BiOperator.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/BiOperator.java @@ -15,7 +15,7 @@ */ public abstract class BiOperator extends Operator { - protected Type producedType = TypePrimitive.NULL.asType(); + protected Type producedType = Type.NULL; protected final ExpressionNode left; protected final ExpressionNode right; diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/LogicalOperator.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/LogicalOperator.java index 95a4755b..09e2f49c 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/LogicalOperator.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/LogicalOperator.java @@ -44,7 +44,7 @@ public void validateTypes(@NotNull Type leftType, @NotNull Type rightType, @NotN } // Only allow same type (but still allow NULL :) ) - if(!(leftType.is(TypePrimitive.NULL) || rightType.is(TypePrimitive.NULL))) { + if(!(leftType.isNull() || rightType.isNull())) { if (!(leftType.equals(rightType))) { throw new TypeException(firstTokenPosition(), "Logical operator " + this + " has unequal types : " + leftType + " and " + rightType + "."); } diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/SubOperator.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/SubOperator.java index 24081462..7fa39e60 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/SubOperator.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/SubOperator.java @@ -32,7 +32,7 @@ public SubOperator(TokenPosition pos, ExpressionNode left, ExpressionNode right) private final static List ALLOWED = List.of( Type.of(TypePrimitive.NUMBER), Type.of(TypePrimitive.DURATION), - Type.of("location") + Type.of(TypePrimitive.LOCATION) ); @Override diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/ReturnStatement.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/ReturnStatement.java index 41fd5c6b..004f081f 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/ReturnStatement.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/ReturnStatement.java @@ -2,9 +2,7 @@ import fr.jamailun.ultimatespellsystem.dsl2.nodes.ExpressionNode; import fr.jamailun.ultimatespellsystem.dsl2.nodes.StatementNode; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.CollectionFilter; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.variables.TypesContext; import fr.jamailun.ultimatespellsystem.dsl2.tokenization.PreviousIndicator; import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenPosition; @@ -35,7 +33,7 @@ public void validateTypes(@NotNull TypesContext context) { public @Nullable Type getReturnType() { if(exitCodeNode != null) return exitCodeNode.getExpressionType(); - return Type.of(TypePrimitive.NULL); + return Type.NULL; } @Override diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/Type.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/Type.java index 4f05990c..4ec22637 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/Type.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/Type.java @@ -15,24 +15,35 @@ public class Type { private final @Nullable TypePrimitive primitive; private final @Nullable String objectClass; + private final boolean isNull; private final int arrayLevel; + /** + * The null value. + */ + public static final Type NULL = new Type(null, null, 0); + public Type(@NotNull TypePrimitive primitive, int arrayLevel) { this.primitive = primitive; this.objectClass = null; this.arrayLevel = arrayLevel; + this.isNull = false; } public Type(@NotNull String objectClass, int arrayLevel) { this.primitive = null; this.objectClass = objectClass; this.arrayLevel = arrayLevel; + this.isNull = false; } private Type(@Nullable TypePrimitive primitive, @Nullable String objectClass, int arrayLevel) { this.primitive = primitive; this.objectClass = objectClass; this.arrayLevel = arrayLevel; + this.isNull = (primitive == null && objectClass == null); + if(isNull && arrayLevel > 0) + throw new IllegalArgumentException("Cannot create a NULL type with an array value."); } /** @@ -57,12 +68,16 @@ public boolean is(@NotNull String objectClass) { return this.objectClass != null && this.objectClass.equals(objectClass); } + public boolean is(@NotNull Type type) { + return this.equals(type); + } + public boolean isCollection() { return arrayLevel > 0; } public boolean isNull() { - return is(TypePrimitive.NULL); + return isNull; } public boolean isPrimitive() { diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/TypePrimitive.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/TypePrimitive.java index 182c7486..859e3395 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/TypePrimitive.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/TypePrimitive.java @@ -1,11 +1,13 @@ package fr.jamailun.ultimatespellsystem.dsl2.nodes.type; +import org.bukkit.Location; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.HashMap; import java.util.Map; +import java.util.Vector; /** * Enumeration of a possible types. @@ -25,10 +27,14 @@ public enum TypePrimitive { /** A temporal duration. */ DURATION(Duration.class), - MAP(Map.class), + ENTITY, - /** A {@code null} value. */ - NULL; + LOCATION(Location.class), + + VECTOR(Vector.class), + + MAP(Map.class) + ; public final Class clazz; @@ -68,7 +74,6 @@ public enum TypePrimitive { case "number", "double", "float", "integer", "int", "short", "byte" -> NUMBER; case "boolean", "bool" -> BOOLEAN; case "duration", "time", "chrono" -> DURATION; - case "null", "void" -> NULL; case "map", "data", "properties", "properties-set", "properties_set" -> MAP; default -> null; }; @@ -83,4 +88,17 @@ public enum TypePrimitive { return map; } + public boolean canImplicitCastTo(@NotNull TypePrimitive other) { + if(this == other || this == STRING) return true; + + return switch (other) { + case STRING -> true; + // location required ? we can always get it from the entity. + case LOCATION -> this == ENTITY; + // Vector needed ? We can still get it from the location / entity + case VECTOR -> this == LOCATION || this == ENTITY; + default -> false; + }; + } + } diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/variables/VariableDefinition.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/variables/VariableDefinition.java index 057540bb..a0f36e5c 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/variables/VariableDefinition.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/variables/VariableDefinition.java @@ -1,7 +1,6 @@ package fr.jamailun.ultimatespellsystem.dsl2.nodes.type.variables; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; import lombok.RequiredArgsConstructor; import org.jetbrains.annotations.NotNull; @@ -32,7 +31,7 @@ public void register(@NotNull VariableReference reference) { /** * Get the representation type of this variable. * @param context current context. - * @return a {@link TypePrimitive#NULL} type if unset. + * @return a {@link Type#NULL} type if unset. */ public @NotNull Type getType(@NotNull TypesContext context) { if(computedType != null) return computedType; @@ -40,20 +39,20 @@ public void register(@NotNull VariableReference reference) { // We need ot compute the type for(VariableReference reference : references) { Type type = reference.getType(context); - if(type.is(TypePrimitive.NULL) && !type.isCollection()) { + if(type.isNull() && !type.isCollection()) { // Nothing here continue; } - if(computedType == null || computedType.is(TypePrimitive.NULL)) { + if(computedType == null || computedType.isNull()) { computedType = type; // We CAN overload a variable that as NULL. - } else if(!computedType.is(TypePrimitive.NULL) && ! computedType.equals(type)) { + } else if(!computedType.isNull() && ! computedType.equals(type)) { throw reference.exception("Cannot change type of an already defined variable (%"+name+"). Previous type: " + computedType + ", new type: " + type + "."); } } // If type not set, then it's a NULL. - return Objects.requireNonNullElseGet(computedType, TypePrimitive.NULL::asType); + return Objects.requireNonNullElse(computedType, Type.NULL); } } diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/objects/CallbackEvent.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/objects/CallbackEvent.java index f8f14bbd..f9089593 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/objects/CallbackEvent.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/objects/CallbackEvent.java @@ -50,8 +50,6 @@ public record CallbackArgument(@NotNull TokenType keyword, @NotNull TypePrimitiv public CallbackArgument { if(!keyword.letters) throw new RuntimeException("Invalid keyword type. Should be a 'letters' keyword."); - if(type == TypePrimitive.NULL) - throw new RuntimeException("Invalid callback argument type. Cannot be null."); } } diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/ExtensionLoader.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/ExtensionLoader.java index 9bcd1fa0..22e71d30 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/ExtensionLoader.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/ExtensionLoader.java @@ -55,14 +55,12 @@ public static synchronized void loadStatic() { JavaFunctionProvider.instance().registerFunction(new GetHealthFunction()); JavaFunctionProvider.instance().registerFunction(new GetMaxHealthFunction()); JavaFunctionProvider.instance().registerFunction(new HealEntityFunction(), "heal_entity"); - JavaFunctionProvider.instance().registerFunction(new LocationToListFunction()); JavaFunctionProvider.instance().registerFunction(new AreAlliesFunction()); JavaFunctionProvider.instance().registerFunction(new EntityHasEffectFunction(), "entity_has_potion_effect", "has_potion_effect", "has_effect"); JavaFunctionProvider.instance().registerFunction(new SetAggroFunction()); JavaFunctionProvider.instance().registerFunction(new GetFoodLevelFunction()); JavaFunctionProvider.instance().registerFunction(new SetFoodLevelFunction()); JavaFunctionProvider.instance().registerFunction(new SolidBlockBellowFunction()); - LogFunctions.register(); // Others EntityAttributes.register(); diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/AbstractFunction.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/AbstractFunction.java index 9a80ab76..6512bd96 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/AbstractFunction.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/AbstractFunction.java @@ -6,6 +6,7 @@ import fr.jamailun.ultimatespellsystem.api.runner.errors.InvalidTypeException; import fr.jamailun.ultimatespellsystem.api.runner.functions.RunnableJavaFunction; import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Duration; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; import fr.jamailun.ultimatespellsystem.plugin.entities.BukkitSpellEntity; import org.bukkit.Location; @@ -76,4 +77,11 @@ protected double toDouble(@NotNull String context, @NotNull RuntimeExpression ex return n.doubleValue(); } + protected @NotNull Duration toDuration(@NotNull String context, @NotNull RuntimeExpression expression, @NotNull SpellRuntime runtime) { + Object raw = expression.evaluate(runtime); + if(raw instanceof Duration dur) + return dur; + throw new InvalidTypeException(context, "Duration", raw); + } + } diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/AreAlliesFunction.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/AreAlliesFunction.java index 65f38d56..57e88173 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/AreAlliesFunction.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/AreAlliesFunction.java @@ -5,7 +5,7 @@ import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionType; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; import org.jetbrains.annotations.NotNull; @@ -26,11 +26,11 @@ public AreAlliesFunction() { // - b : entity 2 List.of( new FunctionArgument( - FunctionType.accept(TypePrimitive.ENTITY), + Type.of(TypePrimitive.ENTITY), "first-entity", false ), new FunctionArgument( - FunctionType.accept(TypePrimitive.ENTITY), + Type.of(TypePrimitive.ENTITY), "second-entity", false ) ) diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/CastSpellFunction.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/CastSpellFunction.java index cfa36338..00966df5 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/CastSpellFunction.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/CastSpellFunction.java @@ -7,7 +7,7 @@ import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; import fr.jamailun.ultimatespellsystem.api.runner.errors.UnknownFunctionException; import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionType; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; import org.jetbrains.annotations.NotNull; @@ -28,11 +28,11 @@ public CastSpellFunction() { // - spell : the spell ID List.of( new FunctionArgument( - FunctionType.accept(TypePrimitive.ENTITY), + Type.of(TypePrimitive.ENTITY), "caster", false ), new FunctionArgument( - FunctionType.accept(TypePrimitive.STRING), + Type.of(TypePrimitive.STRING), "spell", false ) ) diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/DamageFunction.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/DamageFunction.java index f85a8df6..60cdc628 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/DamageFunction.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/DamageFunction.java @@ -4,7 +4,7 @@ import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionType; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; import org.bukkit.Bukkit; import org.bukkit.entity.LivingEntity; @@ -26,15 +26,15 @@ public DamageFunction() { // Args : the location to strike List.of( new FunctionArgument( - FunctionType.accept(TypePrimitive.ENTITY), + Type.of(TypePrimitive.ENTITY), "target", false ), new FunctionArgument( - FunctionType.accept(TypePrimitive.NUMBER), + Type.of(TypePrimitive.NUMBER), "amount", false ), new FunctionArgument( - FunctionType.accept(TypePrimitive.ENTITY), + Type.of(TypePrimitive.ENTITY), "author", true ) ) diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/DirectionOfFunction.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/DirectionOfFunction.java index 65a5e487..5d91c96d 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/DirectionOfFunction.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/DirectionOfFunction.java @@ -3,7 +3,6 @@ import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionType; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; import org.bukkit.Location; import org.bukkit.entity.LivingEntity; @@ -20,11 +19,11 @@ public DirectionOfFunction() { super( "direction_of", // Returns "vector" - TypePrimitive.LOCATION.asType(), + TypePrimitive.VECTOR.asType(), // Args : the entity to read direction of List.of( new FunctionArgument( - FunctionType.accept(TypePrimitive.ENTITY), + TypePrimitive.ENTITY.asType(), "entity", false ) ) diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/DistanceFunction.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/DistanceFunction.java index df82e7da..d50a0d06 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/DistanceFunction.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/DistanceFunction.java @@ -3,7 +3,6 @@ import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionType; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; import org.bukkit.Location; import org.jetbrains.annotations.NotNull; @@ -25,11 +24,11 @@ public DistanceFunction() { // - b : location B List.of( new FunctionArgument( - FunctionType.accept(TypePrimitive.LOCATION, TypePrimitive.ENTITY), + TypePrimitive.LOCATION.asType(), "a", false ), new FunctionArgument( - FunctionType.accept(TypePrimitive.LOCATION, TypePrimitive.ENTITY), + TypePrimitive.LOCATION.asType(), "b", false ) ) diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/EntityHasEffectFunction.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/EntityHasEffectFunction.java index 749f3af5..5d35a121 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/EntityHasEffectFunction.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/EntityHasEffectFunction.java @@ -4,7 +4,6 @@ import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionType; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.functions._old.SendEffectNode; import org.bukkit.entity.LivingEntity; @@ -27,15 +26,15 @@ public EntityHasEffectFunction() { // Args : entity, effect, [min level] List.of( new FunctionArgument( - FunctionType.accept(TypePrimitive.ENTITY), + TypePrimitive.ENTITY.asType(), "entity", false ), new FunctionArgument( - FunctionType.accept(TypePrimitive.STRING, TypePrimitive.CUSTOM), + TypePrimitive.STRING.asType(), "effect", false ), new FunctionArgument( - FunctionType.accept(TypePrimitive.NUMBER), + TypePrimitive.NUMBER.asType(), "level", true ) ) diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/GetFoodLevelFunction.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/GetFoodLevelFunction.java index 85faf9f0..2357388d 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/GetFoodLevelFunction.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/GetFoodLevelFunction.java @@ -3,7 +3,7 @@ import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionType; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; import org.bukkit.entity.HumanEntity; import org.bukkit.entity.LivingEntity; @@ -24,7 +24,7 @@ public GetFoodLevelFunction() { // Args : the entity to get health from List.of( new FunctionArgument( - FunctionType.accept(TypePrimitive.ENTITY), + Type.of(TypePrimitive.ENTITY), "entity", false ) ) diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/GetHealthFunction.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/GetHealthFunction.java deleted file mode 100644 index 0fb8f8d9..00000000 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/GetHealthFunction.java +++ /dev/null @@ -1,40 +0,0 @@ -package fr.jamailun.ultimatespellsystem.extension.functions; - -import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; -import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionType; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; -import org.bukkit.entity.LivingEntity; -import org.jetbrains.annotations.NotNull; - -import java.util.List; - -/** - * get the health of an entity - */ -public class GetHealthFunction extends AbstractFunction { - - public GetHealthFunction() { - super( - "get_health", - // Returns the health value - TypePrimitive.NUMBER.asType(), - // Args : the entity to get health from - List.of( - new FunctionArgument( - FunctionType.accept(TypePrimitive.ENTITY), - "entity", false - ) - ) - ); - } - - @Override - public Double compute(@NotNull List arguments, @NotNull SpellRuntime runtime) { - LivingEntity target = toLivingEntity("get_health:entity", arguments.getFirst(), runtime); - if(target == null) - return 0d; - return target.getHealth(); - } -} diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/GetMaxHealthFunction.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/GetMaxHealthFunction.java deleted file mode 100644 index 69c1995d..00000000 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/GetMaxHealthFunction.java +++ /dev/null @@ -1,45 +0,0 @@ -package fr.jamailun.ultimatespellsystem.extension.functions; - -import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; -import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionType; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; -import org.bukkit.attribute.Attribute; -import org.bukkit.attribute.AttributeInstance; -import org.bukkit.entity.LivingEntity; -import org.jetbrains.annotations.NotNull; - -import java.util.List; -import java.util.Optional; - -/** - * Get the maximum health of a bukkit entity. - */ -public class GetMaxHealthFunction extends AbstractFunction { - - public GetMaxHealthFunction() { - super( - "get_max_health", - // Returns the health value - TypePrimitive.NUMBER.asType(), - // Args : the entity to get health from - List.of( - new FunctionArgument( - FunctionType.accept(TypePrimitive.ENTITY), - "entity", false - ) - ) - ); - } - - @Override - public Double compute(@NotNull List arguments, @NotNull SpellRuntime runtime) { - LivingEntity target = toLivingEntity("get_max_health:entity", arguments.getFirst(), runtime); - if(target == null) - return 0d; - return Optional.ofNullable(target.getAttribute(Attribute.GENERIC_MAX_HEALTH)) - .map(AttributeInstance::getValue) - .orElse(0d); - } -} diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/HealEntityFunction.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/HealEntityFunction.java deleted file mode 100644 index 6705b811..00000000 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/HealEntityFunction.java +++ /dev/null @@ -1,55 +0,0 @@ -package fr.jamailun.ultimatespellsystem.extension.functions; - -import fr.jamailun.ultimatespellsystem.api.events.EntityHealedBySpellEvent; -import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; -import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionType; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; -import org.bukkit.Bukkit; -import org.bukkit.entity.LivingEntity; -import org.jetbrains.annotations.NotNull; - -import java.util.List; - -/** - * Heal an entity. - */ -public class HealEntityFunction extends AbstractFunction { - - public HealEntityFunction() { - super( - "heal", - // Returns new health - TypePrimitive.NUMBER.asType(), - // Args : the entity to heal, and the amount - List.of( - new FunctionArgument( - FunctionType.accept(TypePrimitive.ENTITY), - "entity", false - ), - new FunctionArgument( - FunctionType.accept(TypePrimitive.NUMBER), - "amount", false - ) - ) - ); - } - - @Override - public Double compute(@NotNull List arguments, @NotNull SpellRuntime runtime) { - LivingEntity target = toLivingEntity("heal:entity", arguments.get(0), runtime); - double amount = toDouble("heal:amount", arguments.get(1), runtime); - if(target == null) - return 0d; - - // Heal with an event - var event = new EntityHealedBySpellEvent(target, runtime.getCaster(), runtime.getSpell(), amount); - Bukkit.getPluginManager().callEvent(event); - if(!event.isCancelled()) { - target.heal(amount); - } - - return target.getHealth(); - } -} diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/IsValidFunction.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/IsValidFunction.java index 85a3a6e6..5032e130 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/IsValidFunction.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/IsValidFunction.java @@ -5,7 +5,6 @@ import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; import fr.jamailun.ultimatespellsystem.api.runner.errors.InvalidTypeException; import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionType; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; import org.bukkit.entity.Entity; import org.jetbrains.annotations.NotNull; @@ -25,7 +24,7 @@ public IsValidFunction() { // Args : the entity tio check. List.of( new FunctionArgument( - FunctionType.accept(TypePrimitive.ENTITY), + TypePrimitive.ENTITY.asType(), "entity", false ) ) diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/KnockbackFunction.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/KnockbackFunction.java index c9cfa719..96f1438c 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/KnockbackFunction.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/KnockbackFunction.java @@ -5,7 +5,7 @@ import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionType; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; import fr.jamailun.ultimatespellsystem.plugin.utils.TypeInterpretation; import org.bukkit.util.Vector; @@ -22,22 +22,22 @@ public KnockbackFunction() { super( "knockback", // Returns nothing - TypePrimitive.NULL.asType(), + Type.NULL, // Args : // - entity : entity to knockback // - vector : velocity to apply. // - optional LENGTH List.of( new FunctionArgument( - FunctionType.accept(TypePrimitive.ENTITY), + Type.of(TypePrimitive.ENTITY), "entity", false ), new FunctionArgument( - FunctionType.accept(TypePrimitive.LOCATION, TypePrimitive.NUMBER), + Type.of(TypePrimitive.VECTOR), "velocity", false ), new FunctionArgument( - FunctionType.accept(TypePrimitive.NUMBER), + Type.of(TypePrimitive.NUMBER), "length", true ) ) diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/LocationToListFunction.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/LocationToListFunction.java deleted file mode 100644 index e26e17be..00000000 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/LocationToListFunction.java +++ /dev/null @@ -1,58 +0,0 @@ -package fr.jamailun.ultimatespellsystem.extension.functions; - -import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; -import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; -import fr.jamailun.ultimatespellsystem.api.runner.errors.InvalidTypeException; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionType; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; -import org.bukkit.Location; -import org.jetbrains.annotations.NotNull; - -import java.util.ArrayList; -import java.util.List; - -/** - * Transform a location to a vector. - */ -public class LocationToListFunction extends AbstractFunction { - - public LocationToListFunction() { - super( - "loc_to_list", - // Returns true if success - TypePrimitive.NUMBER.asType(true), - // Args : the location to strike - List.of( - new FunctionArgument( - FunctionType.accept(TypePrimitive.LOCATION, TypePrimitive.NUMBER), - "location", false - ) - ) - ); - } - - @Override - public Object compute(@NotNull List arguments, @NotNull SpellRuntime runtime) { - Object arg = arguments.getFirst().evaluate(runtime); - if(arg instanceof Location loc) { - return List.of(loc.getX(), loc.getY(), loc.getZ()); - } else if(arg instanceof List list) { - List output = new ArrayList<>(); - for(Object obj : list) { - if(!(obj instanceof Double d)) - throw new InvalidTypeException("loc_to_list:loc", "got a list with a non-number: " + obj); - // Add the double. - output.add(d); - if(output.size() == 3) - break; - } - // Fill with 0 if needed - for(int i = output.size(); i < 3; i++) output.add(0d); - return output; - } else if(arg instanceof Double) { - throw new InvalidTypeException("loc_to_list:loc", "the argument must be a LIST of numbers, not just a single number."); - } - throw new InvalidTypeException("loc_to_list:loc", "location/number[]", arg); - } -} diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/LogFunctions.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/LogFunctions.java deleted file mode 100644 index fa7b0120..00000000 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/LogFunctions.java +++ /dev/null @@ -1,57 +0,0 @@ -package fr.jamailun.ultimatespellsystem.extension.functions; - -import fr.jamailun.ultimatespellsystem.UssLogger; -import fr.jamailun.ultimatespellsystem.api.providers.JavaFunctionProvider; -import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; -import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionType; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; -import org.jetbrains.annotations.NotNull; - -import java.util.List; -import java.util.Objects; -import java.util.function.Consumer; - -public abstract class LogFunctions extends AbstractFunction { - - private final Consumer function; - protected LogFunctions(String id, Consumer function) { - super(id, TypePrimitive.NULL.asType(), List.of(new FunctionArgument(FunctionType.accept(TypePrimitive.STRING), "str", false))); - this.function = function; - } - @Override - public final Void compute(@NotNull List arguments, @NotNull SpellRuntime runtime) { - function.accept(Objects.toString(arguments.getFirst().evaluate(runtime))); - return null; - } - - public static void register() { - JavaFunctionProvider.instance().registerFunction(new LogInfoFunction()); - JavaFunctionProvider.instance().registerFunction(new LogWarnFunction()); - JavaFunctionProvider.instance().registerFunction(new LogDebugFunction()); - JavaFunctionProvider.instance().registerFunction(new LogErrorFunction()); - } - - public static class LogInfoFunction extends LogFunctions { - public LogInfoFunction() { - super("INFO", UssLogger::logInfo); - } - } - public static class LogWarnFunction extends LogFunctions { - public LogWarnFunction() { - super("WARN", UssLogger::logWarning); - } - } - public static class LogDebugFunction extends LogFunctions { - public LogDebugFunction() { - super("DEBUG", UssLogger::logDebug); - } - } - public static class LogErrorFunction extends LogFunctions { - public LogErrorFunction() { - super("ERROR", UssLogger::logError); - } - } - -} diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/NormalizeFunction.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/NormalizeFunction.java index cc98c19c..0e2b54a0 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/NormalizeFunction.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/NormalizeFunction.java @@ -3,7 +3,7 @@ import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionType; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; import fr.jamailun.ultimatespellsystem.plugin.utils.TypeInterpretation; import org.jetbrains.annotations.NotNull; @@ -19,12 +19,12 @@ public NormalizeFunction() { super( "normalize", // Returns nothing - TypePrimitive.LOCATION.asType(), + TypePrimitive.VECTOR.asType(), // Args : // location-vector to normalize List.of( new FunctionArgument( - FunctionType.accept(TypePrimitive.LOCATION), + Type.of(TypePrimitive.VECTOR), "vector", false ) ) diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/RandFunction.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/RandFunction.java index 38398e1c..c01f2e66 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/RandFunction.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/RandFunction.java @@ -3,7 +3,6 @@ import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionType; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; import org.jetbrains.annotations.NotNull; @@ -27,11 +26,11 @@ public RandFunction() { // - upper bound List.of( new FunctionArgument( - FunctionType.accept(TypePrimitive.NUMBER), + TypePrimitive.NUMBER.asType(), "lower_bound", false ), new FunctionArgument( - FunctionType.accept(TypePrimitive.NUMBER), + TypePrimitive.NUMBER.asType(), "upper_bound", false ) ) diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/RandIntFunction.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/RandIntFunction.java index 5d203446..63f54a65 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/RandIntFunction.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/RandIntFunction.java @@ -3,7 +3,7 @@ import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionType; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; import org.jetbrains.annotations.NotNull; @@ -27,11 +27,11 @@ public RandIntFunction() { // - upper bound List.of( new FunctionArgument( - FunctionType.accept(TypePrimitive.NUMBER), + Type.of(TypePrimitive.NUMBER), "lower_bound", false ), new FunctionArgument( - FunctionType.accept(TypePrimitive.NUMBER), + Type.of(TypePrimitive.NUMBER), "upper_bound", false ) ) diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/RayCastFunction.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/RayCastFunction.java index 2346a42f..82056924 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/RayCastFunction.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/RayCastFunction.java @@ -5,7 +5,7 @@ import fr.jamailun.ultimatespellsystem.api.runner.errors.InvalidTypeException; import fr.jamailun.ultimatespellsystem.api.entities.SpellEntity; import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionType; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; import org.bukkit.FluidCollisionMode; import org.bukkit.Location; @@ -31,15 +31,15 @@ public RayCastFunction() { // - max : max travel distance List.of( new FunctionArgument( - FunctionType.accept(TypePrimitive.LOCATION, TypePrimitive.ENTITY), + Type.of(TypePrimitive.LOCATION), "source", false ), new FunctionArgument( - FunctionType.accept(TypePrimitive.NUMBER, TypePrimitive.NULL, TypePrimitive.LOCATION, TypePrimitive.ENTITY), + Type.of(TypePrimitive.VECTOR), "direction", false ), new FunctionArgument( - FunctionType.accept(TypePrimitive.NUMBER), + Type.of(TypePrimitive.NUMBER), "max", false ) ) diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/SetAggroFunction.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/SetAggroFunction.java index 500dec13..54dc241a 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/SetAggroFunction.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/SetAggroFunction.java @@ -3,7 +3,7 @@ import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionType; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Mob; @@ -19,14 +19,14 @@ public class SetAggroFunction extends AbstractFunction { public SetAggroFunction() { super( "set_aggro", - TypePrimitive.NULL.asType(), + Type.NULL, List.of( new FunctionArgument( - FunctionType.accept(TypePrimitive.ENTITY), + Type.of("entity"), "entity", false ), new FunctionArgument( - FunctionType.accept(TypePrimitive.ENTITY), + Type.of("entity"), "target", false ) ) diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/SetFireFunction.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/SetFireFunction.java index 862df6c3..2d37e651 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/SetFireFunction.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/SetFireFunction.java @@ -3,8 +3,9 @@ import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionType; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Duration; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; import org.bukkit.entity.LivingEntity; import org.jetbrains.annotations.NotNull; @@ -23,11 +24,11 @@ public SetFireFunction() { // Args : the entity to set on fire List.of( new FunctionArgument( - FunctionType.accept(TypePrimitive.ENTITY), + Type.of(TypePrimitive.ENTITY), "entity", false ), new FunctionArgument( - FunctionType.accept(TypePrimitive.NUMBER), + Type.of(TypePrimitive.DURATION), "ticks", false ) ) @@ -39,8 +40,8 @@ public Object compute(@NotNull List arguments, @NotNull Spell LivingEntity entity = toLivingEntity("set_fire:entity", arguments.getFirst(), runtime); if(entity == null) return false; - int ticks = toInteger("set_fire:ticks", arguments.get(1), runtime); - entity.setFireTicks(ticks); + Duration duration = toDuration("set_fire:ticks", arguments.get(1), runtime); + entity.setFireTicks((int) duration.toTicks()); return true; } diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/SetFoodLevelFunction.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/SetFoodLevelFunction.java index 20b3dcdf..248d0af0 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/SetFoodLevelFunction.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/SetFoodLevelFunction.java @@ -3,7 +3,7 @@ import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionType; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; import org.bukkit.entity.HumanEntity; import org.bukkit.entity.LivingEntity; @@ -24,11 +24,11 @@ public SetFoodLevelFunction() { // Args : the entity to set on fire List.of( new FunctionArgument( - FunctionType.accept(TypePrimitive.ENTITY), + Type.of(TypePrimitive.ENTITY), "entity", false ), new FunctionArgument( - FunctionType.accept(TypePrimitive.NUMBER), + Type.of(TypePrimitive.NUMBER), "amount", false ) ) diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/SetNameFunction.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/SetNameFunction.java deleted file mode 100644 index 57bd38c4..00000000 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/SetNameFunction.java +++ /dev/null @@ -1,42 +0,0 @@ -package fr.jamailun.ultimatespellsystem.extension.functions; - -import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; -import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionType; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; -import org.bukkit.entity.LivingEntity; -import org.jetbrains.annotations.NotNull; - -import java.util.List; - -/** - * Set the custom name of an entity. - */ -public class SetNameFunction extends AbstractFunction { - - public SetNameFunction() { - super( - "set_name", - TypePrimitive.NULL.asType(), - List.of( - new FunctionArgument( - FunctionType.accept(TypePrimitive.ENTITY), - "entity", false - ), - new FunctionArgument( - FunctionType.accept(TypePrimitive.STRING), - "name", false - ) - ) - ); - } - - @Override - public Void compute(@NotNull List arguments, @NotNull SpellRuntime runtime) { - LivingEntity entity = toLivingEntity("v:entity", arguments.get(0), runtime); - String value = runtime.safeEvaluate(arguments.get(1), String.class); - entity.setCustomName(value); - return null; - } -} diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/SolidBlockBellowFunction.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/SolidBlockBellowFunction.java index da2c361f..8975b2e8 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/SolidBlockBellowFunction.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/SolidBlockBellowFunction.java @@ -3,11 +3,10 @@ import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionType; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; import org.bukkit.Location; import org.bukkit.block.Block; -import org.bukkit.entity.LivingEntity; import org.jetbrains.annotations.NotNull; import java.util.List; @@ -20,8 +19,8 @@ public SolidBlockBellowFunction() { TypePrimitive.LOCATION.asType(), List.of( new FunctionArgument( - FunctionType.accept(TypePrimitive.ENTITY), - "entity", false + Type.of(TypePrimitive.LOCATION), + "location", false ) ) ); @@ -29,14 +28,14 @@ public SolidBlockBellowFunction() { @Override public Location compute(@NotNull List arguments, @NotNull SpellRuntime runtime) { - LivingEntity entity = toLivingEntity("block_below:entity", arguments.getFirst(), runtime); - if(entity == null) return null; - int worldMinY = entity.getWorld().getMinHeight(); - int x = entity.getLocation().getBlockX(); - int z = entity.getLocation().getBlockZ(); + Location location = toLocation("block_below:entity", arguments.getFirst(), runtime); - for(int y = entity.getLocation().getBlockY(); y >= worldMinY; y--) { - Block block = entity.getWorld().getBlockAt(x, y, z); + int worldMinY = location.getWorld().getMinHeight(); + int x = location.getBlockX(); + int z = location.getBlockZ(); + + for(int y = location.getBlockY(); y >= worldMinY; y--) { + Block block = location.getWorld().getBlockAt(x, y, z); if( !block.isEmpty() && !block.isPassable()) { return block.getLocation(); } diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/StrikeFunction.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/StrikeFunction.java index 4a5f008e..c7cb0025 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/StrikeFunction.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/functions/StrikeFunction.java @@ -3,7 +3,7 @@ import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionType; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; import org.bukkit.Location; import org.jetbrains.annotations.NotNull; @@ -23,7 +23,7 @@ public StrikeFunction() { // Args : the location to strike List.of( new FunctionArgument( - FunctionType.accept(TypePrimitive.ENTITY, TypePrimitive.LOCATION), + Type.of(TypePrimitive.LOCATION), "target", false ) ) diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/AbstractSpellRuntime.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/AbstractSpellRuntime.java index 501f01a1..cf48fcd1 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/AbstractSpellRuntime.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/AbstractSpellRuntime.java @@ -4,8 +4,11 @@ import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; import fr.jamailun.ultimatespellsystem.api.runner.VariablesSet; +import fr.jamailun.ultimatespellsystem.api.runner.structs.Struct; import fr.jamailun.ultimatespellsystem.api.spells.Spell; +import fr.jamailun.ultimatespellsystem.plugin.runner.structs.StructsLibrary; import lombok.Getter; +import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -17,25 +20,33 @@ */ public abstract class AbstractSpellRuntime implements SpellRuntime { + protected final Map cachedStructures = new HashMap<>(); + protected final StructsLibrary structsLibrary; protected final VariablesSet variables; protected final ExitCode exitCode; @Getter protected final Spell spell; protected boolean flagBreak = false; protected boolean flagContinue = false; + protected final boolean inFunction; - AbstractSpellRuntime(@NotNull AbstractSpellRuntime parent) { + AbstractSpellRuntime(@NotNull AbstractSpellRuntime parent, boolean inFunction) { exitCode = parent.exitCode; variables = parent.variables.inherit(); flagContinue = parent.flagContinue; flagBreak = parent.flagBreak; spell = parent.spell; + cachedStructures.putAll(parent.cachedStructures); + this.inFunction = inFunction; + structsLibrary = parent.structsLibrary; } AbstractSpellRuntime(@NotNull ExitCode exitCode, @Nullable Spell spell) { this.exitCode = exitCode; variables = new VariablesSetImpl(); this.spell = spell; + this.structsLibrary = new StructsLibrary(); + inFunction = false; } @Override @@ -83,25 +94,13 @@ public boolean isStopped() { } @Override - public void stop(int exitCode) { - this.exitCode.set(exitCode); + public @Nullable Object getReturnedValue() { + return exitCode.getValue(); } @Override - public int getFinalExitCode() { - return exitCode.getCode(); - } - - @Getter - public static class ExitCode { - private int code = 0; - private boolean set = false; - public void set(int value) { - if(!set) { - set = true; - code = value; - } - } + public void statementReturn(@Nullable Object value) { + exitCode.set(value); } @Override @@ -131,4 +130,37 @@ public void acceptContinue() { return FlowState.RUNNING; } + @Override + public @Nullable Struct getStructOf(@NotNull String structName, @Nullable Object value) { + if(value == null) return null; + + StructPtr ptr = StructPtr.of(structName, value); + return cachedStructures.computeIfAbsent(ptr, x -> + structsLibrary.instantiate(structName, value) + ); + } + + // ---- utils + + @Getter + public static class ExitCode { + private Object value; + private boolean set = false; + public void set(Object value) { + if(!set) { + set = true; + this.value = value; + } + } + } + + protected record StructPtr( + String structName, + int objHash + ) { + @Contract("_, _ -> new") + static @NotNull StructPtr of(String structName, Object object) { + return new StructPtr(structName, Objects.hashCode(object)); + } + } } diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/SpellRuntimeImpl.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/SpellRuntimeImpl.java index 5f3e1b58..a88f2f8d 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/SpellRuntimeImpl.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/SpellRuntimeImpl.java @@ -17,6 +17,11 @@ public final class SpellRuntimeImpl extends AbstractSpellRuntime { private final SpellEntity caster; + /** + * Create a new context. + * @param caster bukkit-implementation of the caster. + * @param spell spell to use. + */ public SpellRuntimeImpl(@NotNull LivingEntity caster, @Nullable Spell spell) { this(new BukkitSpellEntity(caster), spell); } @@ -24,6 +29,7 @@ public SpellRuntimeImpl(@NotNull LivingEntity caster, @Nullable Spell spell) { /** * Create a new context. * @param caster the caster to declare. + * @param spell spell to use. */ public SpellRuntimeImpl(@NotNull SpellEntity caster, @Nullable Spell spell) { super(new ExitCode(), spell); @@ -31,19 +37,19 @@ public SpellRuntimeImpl(@NotNull SpellEntity caster, @Nullable Spell spell) { variables.set("caster", caster); } - private SpellRuntimeImpl(@NotNull SpellRuntimeImpl parent) { - super(parent); - this.caster = parent.caster; + private SpellRuntimeImpl(@NotNull SpellRuntimeImpl parent, @NotNull SpellEntity caster, boolean inFunction) { + super(parent, inFunction); + this.caster = caster; } @Override - public @NotNull SpellRuntime makeChild() { - return makeChildNewCaster(caster); + public @NotNull SpellRuntime makeChild(boolean inFunction) { + return new SpellRuntimeImpl(this, caster, inFunction); } @Override public @NotNull SpellRuntime makeChildNewCaster(@NotNull SpellEntity newCaster) { - return new SpellRuntimeImpl(this); + return new SpellRuntimeImpl(this, newCaster, false); } @Override diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/builder/ExpressionQueue.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/builder/ExpressionQueue.java index fa0f8e62..5452c106 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/builder/ExpressionQueue.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/builder/ExpressionQueue.java @@ -127,8 +127,6 @@ public void handleMonoOperator(@NotNull MonoOperator operator) { RuntimeExpression child = evaluate(operator.getChild()); if(operator.getType() == MonoOperator.MonoOpeType.NOT) { add(new RunNotOpe(child)); - } else { - add(new RunMathOpe(child, operator.getType())); } } diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/builder/SpellBuilderVisitor.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/builder/SpellBuilderVisitor.java index ba77d5b8..e3c3aed5 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/builder/SpellBuilderVisitor.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/builder/SpellBuilderVisitor.java @@ -2,7 +2,7 @@ import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.blocks.*; -import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.expressions._old.ExpressionWrapperNode; +import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.statements.ExpressionWrapperNode; import fr.jamailun.ultimatespellsystem.dsl2.nodes.ExpressionNode; import fr.jamailun.ultimatespellsystem.dsl2.nodes.StatementNode; import fr.jamailun.ultimatespellsystem.dsl2.nodes.statements.*; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/expressions/_old/EntityTypeLiteral.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/expressions/_old/EntityTypeLiteral.java deleted file mode 100644 index 36fadace..00000000 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/expressions/_old/EntityTypeLiteral.java +++ /dev/null @@ -1,30 +0,0 @@ -package fr.jamailun.ultimatespellsystem.plugin.runner.nodes.expressions._old; - -import fr.jamailun.ultimatespellsystem.api.entities.UssEntityType; -import fr.jamailun.ultimatespellsystem.api.providers.EntityTypeProvider; -import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; -import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.litteral.EntityTypeExpression; -import org.jetbrains.annotations.NotNull; - -/** - * Literal for {@link UssEntityType} - */ -public class EntityTypeLiteral extends RuntimeExpression { - - private final String name; - - public EntityTypeLiteral(@NotNull EntityTypeExpression dsl) { - this.name = dsl.getRaw(); - } - - @Override - public UssEntityType evaluate(@NotNull SpellRuntime runtime) { - return EntityTypeProvider.instance().find(name); - } - - @Override - public String toString() { - return "EntityType." + name; - } -} diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/expressions/_old/PositionOfNode.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/expressions/_old/PositionOfNode.java deleted file mode 100644 index e17c5ad6..00000000 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/expressions/_old/PositionOfNode.java +++ /dev/null @@ -1,52 +0,0 @@ -package fr.jamailun.ultimatespellsystem.plugin.runner.nodes.expressions._old; - -import fr.jamailun.ultimatespellsystem.UssLogger; -import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; -import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; -import fr.jamailun.ultimatespellsystem.api.runner.errors.InvalidTypeException; -import fr.jamailun.ultimatespellsystem.api.entities.SpellEntity; -import lombok.RequiredArgsConstructor; -import org.bukkit.Location; -import org.bukkit.entity.Entity; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.ArrayList; -import java.util.stream.Collectors; - -@RequiredArgsConstructor -public class PositionOfNode extends RuntimeExpression { - - private final RuntimeExpression entity; - private final boolean isCollection; - - @Override - public Object evaluate(@NotNull SpellRuntime runtime) { - if(isCollection) { - return runtime.safeEvaluateList(this.entity, Object.class).stream() - .map(PositionOfNode::getLocation) - .collect(Collectors.toCollection(ArrayList::new)); - } - Object entityRef = runtime.safeEvaluate(this.entity, Object.class); - Location location = getLocation(entityRef); - UssLogger.logDebug("PositionOf : " + entityRef + (entityRef==null?"":" = " +location)); - return location; - - } - - private static @Nullable Location getLocation(@Nullable Object object) { - return switch (object) { - case null -> null; - case Entity entity -> entity.getLocation(); - case SpellEntity spellEntity -> spellEntity.getLocation(); - case Location loc -> loc.clone(); - default -> throw new InvalidTypeException("position-of:entity", "entity", object); - }; - - } - - @Override - public String toString() { - return "position-of(" + entity + ")"; - } -} diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/_old/DefineNode.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/_old/DefineNode.java deleted file mode 100644 index 6a0d6f07..00000000 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/_old/DefineNode.java +++ /dev/null @@ -1,45 +0,0 @@ -package fr.jamailun.ultimatespellsystem.plugin.runner.nodes.functions._old; - -import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; -import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; -import fr.jamailun.ultimatespellsystem.api.runner.RuntimeStatement; -import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; -import lombok.RequiredArgsConstructor; -import org.jetbrains.annotations.NotNull; - -import java.util.ArrayList; - -/** - * A node that can define a variable to the runtime. - */ -@RequiredArgsConstructor -public class DefineNode extends RuntimeStatement { - - private final String varName; - private final RuntimeExpression expression; - private final Type type; - - @Override - public void run(@NotNull SpellRuntime runtime) { - if(type.is(TypePrimitive.NULL)) { - if(type.isCollection()) { - runtime.variables().set(varName, new ArrayList<>()); - } else { - runtime.variables().set(varName, null); - } - return; - } - - Class clazz = type.primitive().clazz; - if(clazz == null) - throw new RuntimeException("Cannot run a null-typed expression : " + runtime); - - runtime.variables().set(varName, expression.evaluate(runtime)); - } - - @Override - public String toString() { - return "DEFINE %" + varName + " = " + expression; - } -} diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/RunMathOpe.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/RunMathOpe.java deleted file mode 100644 index 30814e17..00000000 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/RunMathOpe.java +++ /dev/null @@ -1,52 +0,0 @@ -package fr.jamailun.ultimatespellsystem.plugin.runner.nodes.operators; - -import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; -import fr.jamailun.ultimatespellsystem.api.runner.errors.UnreachableRuntimeException; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.operators.MonoOperator.MonoOpeType; -import org.jetbrains.annotations.NotNull; - -import java.util.ArrayList; -import java.util.List; - -/** - * Not-operator - */ -public final class RunMathOpe extends RuntimeMonoOperator { - - private final MonoOpeType type; - - /** - * Create a new mono-operator. - * @param child the child expression. - * @param type the type of operation. - */ - public RunMathOpe(@NotNull RuntimeExpression child, @NotNull MonoOpeType type) { - super(child); - this.type = type; - } - - @Override - protected @NotNull Object evaluate(@NotNull Object value) { - // A math function only handles numbers. - if(value instanceof List list) { - // evaluate for each element. - List output = new ArrayList<>(); - for(Object subValue : list) { - output.add(evaluate(subValue)); - } - return output; - } - - // If it's a number, accept it - if(value instanceof Number number) { - return type.function.apply(number); - } - - throw new UnreachableRuntimeException("Unexpected type for "+type+"-operator : " + value + " | " + value.getClass()); - } - - @Override - public @NotNull String toString() { - return "not(" + child + ")"; - } -} diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/expressions/_old/ExpressionWrapperNode.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/statements/ExpressionWrapperNode.java similarity index 90% rename from plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/expressions/_old/ExpressionWrapperNode.java rename to plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/statements/ExpressionWrapperNode.java index 9e370134..2fc71fbb 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/expressions/_old/ExpressionWrapperNode.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/statements/ExpressionWrapperNode.java @@ -1,4 +1,4 @@ -package fr.jamailun.ultimatespellsystem.plugin.runner.nodes.expressions._old; +package fr.jamailun.ultimatespellsystem.plugin.runner.nodes.statements; import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.RuntimeStatement; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/AbstractStructDefinition.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/AbstractStructDefinition.java index bdd258a9..041fbb09 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/AbstractStructDefinition.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/AbstractStructDefinition.java @@ -71,7 +71,7 @@ protected void registerNumber(@NotNull String name, @NotNull Function protected void registerNullFunc(@NotNull String name, @NotNull BiConsumer> impl, FunctionArgument... args) { registerFunction( - FunctionDefinition.of(name, TypePrimitive.NULL.asType(), args), + FunctionDefinition.of(name, Type.NULL, args), (s, params) -> { impl.accept(s, params); return null; @@ -153,6 +153,11 @@ protected void set(@NotNull S object, @NotNull TokenPosition pos, @NotNull S return func; } + @Override + public @NotNull String getName() { + return structName; + } + /** * Meta-data holder for types. * @param type of the field. diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/AbstractStructInstance.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/AbstractStructInstance.java index 867a5c72..7fc781cd 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/AbstractStructInstance.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/AbstractStructInstance.java @@ -5,6 +5,8 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.List; + /** * Structure instance for an object. */ @@ -32,4 +34,9 @@ public AbstractStructInstance(@NotNull AbstractStructDefinition definition, S public void setField(@NotNull TokenPosition pos, @NotNull String fieldName, @Nullable Object value) { definition.set(object, pos, fieldName, value); } + + @Override + public @Nullable Object callFunction(@NotNull TokenPosition pos, @NotNull String functionName, @NotNull List parameters) { + return definition.call(object, pos, functionName, parameters);; + } } diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/ConsoleDefinition.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/ConsoleDefinition.java index 955df9fd..a2511916 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/ConsoleDefinition.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/ConsoleDefinition.java @@ -1,6 +1,7 @@ package fr.jamailun.ultimatespellsystem.plugin.runner.structs; import fr.jamailun.ultimatespellsystem.UssLogger; +import fr.jamailun.ultimatespellsystem.api.runner.structs.Struct; import fr.jamailun.ultimatespellsystem.dsl2.library.StructDefinition; import fr.jamailun.ultimatespellsystem.dsl2.library.structs.ConsoleStruct; import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; @@ -33,6 +34,11 @@ public ConsoleDefinition() { registerSend("error", UssLogger::logError); } + @Override + public @NotNull Struct instantiate(Void value) { + return new ConsoleInstance(); + } + private void registerSend(String name, Consumer method) { registerNullFunc( name, @@ -43,6 +49,6 @@ private void registerSend(String name, Consumer method) { @Override protected @NotNull StructDefinition computeDsl() { - return Objects.requireNonNull(ObjectsDefinitionRegistry.getDefaultStruct(structName), "Console struct cannot be found in defaults."); + return Objects.requireNonNull(ObjectsDefinitionRegistry.getDefaultStruct(getName()), "Console struct cannot be found in defaults."); } } diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/EntityDefinition.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/EntityDefinition.java index 36c9f4d9..52c4b8d2 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/EntityDefinition.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/EntityDefinition.java @@ -1,6 +1,7 @@ package fr.jamailun.ultimatespellsystem.plugin.runner.structs; import fr.jamailun.ultimatespellsystem.api.entities.SpellEntity; +import fr.jamailun.ultimatespellsystem.api.runner.structs.Struct; import fr.jamailun.ultimatespellsystem.api.utils.StringTransformation; import fr.jamailun.ultimatespellsystem.dsl2.library.StructDefinition; import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; @@ -39,6 +40,11 @@ public EntityDefinition() { loadFunctions(); } + @Override + public @NotNull Struct instantiate(SpellEntity value) { + return new EntityInstance(value, this); + } + private void loadFields() { // Name registerString("name", makeBukkitGetter(Entity::getName)); @@ -86,7 +92,7 @@ private void loadFunctions() { @Override protected @NotNull StructDefinition computeDsl() { - return Objects.requireNonNull(ObjectsDefinitionRegistry.getDefaultStruct(structName), "Entity struct cannot be found in defaults."); + return Objects.requireNonNull(ObjectsDefinitionRegistry.getDefaultStruct(getName()), "Entity struct cannot be found in defaults."); } private static @NotNull Function makeBukkitGetter(@NotNull Function getter) { diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/EntityInstance.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/EntityInstance.java index 00482fbc..7fc932ef 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/EntityInstance.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/EntityInstance.java @@ -12,8 +12,8 @@ public class EntityInstance extends AbstractStructInstance { * Wraps a spell-entity inside this definition. * @param entity the entity to use. */ - public EntityInstance(@NotNull SpellEntity entity) { - super(EntityDefinition.get(), entity); + public EntityInstance(@NotNull SpellEntity entity, @NotNull EntityDefinition definition) { + super(definition, entity); } } diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/StructsLibrary.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/StructsLibrary.java new file mode 100644 index 00000000..d49e1b16 --- /dev/null +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/StructsLibrary.java @@ -0,0 +1,33 @@ +package fr.jamailun.ultimatespellsystem.plugin.runner.structs; + +import fr.jamailun.ultimatespellsystem.api.runner.structs.Struct; +import fr.jamailun.ultimatespellsystem.api.runner.structs.StructDefinition; +import fr.jamailun.ultimatespellsystem.dsl2.errors.TypeException; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenPosition; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.HashMap; +import java.util.Map; + +public class StructsLibrary { + + private final Map> definitions = new HashMap<>(); + + public @Nullable StructDefinition find(@NotNull String name) { + return definitions.get(name); + } + + public void register(@NotNull StructDefinition struct) { + definitions.put(struct.getName(), struct); + } + + @SuppressWarnings("unchecked") + public @NotNull Struct instantiate(@NotNull String structName, @NotNull S object) { + StructDefinition def = (StructDefinition) find(structName); + if(def == null) + throw new TypeException(TokenPosition.unknown(), "Could not find a definition for struct name '" + structName + "'."); + return def.instantiate(object); + } + +} diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/spells/functions/SpellFunction.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/spells/functions/SpellFunction.java index d084523f..c1e003e0 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/spells/functions/SpellFunction.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/spells/functions/SpellFunction.java @@ -10,7 +10,6 @@ import fr.jamailun.ultimatespellsystem.dsl2.UltimateSpellSystemDSL2; import fr.jamailun.ultimatespellsystem.dsl2.nodes.StatementNode; import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionType; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.MetadataNode; @@ -46,7 +45,7 @@ private void registerFunction() { // Definition new RunnableJavaFunction( name, - outputVar == null ? TypePrimitive.NULL.asType() : outputVar.type(), + outputVar == null ? Type.NULL : outputVar.type(), args ) { // Execution @@ -75,7 +74,7 @@ public Object executeSteps(@NotNull SpellRuntime runtime) { if(outputVar != null) { return runtime.variables().get(outputVar.name()); } - return runtime.getFinalExitCode(); + return runtime.getReturnedValue(); } public static @Nullable SpellFunction loadFile(@NotNull File file) { @@ -141,7 +140,7 @@ public Object executeSteps(@NotNull SpellRuntime runtime) { throw new InvalidMetadata(node, "unknown @param primitive: '" + varType + "'."); list.add(new FunctionArgument( - FunctionType.accept(type), + Type.of(type), varName, false )); diff --git a/plugin/src/test/java/fr/jamailun/ultimatespellsystem/runner/framework/functions/AssertNotCalledFunction.java b/plugin/src/test/java/fr/jamailun/ultimatespellsystem/runner/framework/functions/AssertNotCalledFunction.java index e2bbe024..4ad94280 100644 --- a/plugin/src/test/java/fr/jamailun/ultimatespellsystem/runner/framework/functions/AssertNotCalledFunction.java +++ b/plugin/src/test/java/fr/jamailun/ultimatespellsystem/runner/framework/functions/AssertNotCalledFunction.java @@ -4,7 +4,7 @@ import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; import fr.jamailun.ultimatespellsystem.api.runner.functions.RunnableJavaFunction; import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionType; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; import fr.jamailun.ultimatespellsystem.runner.framework.AssertException; import org.jetbrains.annotations.NotNull; @@ -15,14 +15,8 @@ public class AssertNotCalledFunction extends RunnableJavaFunction { public AssertNotCalledFunction() { super( "ASSERT_NOT_CALLED", - TypePrimitive.NULL.asType(), - List.of( - new FunctionArgument( - FunctionType.acceptOnlyMono(TypePrimitive.STRING), - "message", - false - ) - ) + Type.NULL, + List.of(FunctionArgument.of(TypePrimitive.STRING)) ); } diff --git a/plugin/src/test/java/fr/jamailun/ultimatespellsystem/runner/framework/functions/AssertTrueFunction.java b/plugin/src/test/java/fr/jamailun/ultimatespellsystem/runner/framework/functions/AssertTrueFunction.java index 31828358..da038dbb 100644 --- a/plugin/src/test/java/fr/jamailun/ultimatespellsystem/runner/framework/functions/AssertTrueFunction.java +++ b/plugin/src/test/java/fr/jamailun/ultimatespellsystem/runner/framework/functions/AssertTrueFunction.java @@ -4,7 +4,7 @@ import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; import fr.jamailun.ultimatespellsystem.api.runner.functions.RunnableJavaFunction; import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionType; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; import fr.jamailun.ultimatespellsystem.runner.framework.AssertException; import org.jetbrains.annotations.NotNull; @@ -15,15 +15,15 @@ public class AssertTrueFunction extends RunnableJavaFunction { public AssertTrueFunction() { super( "ASSERT_TRUE", - TypePrimitive.NULL.asType(), + Type.NULL, List.of( new FunctionArgument( - FunctionType.acceptOnlyMono(TypePrimitive.BOOLEAN), + Type.of(TypePrimitive.BOOLEAN), "value", true ), new FunctionArgument( - FunctionType.acceptOnlyMono(TypePrimitive.STRING), + Type.of(TypePrimitive.STRING), "message", false ) diff --git a/plugin/src/test/java/fr/jamailun/ultimatespellsystem/runner/framework/functions/PrintFunction.java b/plugin/src/test/java/fr/jamailun/ultimatespellsystem/runner/framework/functions/PrintFunction.java index 240209cd..cc516d71 100644 --- a/plugin/src/test/java/fr/jamailun/ultimatespellsystem/runner/framework/functions/PrintFunction.java +++ b/plugin/src/test/java/fr/jamailun/ultimatespellsystem/runner/framework/functions/PrintFunction.java @@ -4,7 +4,7 @@ import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; import fr.jamailun.ultimatespellsystem.api.runner.functions.RunnableJavaFunction; import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionType; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; import org.jetbrains.annotations.NotNull; @@ -14,14 +14,8 @@ public class PrintFunction extends RunnableJavaFunction { public PrintFunction() { super( "PRINT", - TypePrimitive.NULL.asType(), - List.of( - new FunctionArgument( - FunctionType.acceptOnlyMono(TypePrimitive.STRING), - "value", - true - ) - ) + Type.NULL, + List.of(FunctionArgument.of(TypePrimitive.STRING)) ); } From facdcdfcab450f502ba30581e9cdc4a32e5d2c58 Mon Sep 17 00:00:00 2001 From: "timothe.rosaz" Date: Sat, 1 Nov 2025 18:11:48 +0100 Subject: [PATCH 28/38] Fixed some minors issues --- .../api/entities/CallbackAction.java | 2 +- .../api/providers/CallbackEventProvider.java | 2 +- .../{objects => callbacks}/CallbackEvent.java | 2 +- .../dsl2/nodes/type/Type.java | 3 +-- .../dsl2/registries/CallbackEventRegistry.java | 2 +- .../validators/StructureValidationVisitor.java | 18 +++++++++++------- .../resources/parsing/corrects/loops/for.uss | 2 +- .../parsing/corrects/loops/for_break.uss | 2 +- .../parsing/corrects/loops/for_break_ctn.uss | 2 +- .../callbacks/EntityDeathCallbacks.java | 2 +- .../callbacks/ProjectileLandCallbacks.java | 2 +- .../callbacks/SummonExpiresCallbacks.java | 2 +- .../runner/nodes/blocks/CallbackNode.java | 2 +- 13 files changed, 23 insertions(+), 20 deletions(-) rename dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/{objects => callbacks}/CallbackEvent.java (97%) diff --git a/api/src/main/java/fr/jamailun/ultimatespellsystem/api/entities/CallbackAction.java b/api/src/main/java/fr/jamailun/ultimatespellsystem/api/entities/CallbackAction.java index 8f8d56aa..db149fa7 100644 --- a/api/src/main/java/fr/jamailun/ultimatespellsystem/api/entities/CallbackAction.java +++ b/api/src/main/java/fr/jamailun/ultimatespellsystem/api/entities/CallbackAction.java @@ -2,7 +2,7 @@ import fr.jamailun.ultimatespellsystem.api.runner.RuntimeStatement; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; -import fr.jamailun.ultimatespellsystem.dsl2.objects.CallbackEvent; +import fr.jamailun.ultimatespellsystem.dsl2.callbacks.CallbackEvent; import lombok.Getter; import org.bukkit.event.Event; import org.jetbrains.annotations.NotNull; diff --git a/api/src/main/java/fr/jamailun/ultimatespellsystem/api/providers/CallbackEventProvider.java b/api/src/main/java/fr/jamailun/ultimatespellsystem/api/providers/CallbackEventProvider.java index d32b04a7..2025a4fa 100644 --- a/api/src/main/java/fr/jamailun/ultimatespellsystem/api/providers/CallbackEventProvider.java +++ b/api/src/main/java/fr/jamailun/ultimatespellsystem/api/providers/CallbackEventProvider.java @@ -1,7 +1,7 @@ package fr.jamailun.ultimatespellsystem.api.providers; import fr.jamailun.ultimatespellsystem.api.entities.CallbackAction; -import fr.jamailun.ultimatespellsystem.dsl2.objects.CallbackEvent; +import fr.jamailun.ultimatespellsystem.dsl2.callbacks.CallbackEvent; import fr.jamailun.ultimatespellsystem.dsl2.registries.CallbackEventRegistry; import org.jetbrains.annotations.NotNull; diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/objects/CallbackEvent.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/callbacks/CallbackEvent.java similarity index 97% rename from dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/objects/CallbackEvent.java rename to dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/callbacks/CallbackEvent.java index f9089593..b62053bf 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/objects/CallbackEvent.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/callbacks/CallbackEvent.java @@ -1,4 +1,4 @@ -package fr.jamailun.ultimatespellsystem.dsl2.objects; +package fr.jamailun.ultimatespellsystem.dsl2.callbacks; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenType; diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/Type.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/Type.java index 4ec22637..3675ccd6 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/Type.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/Type.java @@ -42,8 +42,6 @@ private Type(@Nullable TypePrimitive primitive, @Nullable String objectClass, in this.objectClass = objectClass; this.arrayLevel = arrayLevel; this.isNull = (primitive == null && objectClass == null); - if(isNull && arrayLevel > 0) - throw new IllegalArgumentException("Cannot create a NULL type with an array value."); } /** @@ -130,6 +128,7 @@ public int hashCode() { * @return a non-null Type, either with a primitive or not. */ public static @NotNull Type ofAny(@NotNull String name) { + if("null".equals(name) || "void".equals(name)) return NULL; TypePrimitive primitive = TypePrimitive.parsePrimitive(name); return primitive == null ? Type.of(name) : Type.of(primitive); } diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/registries/CallbackEventRegistry.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/registries/CallbackEventRegistry.java index 623c146a..0c0703ca 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/registries/CallbackEventRegistry.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/registries/CallbackEventRegistry.java @@ -1,6 +1,6 @@ package fr.jamailun.ultimatespellsystem.dsl2.registries; -import fr.jamailun.ultimatespellsystem.dsl2.objects.CallbackEvent; +import fr.jamailun.ultimatespellsystem.dsl2.callbacks.CallbackEvent; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/validators/StructureValidationVisitor.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/validators/StructureValidationVisitor.java index fe85e613..4b0cb997 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/validators/StructureValidationVisitor.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/validators/StructureValidationVisitor.java @@ -55,22 +55,26 @@ public void handleBlock(@NotNull BlockStatement statement) { } @Override - public void handleFunctionDeclaration(@NotNull FunctionDeclarationStatement statement) { + public void handleFunctionDeclaration(@NotNull FunctionDeclarationStatement function) { // Prepare child context StructureValidationVisitor child = child(); child.returnType = new TypeRef(); // Apply to statements - statement.getStatements().forEach(n -> n.visit(child)); + function.getStatements().forEach(n -> n.visit(child)); // Check returns - if(!statement.getOutputType().isNull()) { + if(!function.getOutputType().isNull()) { // No return - if(!child.returnMet) - throw new TreeValidationException(statement.getPosition(), "Function " + statement.getFunctionName() + " should return " + statement.getFunctionReturnType() + ", but not all branches return a value."); + if (!child.returnMet) + throw new TreeValidationException(function.getPosition(), "Function " + function.getFunctionName() + " should return " + function.getFunctionReturnType() + ", but not all branches return a value."); // Different return type. - if(!Objects.equals(statement.getOutputType(), child.returnType.type)) - throw new TreeValidationException(statement.getPosition(), "Function " + statement.getFunctionName() + " should return " + statement.getFunctionReturnType() + ", but returned "+child.returnType.type+" instead."); + if (function.getOutputType().isNull()) { + if(!child.returnType.type.isNull()) + throw new TreeValidationException(function.getPosition(), "Function " + function.getFunctionName() + " should not return anything, but returned " + child.returnType.type + " instead."); + } else if (!Objects.equals(function.getOutputType(), child.returnType.type)) { + throw new TreeValidationException(function.getPosition(), "Function " + function.getFunctionName() + " should return " + function.getFunctionReturnType() + ", but returned " + child.returnType.type + " instead."); + } } } diff --git a/dsl2/src/test/resources/parsing/corrects/loops/for.uss b/dsl2/src/test/resources/parsing/corrects/loops/for.uss index edc7d32d..d0fed29c 100644 --- a/dsl2/src/test/resources/parsing/corrects/loops/for.uss +++ b/dsl2/src/test/resources/parsing/corrects/loops/for.uss @@ -1,3 +1,3 @@ for(int i = 0; i < 5; ++i) { - caster.send("i = " + i); + console.info("i = " + i); } diff --git a/dsl2/src/test/resources/parsing/corrects/loops/for_break.uss b/dsl2/src/test/resources/parsing/corrects/loops/for_break.uss index 87cfc13a..d56ce86f 100644 --- a/dsl2/src/test/resources/parsing/corrects/loops/for_break.uss +++ b/dsl2/src/test/resources/parsing/corrects/loops/for_break.uss @@ -1,4 +1,4 @@ for(int i = 0; i < 5; ++i) { - caster.send("i = " + i); + caster.send_message("i = " + i); break; } diff --git a/dsl2/src/test/resources/parsing/corrects/loops/for_break_ctn.uss b/dsl2/src/test/resources/parsing/corrects/loops/for_break_ctn.uss index d7edc072..2f4462f8 100644 --- a/dsl2/src/test/resources/parsing/corrects/loops/for_break_ctn.uss +++ b/dsl2/src/test/resources/parsing/corrects/loops/for_break_ctn.uss @@ -1,5 +1,5 @@ for(int i = 0; i < 5; ++i) { - caster.send("i = " + i); + caster.send_message("i = " + i); if(i >= 3) continue; break; } diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/callbacks/EntityDeathCallbacks.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/callbacks/EntityDeathCallbacks.java index 6a1f21b6..1eaa6fcd 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/callbacks/EntityDeathCallbacks.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/callbacks/EntityDeathCallbacks.java @@ -3,7 +3,7 @@ import fr.jamailun.ultimatespellsystem.api.UltimateSpellSystem; import fr.jamailun.ultimatespellsystem.api.entities.CallbackAction; import fr.jamailun.ultimatespellsystem.api.entities.SummonAttributes; -import fr.jamailun.ultimatespellsystem.dsl2.objects.CallbackEvent; +import fr.jamailun.ultimatespellsystem.dsl2.callbacks.CallbackEvent; import org.bukkit.event.EventHandler; import org.bukkit.event.entity.EntityDeathEvent; import org.jetbrains.annotations.NotNull; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/callbacks/ProjectileLandCallbacks.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/callbacks/ProjectileLandCallbacks.java index 8311c628..fd62c22d 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/callbacks/ProjectileLandCallbacks.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/callbacks/ProjectileLandCallbacks.java @@ -4,7 +4,7 @@ import fr.jamailun.ultimatespellsystem.api.entities.CallbackAction; import fr.jamailun.ultimatespellsystem.api.entities.SummonAttributes; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; -import fr.jamailun.ultimatespellsystem.dsl2.objects.CallbackEvent; +import fr.jamailun.ultimatespellsystem.dsl2.callbacks.CallbackEvent; import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenType; import fr.jamailun.ultimatespellsystem.plugin.entities.BukkitSpellEntity; import org.bukkit.event.EventHandler; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/callbacks/SummonExpiresCallbacks.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/callbacks/SummonExpiresCallbacks.java index ecb811ae..9d1dfa0a 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/callbacks/SummonExpiresCallbacks.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/callbacks/SummonExpiresCallbacks.java @@ -2,7 +2,7 @@ import fr.jamailun.ultimatespellsystem.api.entities.CallbackAction; import fr.jamailun.ultimatespellsystem.api.events.SummonedEntityExpiredEvent; -import fr.jamailun.ultimatespellsystem.dsl2.objects.CallbackEvent; +import fr.jamailun.ultimatespellsystem.dsl2.callbacks.CallbackEvent; import org.bukkit.event.EventHandler; import org.jetbrains.annotations.NotNull; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/blocks/CallbackNode.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/blocks/CallbackNode.java index 9e235358..6a208275 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/blocks/CallbackNode.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/blocks/CallbackNode.java @@ -8,7 +8,7 @@ import fr.jamailun.ultimatespellsystem.api.runner.RuntimeStatement; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; import fr.jamailun.ultimatespellsystem.api.runner.errors.InvalidTypeException; -import fr.jamailun.ultimatespellsystem.dsl2.objects.CallbackEvent; +import fr.jamailun.ultimatespellsystem.dsl2.callbacks.CallbackEvent; import lombok.Getter; import org.jetbrains.annotations.NotNull; From d4b009632f84eccbc80e7ec622afe41958b165a4 Mon Sep 17 00:00:00 2001 From: "timothe.rosaz" Date: Sun, 2 Nov 2025 10:19:22 +0100 Subject: [PATCH 29/38] Fixed compilation, unicity of functions on signatureinstead of name only. --- .../api/entities/CustomEntity.java | 11 ++++++ .../api/runner/FunctionsSet.java | 35 +++++++++++++++++++ .../api/runner/SpellRuntime.java | 12 +++++++ .../api/runner/functions/GlobalFunction.java | 32 +++++++++++++++++ .../functions/RunnableJavaFunction.java | 15 +++++++- .../expressions/FunctionCallExpression.java | 7 ++++ .../functions/FunctionSignature.java | 20 +++++++++++ .../extension/ExtensionLoader.java | 3 -- .../callbacks/ProjectileLandCallbacks.java | 9 ++--- .../extension/citizens/CasterTrait.java | 11 ++++++ .../plugin/entities/BukkitSpellEntity.java | 11 ++++++ .../plugin/runner/AbstractSpellRuntime.java | 23 +++++++++--- .../plugin/runner/FunctionsSetImpl.java | 35 +++++++++++++++++++ .../plugin/runner/SpellRuntimeImpl.java | 2 ++ .../runner/builder/ExpressionQueue.java | 2 +- .../runner/nodes/blocks/RunRepeatNode.java | 3 +- .../objects/GlobalFunctionCallNode.java | 21 +++++------ .../structs/AbstractStructDefinition.java | 5 +-- .../structs/AbstractStructInstance.java | 2 +- .../runner/structs/EntityDefinition.java | 2 +- .../plugin/spells/SpellDefinition.java | 4 +-- .../runner/framework/TestFramework.java | 3 +- 22 files changed, 229 insertions(+), 39 deletions(-) create mode 100644 api/src/main/java/fr/jamailun/ultimatespellsystem/api/runner/FunctionsSet.java create mode 100644 api/src/main/java/fr/jamailun/ultimatespellsystem/api/runner/functions/GlobalFunction.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/functions/FunctionSignature.java create mode 100644 plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/FunctionsSetImpl.java diff --git a/api/src/main/java/fr/jamailun/ultimatespellsystem/api/entities/CustomEntity.java b/api/src/main/java/fr/jamailun/ultimatespellsystem/api/entities/CustomEntity.java index 741e9538..be7292df 100644 --- a/api/src/main/java/fr/jamailun/ultimatespellsystem/api/entities/CustomEntity.java +++ b/api/src/main/java/fr/jamailun/ultimatespellsystem/api/entities/CustomEntity.java @@ -117,4 +117,15 @@ public void remove() { public @NotNull PersistentDataContainer getNBT() { return transientDataContainer; } + + @Override + public Optional getEntityAs(Class clazz) { + return getBukkitEntity().map(e -> { + try { + return clazz.cast(e); + } catch(Exception ex) { + return null; + } + }); + } } diff --git a/api/src/main/java/fr/jamailun/ultimatespellsystem/api/runner/FunctionsSet.java b/api/src/main/java/fr/jamailun/ultimatespellsystem/api/runner/FunctionsSet.java new file mode 100644 index 00000000..c6cb4bbb --- /dev/null +++ b/api/src/main/java/fr/jamailun/ultimatespellsystem/api/runner/FunctionsSet.java @@ -0,0 +1,35 @@ +package fr.jamailun.ultimatespellsystem.api.runner; + +import fr.jamailun.ultimatespellsystem.api.runner.functions.GlobalFunction; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionSignature; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * A set of functions. + */ +public interface FunctionsSet { + + /** + * Get a function. + * @param signature the function signature key. + * @return the content of the variable, or {@code null} if not defined. + */ + @Nullable GlobalFunction get(@NotNull FunctionSignature signature); + + /** + * Create an inherited functions set. + * @return a new instance. Mutating existing vars of the instance will mutate {@code this} instance. + * But adding new functions will not. + */ + @Contract(" -> new") + @NotNull FunctionsSet inherit(); + + /** + * Register a new function. + * @param function the function to register. + */ + void register(@NotNull GlobalFunction function); + +} diff --git a/api/src/main/java/fr/jamailun/ultimatespellsystem/api/runner/SpellRuntime.java b/api/src/main/java/fr/jamailun/ultimatespellsystem/api/runner/SpellRuntime.java index 2b61d268..1659fd99 100644 --- a/api/src/main/java/fr/jamailun/ultimatespellsystem/api/runner/SpellRuntime.java +++ b/api/src/main/java/fr/jamailun/ultimatespellsystem/api/runner/SpellRuntime.java @@ -32,6 +32,12 @@ public interface SpellRuntime { */ @NotNull VariablesSet variables(); + /** + * A reference to the functions set. + * @return the final reference to the functions. + */ + @NotNull FunctionsSet functions(); + /** * Test if the runtime has been stopped. * @return true if no more statements should be executed. @@ -106,6 +112,12 @@ public interface SpellRuntime { */ @Nullable Object getReturnedValue(); + /** + * Test if the returned value is considered as a success. + * @return true if return value is {@code null}, or {@code 0}, or {@code true}. + */ + boolean isReturnValueSuccess(); + /** * Evaluate a value. * @param expression the expression to evaluate. diff --git a/api/src/main/java/fr/jamailun/ultimatespellsystem/api/runner/functions/GlobalFunction.java b/api/src/main/java/fr/jamailun/ultimatespellsystem/api/runner/functions/GlobalFunction.java new file mode 100644 index 00000000..f66ca413 --- /dev/null +++ b/api/src/main/java/fr/jamailun/ultimatespellsystem/api/runner/functions/GlobalFunction.java @@ -0,0 +1,32 @@ +package fr.jamailun.ultimatespellsystem.api.runner.functions; + +import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; +import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionSignature; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenPosition; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +/** + * A global function. Either from the Java code, or from the USS script. + */ +public interface GlobalFunction { + + /** + * Get the signature of the function. + * @return the instance function signature. + */ + @NotNull FunctionSignature getSignature(); + + /** + * Call the function with parameters. + * @param pos token position. + * @param arguments params of the function. + * @param runtime spell runtime. + * @return the output value. + */ + @Nullable Object call(@NotNull TokenPosition pos, @NotNull List arguments, @NotNull SpellRuntime runtime); + +} diff --git a/api/src/main/java/fr/jamailun/ultimatespellsystem/api/runner/functions/RunnableJavaFunction.java b/api/src/main/java/fr/jamailun/ultimatespellsystem/api/runner/functions/RunnableJavaFunction.java index 773261e2..ed3eaa3b 100644 --- a/api/src/main/java/fr/jamailun/ultimatespellsystem/api/runner/functions/RunnableJavaFunction.java +++ b/api/src/main/java/fr/jamailun/ultimatespellsystem/api/runner/functions/RunnableJavaFunction.java @@ -4,10 +4,13 @@ import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionDefinition; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionSignature; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenPosition; import lombok.Getter; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.List; @@ -15,7 +18,7 @@ * A runnable code declaration */ @Getter -public abstract class RunnableJavaFunction { +public abstract class RunnableJavaFunction implements GlobalFunction { private final @NotNull String id; private final @NotNull Type type; @@ -34,6 +37,16 @@ public RunnableJavaFunction(@NotNull String id, @NotNull Type type, @NotNull Lis this.arguments = arguments; } + @Override + public @NotNull FunctionSignature getSignature() { + return FunctionSignature.of(id, arguments); + } + + @Override + public @Nullable Object call(@NotNull TokenPosition pos, @NotNull List arguments, @NotNull SpellRuntime runtime) { + return compute(arguments, runtime); + } + /** * Compute the value, using the arguments. * @param arguments the arguments values returned. Must be computed in the runtime. diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/FunctionCallExpression.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/FunctionCallExpression.java index 3ebbbb0f..d4bf5d33 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/FunctionCallExpression.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/FunctionCallExpression.java @@ -6,6 +6,7 @@ import fr.jamailun.ultimatespellsystem.dsl2.nodes.ExpressionNode; import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionDefinition; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionSignature; import fr.jamailun.ultimatespellsystem.dsl2.nodes.statements.FunctionDeclarationStatement; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.variables.TypesContext; @@ -16,6 +17,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.ArrayList; import java.util.List; import java.util.Objects; @@ -29,7 +31,9 @@ public class FunctionCallExpression extends ExpressionNode { private final String functionName; private final List arguments; + // post build private @Nullable StructDefinition callerStruct; + private @Nullable FunctionSignature signature; public FunctionCallExpression(@Nullable ExpressionNode caller, @NotNull Token functionName, @NotNull List arguments) { super(functionName.pos()); @@ -48,9 +52,12 @@ public FunctionCallExpression(@Nullable ExpressionNode caller, @NotNull Token fu @Override public void validateTypes(@NotNull TypesContext context) { // 1. Propagate to arguments + List paramTypes = new ArrayList<>(); for(ExpressionNode argument : arguments) { argument.validateTypes(context.childContext()); + paramTypes.add(argument.getExpressionType()); } + signature = new FunctionSignature(functionName, paramTypes); // 2. If we have a caller : we check the function from the type definition. FunctionDefinition function; diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/functions/FunctionSignature.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/functions/FunctionSignature.java new file mode 100644 index 00000000..77a45dd2 --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/functions/FunctionSignature.java @@ -0,0 +1,20 @@ +package fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions; + +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * Defines the unicity of a function. + * @param name name of the function. + * @param paramsTypes arguments types. + */ +public record FunctionSignature( + @NotNull String name, + @NotNull List paramsTypes +) { + public static @NotNull FunctionSignature of(@NotNull String id, @NotNull List args) { + return new FunctionSignature(id, args.stream().map(FunctionArgument::type).toList()); + } +} diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/ExtensionLoader.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/ExtensionLoader.java index 22e71d30..f0190770 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/ExtensionLoader.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/ExtensionLoader.java @@ -52,9 +52,6 @@ public static synchronized void loadStatic() { JavaFunctionProvider.instance().registerFunction(new KnockbackFunction(), "set_velocity"); JavaFunctionProvider.instance().registerFunction(new DirectionOfFunction(), "dir_of"); JavaFunctionProvider.instance().registerFunction(new NormalizeFunction(), "norm"); - JavaFunctionProvider.instance().registerFunction(new GetHealthFunction()); - JavaFunctionProvider.instance().registerFunction(new GetMaxHealthFunction()); - JavaFunctionProvider.instance().registerFunction(new HealEntityFunction(), "heal_entity"); JavaFunctionProvider.instance().registerFunction(new AreAlliesFunction()); JavaFunctionProvider.instance().registerFunction(new EntityHasEffectFunction(), "entity_has_potion_effect", "has_potion_effect", "has_effect"); JavaFunctionProvider.instance().registerFunction(new SetAggroFunction()); diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/callbacks/ProjectileLandCallbacks.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/callbacks/ProjectileLandCallbacks.java index fd62c22d..fb11f70d 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/callbacks/ProjectileLandCallbacks.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/callbacks/ProjectileLandCallbacks.java @@ -3,10 +3,6 @@ import fr.jamailun.ultimatespellsystem.api.UltimateSpellSystem; import fr.jamailun.ultimatespellsystem.api.entities.CallbackAction; import fr.jamailun.ultimatespellsystem.api.entities.SummonAttributes; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; -import fr.jamailun.ultimatespellsystem.dsl2.callbacks.CallbackEvent; -import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenType; -import fr.jamailun.ultimatespellsystem.plugin.entities.BukkitSpellEntity; import org.bukkit.event.EventHandler; import org.bukkit.event.entity.ProjectileHitEvent; import org.jetbrains.annotations.NotNull; @@ -28,8 +24,9 @@ void onEvent(@NotNull ProjectileHitEvent event) { @Override public @NotNull Collection> getCallbacks() { + //FIXME repair the callbacks system return List.of( - new CallbackAction<>( + /*new CallbackAction<>( CallbackEvent.of("landed", TokenType.AT, TypePrimitive.LOCATION), ProjectileHitEvent.class, e -> e.getEntity().getLocation() @@ -38,7 +35,7 @@ void onEvent(@NotNull ProjectileHitEvent event) { CallbackEvent.of("hit", TokenType.TO, TypePrimitive.ENTITY), ProjectileHitEvent.class, e -> new BukkitSpellEntity(e.getHitEntity()) - ) + )*/ ); } diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/citizens/CasterTrait.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/citizens/CasterTrait.java index c96d7204..9e2b46fc 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/citizens/CasterTrait.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/extension/citizens/CasterTrait.java @@ -112,6 +112,17 @@ public void save(@NotNull DataKey key) { return Optional.empty(); } + @Override + public Optional getEntityAs(Class clazz) { + return getBukkitEntity().map(e -> { + try { + return clazz.cast(e); + } catch(Exception ex) { + return null; + } + }); + } + @Override public @NotNull Location getLocation() { return getBukkitEntity().map(Entity::getLocation).orElse(getNPC().getStoredLocation()); diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/entities/BukkitSpellEntity.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/entities/BukkitSpellEntity.java index d0c04eda..4cf1249c 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/entities/BukkitSpellEntity.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/entities/BukkitSpellEntity.java @@ -74,6 +74,17 @@ public void setVelocity(@NotNull Vector vector) { getBukkitEntity().ifPresent(entity -> entity.setVelocity(vector)); } + @Override + public Optional getEntityAs(Class clazz) { + return getBukkitEntity().map(e -> { + try { + return clazz.cast(e); + } catch(Exception ex) { + return null; + } + }); + } + @Override public boolean equals(Object other) { if(other == null) return false; diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/AbstractSpellRuntime.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/AbstractSpellRuntime.java index cf48fcd1..26ae95a3 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/AbstractSpellRuntime.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/AbstractSpellRuntime.java @@ -1,9 +1,6 @@ package fr.jamailun.ultimatespellsystem.plugin.runner; -import fr.jamailun.ultimatespellsystem.api.runner.FlowState; -import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; -import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; -import fr.jamailun.ultimatespellsystem.api.runner.VariablesSet; +import fr.jamailun.ultimatespellsystem.api.runner.*; import fr.jamailun.ultimatespellsystem.api.runner.structs.Struct; import fr.jamailun.ultimatespellsystem.api.spells.Spell; import fr.jamailun.ultimatespellsystem.plugin.runner.structs.StructsLibrary; @@ -23,6 +20,7 @@ public abstract class AbstractSpellRuntime implements SpellRuntime { protected final Map cachedStructures = new HashMap<>(); protected final StructsLibrary structsLibrary; protected final VariablesSet variables; + protected final FunctionsSet functions; protected final ExitCode exitCode; @Getter protected final Spell spell; @@ -33,6 +31,7 @@ public abstract class AbstractSpellRuntime implements SpellRuntime { AbstractSpellRuntime(@NotNull AbstractSpellRuntime parent, boolean inFunction) { exitCode = parent.exitCode; variables = parent.variables.inherit(); + functions = parent.functions.inherit(); flagContinue = parent.flagContinue; flagBreak = parent.flagBreak; spell = parent.spell; @@ -44,6 +43,7 @@ public abstract class AbstractSpellRuntime implements SpellRuntime { AbstractSpellRuntime(@NotNull ExitCode exitCode, @Nullable Spell spell) { this.exitCode = exitCode; variables = new VariablesSetImpl(); + functions = new FunctionsSetImpl(); this.spell = spell; this.structsLibrary = new StructsLibrary(); inFunction = false; @@ -59,6 +59,11 @@ public boolean isStopped() { return variables; } + @Override + public @NotNull FunctionsSet functions() { + return functions; + } + @Override public @Nullable T safeEvaluate(RuntimeExpression expression, Class clazz) { if(expression == null) @@ -98,6 +103,16 @@ public boolean isStopped() { return exitCode.getValue(); } + @Override + public boolean isReturnValueSuccess() { + return switch (getReturnedValue()) { + case null -> true; + case Number num -> num.intValue() == 0; + case Boolean b -> b; + default -> false; + }; + } + @Override public void statementReturn(@Nullable Object value) { exitCode.set(value); diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/FunctionsSetImpl.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/FunctionsSetImpl.java new file mode 100644 index 00000000..ea45e7cb --- /dev/null +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/FunctionsSetImpl.java @@ -0,0 +1,35 @@ +package fr.jamailun.ultimatespellsystem.plugin.runner; + +import fr.jamailun.ultimatespellsystem.api.runner.FunctionsSet; +import fr.jamailun.ultimatespellsystem.api.runner.functions.GlobalFunction; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionSignature; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.HashMap; +import java.util.Map; + +/** + * A set of keyed variables. + */ +public final class FunctionsSetImpl implements FunctionsSet { + + private final Map functions = new HashMap<>(); + + @Override + public @Nullable GlobalFunction get(@NotNull FunctionSignature signature) { + return functions.get(signature); + } + + @Override + public @NotNull FunctionsSetImpl inherit() { + FunctionsSetImpl output = new FunctionsSetImpl(); + output.functions.putAll(functions); + return output; + } + + @Override + public void register(@NotNull GlobalFunction function) { + functions.put(function.getSignature(), function); + } +} diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/SpellRuntimeImpl.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/SpellRuntimeImpl.java index a88f2f8d..fb0ce595 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/SpellRuntimeImpl.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/SpellRuntimeImpl.java @@ -1,6 +1,7 @@ package fr.jamailun.ultimatespellsystem.plugin.runner; import fr.jamailun.ultimatespellsystem.api.entities.SpellEntity; +import fr.jamailun.ultimatespellsystem.api.runner.FunctionsSet; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; import fr.jamailun.ultimatespellsystem.api.spells.Spell; import fr.jamailun.ultimatespellsystem.plugin.entities.BukkitSpellEntity; @@ -35,6 +36,7 @@ public SpellRuntimeImpl(@NotNull SpellEntity caster, @Nullable Spell spell) { super(new ExitCode(), spell); this.caster = caster; variables.set("caster", caster); + variables.set("console", new Object()); } private SpellRuntimeImpl(@NotNull SpellRuntimeImpl parent, @NotNull SpellEntity caster, boolean inFunction) { diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/builder/ExpressionQueue.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/builder/ExpressionQueue.java index 5452c106..e7ef587a 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/builder/ExpressionQueue.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/builder/ExpressionQueue.java @@ -171,7 +171,7 @@ public void handleFunctionCall(@NotNull FunctionCallExpression functionCall) { } // User-defined function instead else { - add(new GlobalFunctionCallNode(pos, functionName, parameters)); + add(new GlobalFunctionCallNode(pos, functionCall.getSignature(), parameters)); } return; } diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/blocks/RunRepeatNode.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/blocks/RunRepeatNode.java index c34faff7..e7f6da83 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/blocks/RunRepeatNode.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/blocks/RunRepeatNode.java @@ -3,7 +3,6 @@ import fr.jamailun.ultimatespellsystem.UssLogger; import fr.jamailun.ultimatespellsystem.api.UltimateSpellSystem; import fr.jamailun.ultimatespellsystem.api.runner.FlowState; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.statements.blocks.RepeatStatement; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Duration; import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.RuntimeStatement; @@ -72,7 +71,7 @@ public void run() { } return; } - runtime.variables().set(RepeatStatement.INDEX_VARIABLE, count); + runtime.variables().set("_index", count); try { child.run(runtime); } catch (Exception t) { diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/objects/GlobalFunctionCallNode.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/objects/GlobalFunctionCallNode.java index 29d87be7..3f291917 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/objects/GlobalFunctionCallNode.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/objects/GlobalFunctionCallNode.java @@ -2,14 +2,14 @@ import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; -import fr.jamailun.ultimatespellsystem.api.runner.structs.Struct; -import fr.jamailun.ultimatespellsystem.dsl2.library.StructDefinition; +import fr.jamailun.ultimatespellsystem.api.runner.functions.GlobalFunction; +import fr.jamailun.ultimatespellsystem.dsl2.errors.UnknownFunctionException; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionSignature; import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenPosition; import lombok.RequiredArgsConstructor; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; import java.util.List; /** @@ -19,25 +19,22 @@ public class GlobalFunctionCallNode extends RuntimeExpression { private final TokenPosition pos; - private final String functionName; + private final FunctionSignature signature; private final List parameters; @Override public @Nullable Object evaluate(@NotNull SpellRuntime runtime) { // Find function - - // Handle params - List params = new ArrayList<>(parameters.size()); - for(RuntimeExpression expression : parameters) { - params.add(expression.evaluate(runtime)); - } + GlobalFunction function = runtime.functions().get(signature); + if(function == null) + throw new UnknownFunctionException(pos, signature.name()); // Call function - return struct.callFunction(pos, functionName, params); + return function.call(pos, parameters, runtime); } @Override public @NotNull String toString() { - return functionName + "(" + parameters + ")"; + return signature.name() + "(" + parameters + ")"; } } diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/AbstractStructDefinition.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/AbstractStructDefinition.java index 041fbb09..8d812ad0 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/AbstractStructDefinition.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/AbstractStructDefinition.java @@ -29,9 +29,6 @@ @RequiredArgsConstructor(access = AccessLevel.PROTECTED) public abstract class AbstractStructDefinition implements StructDefinition { - protected static final Type TYPE_LOCATION = Type.of(fr.jamailun.ultimatespellsystem.dsl2.library.StructDefinition.LAZY_TYPE_LOCATION); - protected static final Type TYPE_ENTITY = Type.of(fr.jamailun.ultimatespellsystem.dsl2.library.StructDefinition.LAZY_TYPE_ENTITY); - private final Map> fields = new HashMap<>(); private final Map> functions = new HashMap<>(); @@ -58,7 +55,7 @@ protected void registerNumber(@NotNull String name, @NotNull Function } protected void registerLocation(@NotNull String name, @NotNull Function getter) { - registerField(name, TYPE_LOCATION, getter, null); + registerField(name, Type.of(TypePrimitive.LOCATION), getter, null); } protected void registerString(@NotNull String name, @NotNull Function getter) { diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/AbstractStructInstance.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/AbstractStructInstance.java index 7fc781cd..3afc10f6 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/AbstractStructInstance.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/AbstractStructInstance.java @@ -37,6 +37,6 @@ public void setField(@NotNull TokenPosition pos, @NotNull String fieldName, @Nul @Override public @Nullable Object callFunction(@NotNull TokenPosition pos, @NotNull String functionName, @NotNull List parameters) { - return definition.call(object, pos, functionName, parameters);; + return definition.call(object, pos, functionName, parameters); } } diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/EntityDefinition.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/EntityDefinition.java index 52c4b8d2..bb55fd55 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/EntityDefinition.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/EntityDefinition.java @@ -76,7 +76,7 @@ private void loadFunctions() { registerNullFunc( "teleport", (se,a) -> se.teleport((Location) a.getFirst()), - FunctionArgument.of(TYPE_LOCATION) + FunctionArgument.of(TypePrimitive.LOCATION) ); registerNullFunc( "send_message", diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/spells/SpellDefinition.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/spells/SpellDefinition.java index 47a70b24..c873483b 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/spells/SpellDefinition.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/spells/SpellDefinition.java @@ -124,8 +124,8 @@ protected boolean castSpell(@NotNull SpellEntity caster, @NotNull SpellRuntime r break; } - boolean success = runtime.getFinalExitCode() == 0; - UssLogger.logDebug(prefix + "End of cast on " + caster + " with code " + runtime.getFinalExitCode() + ". Success = " + success); + boolean success = runtime.isReturnValueSuccess(); + UssLogger.logDebug(prefix + "End of cast on " + caster + " with " + runtime.getReturnedValue() + ". Success = " + success); return success; } diff --git a/plugin/src/test/java/fr/jamailun/ultimatespellsystem/runner/framework/TestFramework.java b/plugin/src/test/java/fr/jamailun/ultimatespellsystem/runner/framework/TestFramework.java index f0f51973..4c775370 100644 --- a/plugin/src/test/java/fr/jamailun/ultimatespellsystem/runner/framework/TestFramework.java +++ b/plugin/src/test/java/fr/jamailun/ultimatespellsystem/runner/framework/TestFramework.java @@ -22,7 +22,6 @@ import org.jetbrains.annotations.NotNull; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; -import org.mockito.Mock; import org.mockito.MockedStatic; import org.mockito.Mockito; @@ -97,7 +96,7 @@ protected boolean cast(@NotNull List statements) { if(runtime.isStopped()) break; } - return runtime.getFinalExitCode() == 0; + return runtime.getReturnedValue() == null; } } From 1ffd7a284ad03fcc6f6b458197545745e0491365 Mon Sep 17 00:00:00 2001 From: "timothe.rosaz" Date: Sun, 2 Nov 2025 10:50:29 +0100 Subject: [PATCH 30/38] Fixed a bug with post-fix increment operator --- .../jamailun/ultimatespellsystem/dsl2/nodes/StatementNode.java | 3 ++- .../dsl2/nodes/statements/blocks/ForLoopStatement.java | 1 + dsl2/src/test/resources/parsing/corrects/loops/for_postfix.uss | 3 +++ .../parsing/corrects/loops/{for.uss => for_prefix.uss} | 0 4 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 dsl2/src/test/resources/parsing/corrects/loops/for_postfix.uss rename dsl2/src/test/resources/parsing/corrects/loops/{for.uss => for_prefix.uss} (100%) diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/StatementNode.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/StatementNode.java index eb76a013..9563d6c6 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/StatementNode.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/StatementNode.java @@ -72,7 +72,8 @@ public abstract class StatementNode extends Node { return AffectationStatement.parseNextDefine(wrapped, tokens); } - throw new SyntaxException(tokens.position(), "Unexpected token after IDENTIFIER: " + tokens.peek()); + // Other ? + return new SimpleExpressionStatement(wrapped); } /** diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/blocks/ForLoopStatement.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/blocks/ForLoopStatement.java index 2ada4c17..3308b4c2 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/blocks/ForLoopStatement.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/blocks/ForLoopStatement.java @@ -67,6 +67,7 @@ public void visit(@NotNull StatementVisitor visitor) { if(tokens.dropOptional(TokenType.BRACKET_CLOSE)) { iterator = null; } else { + System.out.println("salut salut :: " + tokens); iterator = StatementNode.parseNextStatement(tokens); tokens.dropOrThrow(TokenType.BRACKET_CLOSE); } diff --git a/dsl2/src/test/resources/parsing/corrects/loops/for_postfix.uss b/dsl2/src/test/resources/parsing/corrects/loops/for_postfix.uss new file mode 100644 index 00000000..a8b4c7a4 --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/loops/for_postfix.uss @@ -0,0 +1,3 @@ +for(int i = 0; i < 5; i++) { + console.info("i = " + i); +} diff --git a/dsl2/src/test/resources/parsing/corrects/loops/for.uss b/dsl2/src/test/resources/parsing/corrects/loops/for_prefix.uss similarity index 100% rename from dsl2/src/test/resources/parsing/corrects/loops/for.uss rename to dsl2/src/test/resources/parsing/corrects/loops/for_prefix.uss From 24739939584ba972d10d98462a9b54597f7ff381 Mon Sep 17 00:00:00 2001 From: "timothe.rosaz" Date: Sun, 2 Nov 2025 10:51:06 +0100 Subject: [PATCH 31/38] Disabled old DSL module --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 97084fc5..cf7b96bf 100644 --- a/pom.xml +++ b/pom.xml @@ -13,7 +13,7 @@ Spells in Minecraft with a custom DSL. - dsl + dsl2 api plugin From ed2a92e9809131436348552583324b534d688f3a Mon Sep 17 00:00:00 2001 From: "timothe.rosaz" Date: Sun, 2 Nov 2025 10:52:02 +0100 Subject: [PATCH 32/38] Properly register functions in runner --- .../runner/builder/SpellBuilderVisitor.java | 10 +++++--- .../plugin/runner/builder/SpellStructure.java | 20 +++++++++++++++ .../functions/RuntimeFunctionDeclaration.java | 25 ++++++++++++++----- .../objects/GlobalFunctionCallNode.java | 7 ++++++ .../plugin/spells/SpellDefinition.java | 15 ++++++++--- .../plugin/spells/SpellsCooldowns.java | 16 +++++++++++- .../spells/external/ExternalExecutorImpl.java | 2 +- .../spells/functions/SpellFunction.java | 4 ++- .../extension/ExtensionParsingTests.java | 4 ++- .../extension/ParseAndCompileTest.java | 3 ++- .../extension-parsing/loops/basic_incr.uss | 9 +++---- .../extension-parsing/loops/for_break.uss | 8 +++--- .../extension-parsing/loops/while_breaks.uss | 14 +++++------ .../entities/summon-orb.uss | 0 .../lists/basic_list.uss | 0 .../lists/entity_contains.uss | 0 .../test/resources/old/loops/basic_incr.uss | 6 +++++ .../test/resources/old/loops/for_break.uss | 11 ++++++++ .../loops/foreach_break.uss | 0 .../loops/repeat_breaks.uss | 0 .../test/resources/old/loops/while_breaks.uss | 14 +++++++++++ .../various/damage.uss | 0 .../various/entity_set_unset.uss | 0 .../various/operators.uss | 0 .../various/repeat.uss | 0 .../various/strike.uss | 0 26 files changed, 134 insertions(+), 34 deletions(-) create mode 100644 plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/builder/SpellStructure.java rename plugin/src/test/resources/{extension-parsing => old}/entities/summon-orb.uss (100%) rename plugin/src/test/resources/{extension-parsing => old}/lists/basic_list.uss (100%) rename plugin/src/test/resources/{extension-parsing => old}/lists/entity_contains.uss (100%) create mode 100644 plugin/src/test/resources/old/loops/basic_incr.uss create mode 100644 plugin/src/test/resources/old/loops/for_break.uss rename plugin/src/test/resources/{extension-parsing => old}/loops/foreach_break.uss (100%) rename plugin/src/test/resources/{extension-parsing => old}/loops/repeat_breaks.uss (100%) create mode 100644 plugin/src/test/resources/old/loops/while_breaks.uss rename plugin/src/test/resources/{extension-parsing => old}/various/damage.uss (100%) rename plugin/src/test/resources/{extension-parsing => old}/various/entity_set_unset.uss (100%) rename plugin/src/test/resources/{extension-parsing => old}/various/operators.uss (100%) rename plugin/src/test/resources/{extension-parsing => old}/various/repeat.uss (100%) rename plugin/src/test/resources/{extension-parsing => old}/various/strike.uss (100%) diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/builder/SpellBuilderVisitor.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/builder/SpellBuilderVisitor.java index e3c3aed5..f6a13ca3 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/builder/SpellBuilderVisitor.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/builder/SpellBuilderVisitor.java @@ -1,5 +1,6 @@ package fr.jamailun.ultimatespellsystem.plugin.runner.builder; +import fr.jamailun.ultimatespellsystem.api.runner.functions.GlobalFunction; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.blocks.*; import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.statements.ExpressionWrapperNode; @@ -32,18 +33,21 @@ public class SpellBuilderVisitor implements StatementVisitor { private final List statementsAccumulator = new ArrayList<>(); private final Deque> accumulatorsStack = new ArrayDeque<>(); - @Getter private final Map functions = new HashMap<>(); + @Getter private final Map functions = new HashMap<>(); public SpellBuilderVisitor() { currentQueue = statementsAccumulator; } - public static @NotNull List build(@NotNull List dsl) { + public static @NotNull SpellStructure build(@NotNull List dsl) { SpellBuilderVisitor visitor = new SpellBuilderVisitor(); for(StatementNode statement : dsl) { statement.visit(visitor); } - return visitor.statementsAccumulator; + return new SpellStructure( + visitor.statementsAccumulator, + visitor.functions.values() + ); } @Override diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/builder/SpellStructure.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/builder/SpellStructure.java new file mode 100644 index 00000000..09eadf5b --- /dev/null +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/builder/SpellStructure.java @@ -0,0 +1,20 @@ +package fr.jamailun.ultimatespellsystem.plugin.runner.builder; + +import fr.jamailun.ultimatespellsystem.api.runner.RuntimeStatement; +import fr.jamailun.ultimatespellsystem.api.runner.functions.GlobalFunction; +import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.functions.RuntimeFunctionDeclaration; +import org.jetbrains.annotations.NotNull; + +import java.util.Collection; +import java.util.List; + +/** + * Content of a spell. + * @param statements statements of the spell. + * @param functions functions registered inside the spell. + */ +public record SpellStructure( + @NotNull List statements, + @NotNull Collection functions +) { +} diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/RuntimeFunctionDeclaration.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/RuntimeFunctionDeclaration.java index 0823dac8..fb5488c1 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/RuntimeFunctionDeclaration.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/functions/RuntimeFunctionDeclaration.java @@ -1,10 +1,14 @@ package fr.jamailun.ultimatespellsystem.plugin.runner.nodes.functions; import fr.jamailun.ultimatespellsystem.api.runner.FlowState; +import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; import fr.jamailun.ultimatespellsystem.api.runner.RuntimeStatement; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; +import fr.jamailun.ultimatespellsystem.api.runner.functions.GlobalFunction; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionSignature; import fr.jamailun.ultimatespellsystem.dsl2.nodes.statements.FunctionDeclarationStatement; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenPosition; import lombok.RequiredArgsConstructor; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -13,18 +17,24 @@ import java.util.List; @RequiredArgsConstructor -public class RuntimeFunctionDeclaration { +public class RuntimeFunctionDeclaration implements GlobalFunction { private final @NotNull String name; private final @NotNull Type type; private final @NotNull List args; private final @NotNull List statements; - public @Nullable Object execute(@NotNull SpellRuntime runtimeSource, @NotNull List parameters) { - SpellRuntime runtime = runtimeSource.makeChild(true); + @Override + public @NotNull FunctionSignature getSignature() { + return new FunctionSignature(name, args.stream().map(fa -> Type.ofAny(fa.type())).toList()); + } + + @Override + public @Nullable Object call(@NotNull TokenPosition pos, @NotNull List arguments, @NotNull SpellRuntime runtimeParent) { + SpellRuntime runtime = runtimeParent.makeChild(true); - // Register parameters as variables in local scope - for(MatchedParam param : matchParams(parameters)) { + // Handle params + for(MatchedParam param : matchParams(runtime, arguments)) { runtime.variables().set(param.argName(), param.value()); } @@ -40,13 +50,16 @@ public class RuntimeFunctionDeclaration { } } - //TODO Check the output type + //TODO match output type? return output; } private record MatchedParam(@NotNull String argName, @Nullable Object value) { } + private @NotNull List matchParams(@NotNull SpellRuntime runtime, List args) { + return matchParams(args.stream().map(a -> a.evaluate(runtime)).toList()); + } private @NotNull List matchParams(@NotNull List params) { List output = new ArrayList<>(args.size()); for(int i = 0; i < args.size(); i++) { diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/objects/GlobalFunctionCallNode.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/objects/GlobalFunctionCallNode.java index 3f291917..88f67e10 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/objects/GlobalFunctionCallNode.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/objects/GlobalFunctionCallNode.java @@ -10,6 +10,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.ArrayList; import java.util.List; /** @@ -29,6 +30,12 @@ public class GlobalFunctionCallNode extends RuntimeExpression { if(function == null) throw new UnknownFunctionException(pos, signature.name()); + // Handle params + List params = new ArrayList<>(parameters.size()); + for(RuntimeExpression expression : parameters) { + params.add(expression.evaluate(runtime)); + } + // Call function return function.call(pos, parameters, runtime); } diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/spells/SpellDefinition.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/spells/SpellDefinition.java index c873483b..7f9d01e9 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/spells/SpellDefinition.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/spells/SpellDefinition.java @@ -4,6 +4,7 @@ import fr.jamailun.ultimatespellsystem.api.entities.SpellEntity; import fr.jamailun.ultimatespellsystem.api.runner.RuntimeStatement; import fr.jamailun.ultimatespellsystem.api.runner.SpellRuntime; +import fr.jamailun.ultimatespellsystem.api.runner.functions.GlobalFunction; import fr.jamailun.ultimatespellsystem.api.spells.SpellMetadata; import fr.jamailun.ultimatespellsystem.api.utils.MultivaluedMap; import fr.jamailun.ultimatespellsystem.dsl2.visitor.PrintingVisitor; @@ -12,6 +13,7 @@ import fr.jamailun.ultimatespellsystem.dsl2.validators.DslValidator; import fr.jamailun.ultimatespellsystem.plugin.configuration.UssConfig; import fr.jamailun.ultimatespellsystem.plugin.runner.builder.SpellBuilderVisitor; +import fr.jamailun.ultimatespellsystem.plugin.runner.builder.SpellStructure; import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.MetadataNode; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -26,6 +28,7 @@ public class SpellDefinition extends AbstractSpell { private final File file; private final List steps = new ArrayList<>(); + private final Collection functions; private final MultivaluedMap metadata = new MultivaluedMap<>(); /** @@ -34,9 +37,10 @@ public class SpellDefinition extends AbstractSpell { * @param name the name of the spell. * @param steps the steps to run. */ - public SpellDefinition(@NotNull File file, @NotNull String name, @NotNull List steps) { + public SpellDefinition(@NotNull File file, @NotNull String name, @NotNull List steps, @NotNull Collection functions) { super(name); this.file = file; + this.functions = functions; // Metadata are already sorted (thanks to AST validation) for(RuntimeStatement statement : steps) { if(statement instanceof MetadataNode meta) { @@ -78,8 +82,8 @@ private void checkSpellWarnings() { public static @Nullable SpellDefinition loadFile(@NotNull String name, @NotNull File file) { try { List dsl = UltimateSpellSystemDSL2.parse(file); - List steps = load(dsl); - SpellDefinition spell = new SpellDefinition(file, name, steps); + SpellStructure structure = load(dsl); + SpellDefinition spell = new SpellDefinition(file, name, structure.statements(), structure.functions()); if(UssConfig.displaySummonWarnings()) spell.checkSpellWarnings(); return spell; @@ -92,7 +96,7 @@ private void checkSpellWarnings() { } } - public static @NotNull List load(@NotNull List dsl) { + public static @NotNull SpellStructure load(@NotNull List dsl) { DslValidator.validateDsl(dsl); return SpellBuilderVisitor.build(dsl); } @@ -114,6 +118,9 @@ private void checkSpellWarnings() { protected boolean castSpell(@NotNull SpellEntity caster, @NotNull SpellRuntime runtime) { String prefix = "SpellRun-" + UUID.randomUUID().toString().substring(20) + " | "; + // Load functions + functions.forEach(runtime.functions()::register); + UssLogger.logDebug(prefix + " Casted on " + caster); for(RuntimeStatement statement : steps) { diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/spells/SpellsCooldowns.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/spells/SpellsCooldowns.java index 22add7e2..e779b042 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/spells/SpellsCooldowns.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/spells/SpellsCooldowns.java @@ -9,11 +9,21 @@ import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; -public class SpellsCooldowns { +/** + * Static handler for cooldowns. + */ +public final class SpellsCooldowns { private SpellsCooldowns() {} private static final Map> COOLDOWNS = new ConcurrentHashMap<>(128); + /** + * Test if an entity can cast. + * @param caster UUID of the potential caster. + * @param spellId ID of the spell to use. + * @param duration cooldown duration to apply on the next cooldown. + * @return true if the caster can cast this specific spell at this instant. + */ public static boolean canCast(@NotNull UUID caster, @NotNull String spellId, @NotNull Duration duration) { Map data = COOLDOWNS.computeIfAbsent(caster, x -> new HashMap<>()); Instant next = data.get(spellId); @@ -24,6 +34,10 @@ public static boolean canCast(@NotNull UUID caster, @NotNull String spellId, @No return false; } + /** + * Clear the data related to one caster. + * @param caster UUID of the caster to clear the memory of. + */ public static void removeCaster(@NotNull UUID caster) { COOLDOWNS.remove(caster); } diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/spells/external/ExternalExecutorImpl.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/spells/external/ExternalExecutorImpl.java index 2685ce12..bc507dbe 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/spells/external/ExternalExecutorImpl.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/spells/external/ExternalExecutorImpl.java @@ -34,7 +34,7 @@ public class ExternalExecutorImpl implements ExternalExecutor { @Override public @NotNull @UnmodifiableView List handleImplementation(@NotNull List dsl) { - return Collections.unmodifiableList(SpellDefinition.load(dsl)); + return Collections.unmodifiableList(SpellDefinition.load(dsl).statements()); } @Override diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/spells/functions/SpellFunction.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/spells/functions/SpellFunction.java index c1e003e0..cbcf89a2 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/spells/functions/SpellFunction.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/spells/functions/SpellFunction.java @@ -12,6 +12,7 @@ import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionArgument; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; +import fr.jamailun.ultimatespellsystem.plugin.runner.builder.SpellStructure; import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.MetadataNode; import fr.jamailun.ultimatespellsystem.plugin.spells.SpellDefinition; import lombok.Getter; @@ -83,7 +84,8 @@ public Object executeSteps(@NotNull SpellRuntime runtime) { try { List dsl = UltimateSpellSystemDSL2.parse(file); - List rawStatements = SpellDefinition.load(dsl); + SpellStructure structure = SpellDefinition.load(dsl); + List rawStatements = structure.statements(); // Metadata are already sorted (thanks to AST validation) for(RuntimeStatement statement : rawStatements) { diff --git a/plugin/src/test/java/fr/jamailun/ultimatespellsystem/extension/ExtensionParsingTests.java b/plugin/src/test/java/fr/jamailun/ultimatespellsystem/extension/ExtensionParsingTests.java index f38d9d11..c7338375 100644 --- a/plugin/src/test/java/fr/jamailun/ultimatespellsystem/extension/ExtensionParsingTests.java +++ b/plugin/src/test/java/fr/jamailun/ultimatespellsystem/extension/ExtensionParsingTests.java @@ -2,6 +2,7 @@ import fr.jamailun.ultimatespellsystem.api.runner.RuntimeStatement; import fr.jamailun.ultimatespellsystem.dsl2.errors.UssException; +import fr.jamailun.ultimatespellsystem.plugin.runner.builder.SpellStructure; import fr.jamailun.ultimatespellsystem.runner.framework.AssertException; import org.jetbrains.annotations.NotNull; import org.junit.jupiter.api.BeforeAll; @@ -43,7 +44,8 @@ void testLoops() { private void testFolder(@NotNull String folder, boolean run) { for(File file : listTests(folder)) { try { - List statements = parseAndVerify(file); + SpellStructure structure = parseAndVerify(file); + List statements = structure.statements(); if(run) cast(statements); addOk(); diff --git a/plugin/src/test/java/fr/jamailun/ultimatespellsystem/extension/ParseAndCompileTest.java b/plugin/src/test/java/fr/jamailun/ultimatespellsystem/extension/ParseAndCompileTest.java index 83ccce0f..717e6112 100644 --- a/plugin/src/test/java/fr/jamailun/ultimatespellsystem/extension/ParseAndCompileTest.java +++ b/plugin/src/test/java/fr/jamailun/ultimatespellsystem/extension/ParseAndCompileTest.java @@ -9,6 +9,7 @@ import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenStream; import fr.jamailun.ultimatespellsystem.dsl2.tokenization.Tokenizer; import fr.jamailun.ultimatespellsystem.plugin.runner.builder.SpellBuilderVisitor; +import fr.jamailun.ultimatespellsystem.plugin.runner.builder.SpellStructure; import fr.jamailun.ultimatespellsystem.runner.framework.TestFramework; import org.jetbrains.annotations.NotNull; import org.junit.jupiter.api.Assertions; @@ -52,7 +53,7 @@ protected void addFails(@NotNull File test, @NotNull String error) { failures.put(test, error); } - protected List parseAndVerify(@NotNull File file) throws UssException { + protected SpellStructure parseAndVerify(@NotNull File file) throws UssException { System.out.println("\n\n ================[ " + file.getName() + "]================\n"); // Tokenize TokenStream tokens = Tokenizer.tokenize(CharStream.from(file)); diff --git a/plugin/src/test/resources/extension-parsing/loops/basic_incr.uss b/plugin/src/test/resources/extension-parsing/loops/basic_incr.uss index 5c20e9e7..ba5f9501 100644 --- a/plugin/src/test/resources/extension-parsing/loops/basic_incr.uss +++ b/plugin/src/test/resources/extension-parsing/loops/basic_incr.uss @@ -1,7 +1,6 @@ -%val = 0; - -for(%i = 0; %i < 5; increment %i) { - increment %val; +int val = 0; +for(int i = 0; i < 5; i++) { + ++val; } -ASSERT_TRUE(%val == 5, "%val = " + %val + ", should be 5."); +ASSERT_TRUE(val == 5, "val = " + val + ", should be 5."); diff --git a/plugin/src/test/resources/extension-parsing/loops/for_break.uss b/plugin/src/test/resources/extension-parsing/loops/for_break.uss index cb84c120..07a3d74c 100644 --- a/plugin/src/test/resources/extension-parsing/loops/for_break.uss +++ b/plugin/src/test/resources/extension-parsing/loops/for_break.uss @@ -1,11 +1,11 @@ -for(%i = 0; %i < 5; increment %i) { - if(%i >= 0) +for(int i = 0; i < 5; ++i) { + if(i >= 0) break; ASSERT_NOT_CALLED("FOR::Break should work."); } -for(%i = 0; %i < 5; increment %i) { - if(%i >= 0) +for(i = 0; i < 5; %i++) { + if(i >= 0) continue; ASSERT_NOT_CALLED("FOR::Continue should work."); } diff --git a/plugin/src/test/resources/extension-parsing/loops/while_breaks.uss b/plugin/src/test/resources/extension-parsing/loops/while_breaks.uss index ba2e457e..383e4977 100644 --- a/plugin/src/test/resources/extension-parsing/loops/while_breaks.uss +++ b/plugin/src/test/resources/extension-parsing/loops/while_breaks.uss @@ -1,14 +1,14 @@ -%i = 0; -while(%i < 5) { - increment %i; - if(%i >= 0) +int i = 0; +while(i < 5) { + i++; + if(i >= 0) break; ASSERT_NOT_CALLED("WHILE::Break should work."); } do { - decrement %i; - if(%i >= 0) + --i; + if(i >= 0) continue; ASSERT_NOT_CALLED("WHILE::Continue should work."); -} while(%i > 0); +} while(i > 0); diff --git a/plugin/src/test/resources/extension-parsing/entities/summon-orb.uss b/plugin/src/test/resources/old/entities/summon-orb.uss similarity index 100% rename from plugin/src/test/resources/extension-parsing/entities/summon-orb.uss rename to plugin/src/test/resources/old/entities/summon-orb.uss diff --git a/plugin/src/test/resources/extension-parsing/lists/basic_list.uss b/plugin/src/test/resources/old/lists/basic_list.uss similarity index 100% rename from plugin/src/test/resources/extension-parsing/lists/basic_list.uss rename to plugin/src/test/resources/old/lists/basic_list.uss diff --git a/plugin/src/test/resources/extension-parsing/lists/entity_contains.uss b/plugin/src/test/resources/old/lists/entity_contains.uss similarity index 100% rename from plugin/src/test/resources/extension-parsing/lists/entity_contains.uss rename to plugin/src/test/resources/old/lists/entity_contains.uss diff --git a/plugin/src/test/resources/old/loops/basic_incr.uss b/plugin/src/test/resources/old/loops/basic_incr.uss new file mode 100644 index 00000000..ba5f9501 --- /dev/null +++ b/plugin/src/test/resources/old/loops/basic_incr.uss @@ -0,0 +1,6 @@ +int val = 0; +for(int i = 0; i < 5; i++) { + ++val; +} + +ASSERT_TRUE(val == 5, "val = " + val + ", should be 5."); diff --git a/plugin/src/test/resources/old/loops/for_break.uss b/plugin/src/test/resources/old/loops/for_break.uss new file mode 100644 index 00000000..cb84c120 --- /dev/null +++ b/plugin/src/test/resources/old/loops/for_break.uss @@ -0,0 +1,11 @@ +for(%i = 0; %i < 5; increment %i) { + if(%i >= 0) + break; + ASSERT_NOT_CALLED("FOR::Break should work."); +} + +for(%i = 0; %i < 5; increment %i) { + if(%i >= 0) + continue; + ASSERT_NOT_CALLED("FOR::Continue should work."); +} diff --git a/plugin/src/test/resources/extension-parsing/loops/foreach_break.uss b/plugin/src/test/resources/old/loops/foreach_break.uss similarity index 100% rename from plugin/src/test/resources/extension-parsing/loops/foreach_break.uss rename to plugin/src/test/resources/old/loops/foreach_break.uss diff --git a/plugin/src/test/resources/extension-parsing/loops/repeat_breaks.uss b/plugin/src/test/resources/old/loops/repeat_breaks.uss similarity index 100% rename from plugin/src/test/resources/extension-parsing/loops/repeat_breaks.uss rename to plugin/src/test/resources/old/loops/repeat_breaks.uss diff --git a/plugin/src/test/resources/old/loops/while_breaks.uss b/plugin/src/test/resources/old/loops/while_breaks.uss new file mode 100644 index 00000000..ba2e457e --- /dev/null +++ b/plugin/src/test/resources/old/loops/while_breaks.uss @@ -0,0 +1,14 @@ +%i = 0; +while(%i < 5) { + increment %i; + if(%i >= 0) + break; + ASSERT_NOT_CALLED("WHILE::Break should work."); +} + +do { + decrement %i; + if(%i >= 0) + continue; + ASSERT_NOT_CALLED("WHILE::Continue should work."); +} while(%i > 0); diff --git a/plugin/src/test/resources/extension-parsing/various/damage.uss b/plugin/src/test/resources/old/various/damage.uss similarity index 100% rename from plugin/src/test/resources/extension-parsing/various/damage.uss rename to plugin/src/test/resources/old/various/damage.uss diff --git a/plugin/src/test/resources/extension-parsing/various/entity_set_unset.uss b/plugin/src/test/resources/old/various/entity_set_unset.uss similarity index 100% rename from plugin/src/test/resources/extension-parsing/various/entity_set_unset.uss rename to plugin/src/test/resources/old/various/entity_set_unset.uss diff --git a/plugin/src/test/resources/extension-parsing/various/operators.uss b/plugin/src/test/resources/old/various/operators.uss similarity index 100% rename from plugin/src/test/resources/extension-parsing/various/operators.uss rename to plugin/src/test/resources/old/various/operators.uss diff --git a/plugin/src/test/resources/extension-parsing/various/repeat.uss b/plugin/src/test/resources/old/various/repeat.uss similarity index 100% rename from plugin/src/test/resources/extension-parsing/various/repeat.uss rename to plugin/src/test/resources/old/various/repeat.uss diff --git a/plugin/src/test/resources/extension-parsing/various/strike.uss b/plugin/src/test/resources/old/various/strike.uss similarity index 100% rename from plugin/src/test/resources/extension-parsing/various/strike.uss rename to plugin/src/test/resources/old/various/strike.uss From f938835851cc41515cc96a2e52b3c80c2c70f8dc Mon Sep 17 00:00:00 2001 From: "timothe.rosaz" Date: Sun, 2 Nov 2025 11:51:29 +0100 Subject: [PATCH 33/38] Fixed handler with function definitions. --- .../expressions/FunctionCallExpression.java | 6 +-- .../FunctionDeclarationStatement.java | 38 ++++++++----------- .../nodes/type/variables/TypesContext.java | 9 ++++- .../objects/GlobalFunctionCallNode.java | 7 ---- .../extension/ParseAndCompileTest.java | 1 - .../runner/framework/TestFramework.java | 7 ++-- .../extension-parsing/loops/for_break.uss | 2 +- 7 files changed, 29 insertions(+), 41 deletions(-) diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/FunctionCallExpression.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/FunctionCallExpression.java index d4bf5d33..fe401ac6 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/FunctionCallExpression.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/FunctionCallExpression.java @@ -75,11 +75,11 @@ public void validateTypes(@NotNull TypesContext context) { } // Pas de caller : function globale else { - FunctionDeclarationStatement declaration = context.findFunction(functionName); - if(declaration == null) { + FunctionDefinition definition = context.findFunction(functionName); + if(definition == null) { throw new SyntaxException(position, "Global function '" + functionName + "' not found"); } - function = declaration.asFunctionDefinition(); + function = definition; } // 3. Set our type diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/FunctionDeclarationStatement.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/FunctionDeclarationStatement.java index 095102bd..7899487e 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/FunctionDeclarationStatement.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/FunctionDeclarationStatement.java @@ -13,6 +13,7 @@ import fr.jamailun.ultimatespellsystem.dsl2.visitor.StatementVisitor; import lombok.AllArgsConstructor; import lombok.Getter; +import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; @@ -28,6 +29,14 @@ public class FunctionDeclarationStatement extends StatementNode { private final List parameters; private final List statements; + public @NotNull FunctionDefinition asDefinition() { + return new FunctionDefinition( + functionName, + Type.ofAny(functionReturnType), + parameters.stream().map(FunctionParameter::asArgument).toList() + ); + } + @Override public void visit(@NotNull StatementVisitor visitor) { visitor.handleFunctionDeclaration(this); @@ -40,9 +49,9 @@ public void visit(@NotNull StatementVisitor visitor) { @Override public void validateTypes(@NotNull TypesContext context) { // 1. Check function does not already exist - var existingFunction = context.findFunction(functionName); + FunctionDefinition existingFunction = context.findFunction(functionName); if (existingFunction != null) { - throw new SyntaxException(position, "The function '" + functionName + "' has already been defined. Signature is " + existingFunction.signature()); + throw new SyntaxException(position, "The function '" + functionName + "' has already been defined. Signature is " + existingFunction); } // 2. Register function and variables ! @@ -89,6 +98,10 @@ public record FunctionParameter(@NotNull String type, @NotNull String name) { public @NotNull Type getType() { return Type.ofAny(type); } + @Contract(" -> new") + public @NotNull FunctionArgument asArgument() { + return new FunctionArgument(Type.ofAny(type), name, false); + } } @Override @@ -99,25 +112,4 @@ public String toString() { statements.toString() + "}"; } - - public @NotNull String signature() { - return functionReturnType + " " + functionName + "(" + String.join(", ", getParameters().stream().map(Object::toString).toList()) + ")"; - } - - /** - * Create a function declaration instance from this function declaration. - * @return a new function definition. - */ - public @NotNull FunctionDefinition asFunctionDefinition() { - return new FunctionDefinition( - functionName, - getOutputType(), - parameters.stream() - .map(p -> new FunctionArgument( - p.getType(), - p.name(), - false - )).toList() - ); - } } diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/variables/TypesContext.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/variables/TypesContext.java index 6e9c6b87..29530511 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/variables/TypesContext.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/variables/TypesContext.java @@ -6,8 +6,10 @@ import fr.jamailun.ultimatespellsystem.dsl2.library.structs.ConsoleStruct; import fr.jamailun.ultimatespellsystem.dsl2.library.structs.EntityStruct; import fr.jamailun.ultimatespellsystem.dsl2.nodes.ExpressionNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.functions.FunctionDefinition; import fr.jamailun.ultimatespellsystem.dsl2.nodes.statements.FunctionDeclarationStatement; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; +import fr.jamailun.ultimatespellsystem.dsl2.registries.FunctionDefinitionsRegistry; import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenPosition; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; @@ -95,8 +97,11 @@ public void registerVariable(@NotNull TokenPosition position, @NotNull String va return objectsLibrary.getType(name); } - public @Nullable FunctionDeclarationStatement findFunction(@NotNull String name) { - return objectsLibrary.getFunction(name); + public @Nullable FunctionDefinition findFunction(@NotNull String name) { + FunctionDeclarationStatement local = objectsLibrary.getFunction(name); + if(local == null) + return FunctionDefinitionsRegistry.find(name); + return local.asDefinition(); } public @Nullable StructDefinition findStruct(@NotNull String name) { diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/objects/GlobalFunctionCallNode.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/objects/GlobalFunctionCallNode.java index 88f67e10..3f291917 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/objects/GlobalFunctionCallNode.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/objects/GlobalFunctionCallNode.java @@ -10,7 +10,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; import java.util.List; /** @@ -30,12 +29,6 @@ public class GlobalFunctionCallNode extends RuntimeExpression { if(function == null) throw new UnknownFunctionException(pos, signature.name()); - // Handle params - List params = new ArrayList<>(parameters.size()); - for(RuntimeExpression expression : parameters) { - params.add(expression.evaluate(runtime)); - } - // Call function return function.call(pos, parameters, runtime); } diff --git a/plugin/src/test/java/fr/jamailun/ultimatespellsystem/extension/ParseAndCompileTest.java b/plugin/src/test/java/fr/jamailun/ultimatespellsystem/extension/ParseAndCompileTest.java index 717e6112..3bdc8a48 100644 --- a/plugin/src/test/java/fr/jamailun/ultimatespellsystem/extension/ParseAndCompileTest.java +++ b/plugin/src/test/java/fr/jamailun/ultimatespellsystem/extension/ParseAndCompileTest.java @@ -1,6 +1,5 @@ package fr.jamailun.ultimatespellsystem.extension; -import fr.jamailun.ultimatespellsystem.api.runner.RuntimeStatement; import fr.jamailun.ultimatespellsystem.dsl2.UltimateSpellSystemDSL2; import fr.jamailun.ultimatespellsystem.dsl2.errors.UssException; import fr.jamailun.ultimatespellsystem.dsl2.nodes.StatementNode; diff --git a/plugin/src/test/java/fr/jamailun/ultimatespellsystem/runner/framework/TestFramework.java b/plugin/src/test/java/fr/jamailun/ultimatespellsystem/runner/framework/TestFramework.java index 4c775370..0ac24cee 100644 --- a/plugin/src/test/java/fr/jamailun/ultimatespellsystem/runner/framework/TestFramework.java +++ b/plugin/src/test/java/fr/jamailun/ultimatespellsystem/runner/framework/TestFramework.java @@ -62,11 +62,10 @@ static void initAll() { Mockito.when(fakePlugin.getScheduler()).thenReturn(Mockito.mock(Scheduler.class)); try { UltimateSpellSystem.setPlugin(fakePlugin); - - JavaFunctionProvider.instance().registerFunction(new AssertTrueFunction()); - JavaFunctionProvider.instance().registerFunction(new AssertNotCalledFunction()); - JavaFunctionProvider.instance().registerFunction(new PrintFunction()); } catch(IllegalStateException ignored) {} + JavaFunctionProvider.instance().registerFunction(new AssertTrueFunction()); + JavaFunctionProvider.instance().registerFunction(new AssertNotCalledFunction()); + JavaFunctionProvider.instance().registerFunction(new PrintFunction()); } @BeforeEach diff --git a/plugin/src/test/resources/extension-parsing/loops/for_break.uss b/plugin/src/test/resources/extension-parsing/loops/for_break.uss index 07a3d74c..697b6e22 100644 --- a/plugin/src/test/resources/extension-parsing/loops/for_break.uss +++ b/plugin/src/test/resources/extension-parsing/loops/for_break.uss @@ -4,7 +4,7 @@ for(int i = 0; i < 5; ++i) { ASSERT_NOT_CALLED("FOR::Break should work."); } -for(i = 0; i < 5; %i++) { +for(int i = 0; i < 5; i++) { if(i >= 0) continue; ASSERT_NOT_CALLED("FOR::Continue should work."); From b65975619640098014684ce7f32cde7dca0f2636 Mon Sep 17 00:00:00 2001 From: "timothe.rosaz" Date: Sun, 2 Nov 2025 11:58:19 +0100 Subject: [PATCH 34/38] Added more compiler syntax hints --- .../dsl/nodes/statements/BlockStatement.java | 2 +- .../ultimatespellsystem/dsl2/nodes/ExpressionNode.java | 2 +- .../dsl2/nodes/expressions/ParenthesisExpression.java | 2 +- .../nodes/expressions/litteral/LocationLiteral.java | 2 +- .../dsl2/nodes/statements/blocks/ForLoopStatement.java | 7 +++---- .../dsl2/nodes/statements/blocks/IfElseStatement.java | 4 ++-- .../nodes/statements/blocks/WhileLoopStatement.java | 10 +++++----- 7 files changed, 14 insertions(+), 15 deletions(-) diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/BlockStatement.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/BlockStatement.java index 9ce0ac4a..c4d9f1b4 100644 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/BlockStatement.java +++ b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/BlockStatement.java @@ -51,7 +51,7 @@ public void visit(@NotNull StatementVisitor visitor) { } list.add(StatementNode.parseNextStatement(tokens)); } - tokens.dropOrThrow(TokenType.BRACES_CLOSE); + tokens.dropOrThrow(TokenType.BRACES_CLOSE, "A '}' is required after a block statement."); return new BlockStatement(list); } diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/ExpressionNode.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/ExpressionNode.java index 25e998ac..23490d69 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/ExpressionNode.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/ExpressionNode.java @@ -70,7 +70,7 @@ protected ExpressionNode(@NotNull TokenPosition position) { // Check if the element is accessed ! if(tokens.dropOptional(TokenType.SQUARE_BRACKET_OPEN)) { ExpressionNode index = readNextExpression(tokens); - tokens.dropOrThrow(TokenType.SQUARE_BRACKET_CLOSE); + tokens.dropOrThrow(TokenType.SQUARE_BRACKET_CLOSE, "A ')' is required after an expression that started with a '('."); raw = new ArrayGetterExpression(raw, index); } diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/ParenthesisExpression.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/ParenthesisExpression.java index e5e1a565..fa593f43 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/ParenthesisExpression.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/ParenthesisExpression.java @@ -49,7 +49,7 @@ public String toString() { public static ParenthesisExpression parseParenthesis(TokenStream tokens) { TokenPosition pos = tokens.position(); ExpressionNode expression = ExpressionNode.readNextExpression(tokens); - tokens.dropOrThrow(TokenType.BRACKET_CLOSE); + tokens.dropOrThrow(TokenType.BRACKET_CLOSE, "Missing matching closing bracket."); return new ParenthesisExpression(pos, expression); } } diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/LocationLiteral.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/LocationLiteral.java index b91cd234..cb11290b 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/LocationLiteral.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/litteral/LocationLiteral.java @@ -71,7 +71,7 @@ public void validateTypes(@NotNull TypesContext context) { public static @NotNull LocationLiteral readNextLocation(@NotNull TokenStream tokens) { TokenPosition position = tokens.position(); // Open - tokens.dropOrThrow(TokenType.BRACKET_OPEN); + tokens.dropOrThrow(TokenType.BRACKET_OPEN, "A '(' is required after a '@' to create a location."); // World + vector ExpressionNode world = ExpressionNode.readNextExpression(tokens); diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/blocks/ForLoopStatement.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/blocks/ForLoopStatement.java index 3308b4c2..16ff4219 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/blocks/ForLoopStatement.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/blocks/ForLoopStatement.java @@ -47,7 +47,7 @@ public void visit(@NotNull StatementVisitor visitor) { */ @PreviousIndicator(expected = TokenType.FOR) public static @NotNull ForLoopStatement parseForLoop(@NotNull TokenStream tokens) { - tokens.dropOrThrow(TokenType.BRACKET_OPEN); + tokens.dropOrThrow(TokenType.BRACKET_OPEN, "This is not Python. A '(' is required after a FOR keyword."); // Optional init StatementNode init; @@ -60,16 +60,15 @@ public void visit(@NotNull StatementVisitor visitor) { // Required condition ExpressionNode condition = ExpressionNode.readNextExpression(tokens); - tokens.dropOrThrow(TokenType.SEMI_COLON); + tokens.dropOrThrow(TokenType.SEMI_COLON, "A semi-colo (';') is required between FOR definition statements."); // Optional iteration StatementNode iterator; if(tokens.dropOptional(TokenType.BRACKET_CLOSE)) { iterator = null; } else { - System.out.println("salut salut :: " + tokens); iterator = StatementNode.parseNextStatement(tokens); - tokens.dropOrThrow(TokenType.BRACKET_CLOSE); + tokens.dropOrThrow(TokenType.BRACKET_CLOSE, "Expected a ')' after the last FOR definition statements."); } StatementNode child = StatementNode.parseNextStatement(tokens); diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/blocks/IfElseStatement.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/blocks/IfElseStatement.java index 636ea8e7..d753cf56 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/blocks/IfElseStatement.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/blocks/IfElseStatement.java @@ -54,9 +54,9 @@ public void visit(@NotNull StatementVisitor visitor) { @PreviousIndicator(expected = TokenType.IF) public static @NotNull IfElseStatement parseIfStatement(@NotNull TokenStream tokens) { // Condition - tokens.dropOrThrow(TokenType.BRACKET_OPEN); + tokens.dropOrThrow(TokenType.BRACKET_OPEN, "This is not Python, a '(' is required after the IF keyword."); ExpressionNode condition = ExpressionNode.readNextExpression(tokens); - tokens.dropOrThrow(TokenType.BRACKET_CLOSE); + tokens.dropOrThrow(TokenType.BRACKET_CLOSE, "A ')' is expected after the IF condition."); // Content StatementNode child = StatementNode.parseNextStatement(tokens); diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/blocks/WhileLoopStatement.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/blocks/WhileLoopStatement.java index ed1be4a8..5669b20d 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/blocks/WhileLoopStatement.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/statements/blocks/WhileLoopStatement.java @@ -48,18 +48,18 @@ public static WhileLoopStatement parseWhileLoop(TokenStream tokens, boolean wasW ExpressionNode condition = null; if(wasWhile) { - tokens.dropOrThrow(TokenType.BRACKET_OPEN); + tokens.dropOrThrow(TokenType.BRACKET_OPEN, "A '(' is required after a WHILE keyword."); condition = ExpressionNode.readNextExpression(tokens); - tokens.dropOrThrow(TokenType.BRACKET_CLOSE); + tokens.dropOrThrow(TokenType.BRACKET_CLOSE, "A ')' is required after a WHILE condition."); } StatementNode child = StatementNode.parseNextStatement(tokens); if( ! wasWhile) { - tokens.dropOrThrow(TokenType.WHILE); - tokens.dropOrThrow(TokenType.BRACKET_OPEN); + tokens.dropOrThrow(TokenType.WHILE, "A WHILE keyword is expected after a DO statement."); + tokens.dropOrThrow(TokenType.BRACKET_OPEN, "A '(' is required after a DO keyword."); condition = ExpressionNode.readNextExpression(tokens); - tokens.dropOrThrow(TokenType.BRACKET_CLOSE); + tokens.dropOrThrow(TokenType.BRACKET_CLOSE, "A ')' is required after a DO condition."); tokens.dropOptional(TokenType.SEMI_COLON); } From e6f851b5ea8d526168f499e59fbea05aaff5a714 Mon Sep 17 00:00:00 2001 From: "timothe.rosaz" Date: Sun, 2 Nov 2025 11:59:42 +0100 Subject: [PATCH 35/38] Deleted old DSL folder --- dsl/README.md | 4 - dsl/pom.xml | 57 -- .../dsl/UltimateSpellSystemDSL.java | 78 --- .../errors/MetadataRuleFailureException.java | 18 - .../dsl/errors/ParsingException.java | 30 - .../dsl/errors/SyntaxException.java | 50 -- .../dsl/errors/TreeValidationException.java | 18 - .../dsl/errors/TypeException.java | 39 -- .../dsl/errors/UnknownFunctionException.java | 19 - .../dsl/errors/UssException.java | 31 - .../dsl/metadata/MetadataRule.java | 25 - .../dsl/metadata/MetadataRulesManager.java | 42 -- .../metadata/rules/DefaultMetadataRules.java | 24 - .../rules/ParamDefinitionMetadata.java | 41 -- .../dsl/nodes/ExpressionNode.java | 253 -------- .../ultimatespellsystem/dsl/nodes/Node.java | 70 --- .../dsl/nodes/StatementNode.java | 79 --- .../nodes/expressions/ArrayExpression.java | 87 --- .../expressions/ArrayGetterExpression.java | 55 -- .../expressions/ParenthesisExpression.java | 55 -- .../expressions/PropertiesExpression.java | 83 --- .../nodes/expressions/VariableExpression.java | 60 -- .../compute/AllEntitiesAroundExpression.java | 88 --- .../compute/PositionOfExpression.java | 59 -- .../expressions/compute/SizeOfExpression.java | 61 -- .../functions/FunctionArgument.java | 18 - .../functions/FunctionCallExpression.java | 99 ---- .../functions/FunctionDefinition.java | 27 - .../expressions/functions/FunctionType.java | 96 --- .../litteral/BooleanExpression.java | 44 -- .../litteral/DurationExpression.java | 46 -- .../litteral/EntityTypeExpression.java | 46 -- .../litteral/LiteralExpression.java | 38 -- .../expressions/litteral/LocationLiteral.java | 105 ---- .../expressions/litteral/NullExpression.java | 39 -- .../litteral/NumberExpression.java | 55 -- .../expressions/litteral/RuntimeLiteral.java | 44 -- .../litteral/StringExpression.java | 44 -- .../expressions/operators/AddOperator.java | 61 -- .../expressions/operators/BiOperator.java | 108 ---- .../expressions/operators/ListOperator.java | 79 --- .../operators/LogicalOperator.java | 75 --- .../operators/MathFunctionOperator.java | 55 -- .../expressions/operators/MonoOperator.java | 71 --- .../expressions/operators/MulDivOperator.java | 69 --- .../expressions/operators/NotOperator.java | 51 -- .../nodes/expressions/operators/Operator.java | 43 -- .../expressions/operators/SubOperator.java | 59 -- .../dsl/nodes/statements/BlockStatement.java | 65 -- .../statements/BreakContinueStatement.java | 47 -- .../dsl/nodes/statements/DefineStatement.java | 71 --- .../dsl/nodes/statements/GiveStatement.java | 96 --- .../nodes/statements/IncrementStatement.java | 58 -- .../nodes/statements/MetadataStatement.java | 89 --- .../dsl/nodes/statements/PlayStatement.java | 97 --- .../statements/SendAttributeStatement.java | 89 --- .../nodes/statements/SendEffectStatement.java | 82 --- .../statements/SendMessageStatement.java | 56 -- .../nodes/statements/SendNbtStatement.java | 68 --- .../dsl/nodes/statements/SendStatement.java | 55 -- .../statements/SimpleExpressionStatement.java | 40 -- .../dsl/nodes/statements/StopStatement.java | 57 -- .../dsl/nodes/statements/SummonStatement.java | 104 ---- .../nodes/statements/TeleportStatement.java | 55 -- .../nodes/statements/blocks/BlockHolder.java | 34 -- .../statements/blocks/CallbackStatement.java | 108 ---- .../statements/blocks/ForLoopStatement.java | 82 --- .../blocks/ForeachLoopStatement.java | 75 --- .../statements/blocks/IfElseStatement.java | 78 --- .../statements/blocks/RepeatStatement.java | 111 ---- .../statements/blocks/RunLaterStatement.java | 61 -- .../statements/blocks/WhileLoopStatement.java | 79 --- .../dsl/nodes/type/CollectionFilter.java | 38 -- .../dsl/nodes/type/Duration.java | 136 ----- .../dsl/nodes/type/SpellEntity.java | 79 --- .../dsl/nodes/type/Type.java | 45 -- .../dsl/nodes/type/TypePrimitive.java | 87 --- .../nodes/type/variables/TypesContext.java | 89 --- .../type/variables/VariableDefinition.java | 59 -- .../type/variables/VariableReference.java | 78 --- .../dsl/objects/CallbackEvent.java | 58 -- .../dsl/registries/CallbackEventRegistry.java | 58 -- .../dsl/registries/EntityTypeRegistry.java | 65 -- .../FunctionDefinitionsRegistry.java | 55 -- .../dsl/registries/RegistryException.java | 21 - .../dsl/tokenization/CharStream.java | 112 ---- .../dsl/tokenization/PreviousIndicator.java | 23 - .../dsl/tokenization/Token.java | 156 ----- .../dsl/tokenization/TokenPosition.java | 26 - .../dsl/tokenization/TokenStream.java | 126 ---- .../dsl/tokenization/TokenType.java | 132 ----- .../dsl/tokenization/Tokenizer.java | 293 --------- .../dsl/validators/DslValidator.java | 45 -- .../StructureValidationVisitor.java | 114 ---- .../dsl/visitor/ExpressionVisitor.java | 45 -- .../dsl/visitor/PrintingVisitor.java | 557 ------------------ .../dsl/visitor/StatementVisitor.java | 35 -- .../dsl/CorrectParsingTests.java | 79 --- .../dsl/FailuresParsingTests.java | 59 -- .../ultimatespellsystem/dsl/ParsingTest.java | 97 --- .../dsl/nodes/type/DurationTests.java | 38 -- .../parsing/bad_mix/invalid_param_meta.uss | 3 - .../parsing/bad_mix/unknown_function.uss | 1 - .../parsing/bad_parsing/bad_number.uss | 1 - .../parsing/bad_parsing/bad_string.uss | 2 - .../resources/parsing/bad_syntax/bad_else.uss | 3 - .../parsing/bad_syntax/bad_entity_type.uss | 3 - .../resources/parsing/bad_syntax/bad_send.uss | 3 - .../resources/parsing/bad_syntax/bad_var.uss | 2 - .../parsing/bad_syntax/redefine_caster.uss | 1 - .../parsing/bad_tree/after_break.uss | 6 - .../parsing/bad_tree/after_meta_1.uss | 5 - .../parsing/bad_tree/after_meta_2.uss | 5 - .../parsing/bad_tree/after_stop_1.uss | 2 - .../parsing/bad_tree/after_stop_2.uss | 3 - .../parsing/bad_tree/after_stop_3.uss | 5 - .../bad_type/bad_collection_teleport.uss | 4 - .../parsing/bad_type/bad_list_append.uss | 3 - .../resources/parsing/bad_type/bad_ope.uss | 5 - .../resources/parsing/bad_type/bad_ope_2.uss | 6 - .../resources/parsing/bad_type/bad_ope_3.uss | 7 - .../parsing/bad_type/increment_type.uss | 2 - .../parsing/bad_type/redefine_difftype.uss | 2 - .../resources/parsing/bad_type/stop_type.uss | 1 - .../resources/parsing/corrects/blocks/for.uss | 14 - .../parsing/corrects/blocks/for_break.uss | 5 - .../parsing/corrects/blocks/foreach.uss | 6 - .../parsing/corrects/blocks/ifelse_p1.uss | 7 - .../parsing/corrects/blocks/ifelse_p2.uss | 20 - .../parsing/corrects/blocks/repeat.uss | 13 - .../parsing/corrects/blocks/repeat_2.uss | 9 - .../parsing/corrects/blocks/run_later.uss | 9 - .../parsing/corrects/blocks/while.uss | 15 - .../corrects/metadata/param_metadata.uss | 3 - .../resources/parsing/corrects/mix/cercle.uss | 12 - .../parsing/corrects/mix/collections.uss | 8 - .../resources/parsing/corrects/mix/empty.uss | 0 .../parsing/corrects/mix/implicit_define.uss | 2 - .../parsing/corrects/mix/metadata.uss | 5 - .../parsing/corrects/mix/null_recovery.uss | 6 - .../parsing/corrects/mix/null_set.uss | 7 - .../parsing/corrects/mix/particle_shape.uss | 8 - .../parsing/corrects/mix/test_allof.uss | 6 - .../parsing/corrects/mix/test_basic.uss | 4 - .../parsing/corrects/mix/test_complex_tp.uss | 27 - .../corrects/mix/test_location_literal.uss | 2 - .../parsing/corrects/mix/test_null.uss | 5 - .../parsing/corrects/mix/test_teleport.uss | 6 - .../corrects/operators/bool_operators.uss | 2 - .../parsing/corrects/operators/conditions.uss | 13 - .../corrects/operators/list_append.uss | 16 - .../parsing/corrects/operators/math.uss | 3 - .../corrects/operators/operator_priority.uss | 11 - .../corrects/operators/parenthesis.uss | 6 - .../corrects/operators/type_operators.uss | 5 - .../parsing/corrects/statements/define.uss | 12 - .../parsing/corrects/statements/give.uss | 10 - .../parsing/corrects/statements/increment.uss | 3 - .../parsing/corrects/statements/play.uss | 17 - .../parsing/corrects/statements/send.uss | 22 - .../parsing/corrects/statements/send_nbt.uss | 1 - .../parsing/corrects/statements/stop_1.uss | 2 - .../parsing/corrects/statements/stop_2.uss | 2 - .../parsing/corrects/statements/stop_3.uss | 3 - .../parsing/corrects/statements/summon.uss | 9 - .../parsing/corrects/statements/teleport.uss | 4 - .../parsing/corrects_with_custom/callback.uss | 6 - .../parsing/corrects_with_custom/custom.uss | 4 - 168 files changed, 7785 deletions(-) delete mode 100644 dsl/README.md delete mode 100644 dsl/pom.xml delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/UltimateSpellSystemDSL.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/errors/MetadataRuleFailureException.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/errors/ParsingException.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/errors/SyntaxException.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/errors/TreeValidationException.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/errors/TypeException.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/errors/UnknownFunctionException.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/errors/UssException.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/metadata/MetadataRule.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/metadata/MetadataRulesManager.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/metadata/rules/DefaultMetadataRules.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/metadata/rules/ParamDefinitionMetadata.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/ExpressionNode.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/Node.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/StatementNode.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/ArrayExpression.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/ArrayGetterExpression.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/ParenthesisExpression.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/PropertiesExpression.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/VariableExpression.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/compute/AllEntitiesAroundExpression.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/compute/PositionOfExpression.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/compute/SizeOfExpression.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/functions/FunctionArgument.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/functions/FunctionCallExpression.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/functions/FunctionDefinition.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/functions/FunctionType.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/litteral/BooleanExpression.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/litteral/DurationExpression.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/litteral/EntityTypeExpression.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/litteral/LiteralExpression.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/litteral/LocationLiteral.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/litteral/NullExpression.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/litteral/NumberExpression.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/litteral/RuntimeLiteral.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/litteral/StringExpression.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/operators/AddOperator.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/operators/BiOperator.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/operators/ListOperator.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/operators/LogicalOperator.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/operators/MathFunctionOperator.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/operators/MonoOperator.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/operators/MulDivOperator.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/operators/NotOperator.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/operators/Operator.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/operators/SubOperator.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/BlockStatement.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/BreakContinueStatement.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/DefineStatement.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/GiveStatement.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/IncrementStatement.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/MetadataStatement.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/PlayStatement.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/SendAttributeStatement.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/SendEffectStatement.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/SendMessageStatement.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/SendNbtStatement.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/SendStatement.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/SimpleExpressionStatement.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/StopStatement.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/SummonStatement.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/TeleportStatement.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/blocks/BlockHolder.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/blocks/CallbackStatement.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/blocks/ForLoopStatement.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/blocks/ForeachLoopStatement.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/blocks/IfElseStatement.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/blocks/RepeatStatement.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/blocks/RunLaterStatement.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/blocks/WhileLoopStatement.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/type/CollectionFilter.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/type/Duration.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/type/SpellEntity.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/type/Type.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/type/TypePrimitive.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/type/variables/TypesContext.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/type/variables/VariableDefinition.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/type/variables/VariableReference.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/objects/CallbackEvent.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/registries/CallbackEventRegistry.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/registries/EntityTypeRegistry.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/registries/FunctionDefinitionsRegistry.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/registries/RegistryException.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/tokenization/CharStream.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/tokenization/PreviousIndicator.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/tokenization/Token.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/tokenization/TokenPosition.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/tokenization/TokenStream.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/tokenization/TokenType.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/tokenization/Tokenizer.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/validators/DslValidator.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/validators/StructureValidationVisitor.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/visitor/ExpressionVisitor.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/visitor/PrintingVisitor.java delete mode 100644 dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/visitor/StatementVisitor.java delete mode 100644 dsl/src/test/java/fr/jamailun/ultimatespellsystem/dsl/CorrectParsingTests.java delete mode 100644 dsl/src/test/java/fr/jamailun/ultimatespellsystem/dsl/FailuresParsingTests.java delete mode 100644 dsl/src/test/java/fr/jamailun/ultimatespellsystem/dsl/ParsingTest.java delete mode 100644 dsl/src/test/java/fr/jamailun/ultimatespellsystem/dsl/nodes/type/DurationTests.java delete mode 100644 dsl/src/test/resources/parsing/bad_mix/invalid_param_meta.uss delete mode 100644 dsl/src/test/resources/parsing/bad_mix/unknown_function.uss delete mode 100644 dsl/src/test/resources/parsing/bad_parsing/bad_number.uss delete mode 100644 dsl/src/test/resources/parsing/bad_parsing/bad_string.uss delete mode 100644 dsl/src/test/resources/parsing/bad_syntax/bad_else.uss delete mode 100644 dsl/src/test/resources/parsing/bad_syntax/bad_entity_type.uss delete mode 100644 dsl/src/test/resources/parsing/bad_syntax/bad_send.uss delete mode 100644 dsl/src/test/resources/parsing/bad_syntax/bad_var.uss delete mode 100644 dsl/src/test/resources/parsing/bad_syntax/redefine_caster.uss delete mode 100644 dsl/src/test/resources/parsing/bad_tree/after_break.uss delete mode 100644 dsl/src/test/resources/parsing/bad_tree/after_meta_1.uss delete mode 100644 dsl/src/test/resources/parsing/bad_tree/after_meta_2.uss delete mode 100644 dsl/src/test/resources/parsing/bad_tree/after_stop_1.uss delete mode 100644 dsl/src/test/resources/parsing/bad_tree/after_stop_2.uss delete mode 100644 dsl/src/test/resources/parsing/bad_tree/after_stop_3.uss delete mode 100644 dsl/src/test/resources/parsing/bad_type/bad_collection_teleport.uss delete mode 100644 dsl/src/test/resources/parsing/bad_type/bad_list_append.uss delete mode 100644 dsl/src/test/resources/parsing/bad_type/bad_ope.uss delete mode 100644 dsl/src/test/resources/parsing/bad_type/bad_ope_2.uss delete mode 100644 dsl/src/test/resources/parsing/bad_type/bad_ope_3.uss delete mode 100644 dsl/src/test/resources/parsing/bad_type/increment_type.uss delete mode 100644 dsl/src/test/resources/parsing/bad_type/redefine_difftype.uss delete mode 100644 dsl/src/test/resources/parsing/bad_type/stop_type.uss delete mode 100644 dsl/src/test/resources/parsing/corrects/blocks/for.uss delete mode 100644 dsl/src/test/resources/parsing/corrects/blocks/for_break.uss delete mode 100644 dsl/src/test/resources/parsing/corrects/blocks/foreach.uss delete mode 100644 dsl/src/test/resources/parsing/corrects/blocks/ifelse_p1.uss delete mode 100644 dsl/src/test/resources/parsing/corrects/blocks/ifelse_p2.uss delete mode 100644 dsl/src/test/resources/parsing/corrects/blocks/repeat.uss delete mode 100644 dsl/src/test/resources/parsing/corrects/blocks/repeat_2.uss delete mode 100644 dsl/src/test/resources/parsing/corrects/blocks/run_later.uss delete mode 100644 dsl/src/test/resources/parsing/corrects/blocks/while.uss delete mode 100644 dsl/src/test/resources/parsing/corrects/metadata/param_metadata.uss delete mode 100644 dsl/src/test/resources/parsing/corrects/mix/cercle.uss delete mode 100644 dsl/src/test/resources/parsing/corrects/mix/collections.uss delete mode 100644 dsl/src/test/resources/parsing/corrects/mix/empty.uss delete mode 100644 dsl/src/test/resources/parsing/corrects/mix/implicit_define.uss delete mode 100644 dsl/src/test/resources/parsing/corrects/mix/metadata.uss delete mode 100644 dsl/src/test/resources/parsing/corrects/mix/null_recovery.uss delete mode 100644 dsl/src/test/resources/parsing/corrects/mix/null_set.uss delete mode 100644 dsl/src/test/resources/parsing/corrects/mix/particle_shape.uss delete mode 100644 dsl/src/test/resources/parsing/corrects/mix/test_allof.uss delete mode 100644 dsl/src/test/resources/parsing/corrects/mix/test_basic.uss delete mode 100644 dsl/src/test/resources/parsing/corrects/mix/test_complex_tp.uss delete mode 100644 dsl/src/test/resources/parsing/corrects/mix/test_location_literal.uss delete mode 100644 dsl/src/test/resources/parsing/corrects/mix/test_null.uss delete mode 100644 dsl/src/test/resources/parsing/corrects/mix/test_teleport.uss delete mode 100644 dsl/src/test/resources/parsing/corrects/operators/bool_operators.uss delete mode 100644 dsl/src/test/resources/parsing/corrects/operators/conditions.uss delete mode 100644 dsl/src/test/resources/parsing/corrects/operators/list_append.uss delete mode 100644 dsl/src/test/resources/parsing/corrects/operators/math.uss delete mode 100644 dsl/src/test/resources/parsing/corrects/operators/operator_priority.uss delete mode 100644 dsl/src/test/resources/parsing/corrects/operators/parenthesis.uss delete mode 100644 dsl/src/test/resources/parsing/corrects/operators/type_operators.uss delete mode 100644 dsl/src/test/resources/parsing/corrects/statements/define.uss delete mode 100644 dsl/src/test/resources/parsing/corrects/statements/give.uss delete mode 100644 dsl/src/test/resources/parsing/corrects/statements/increment.uss delete mode 100644 dsl/src/test/resources/parsing/corrects/statements/play.uss delete mode 100644 dsl/src/test/resources/parsing/corrects/statements/send.uss delete mode 100644 dsl/src/test/resources/parsing/corrects/statements/send_nbt.uss delete mode 100644 dsl/src/test/resources/parsing/corrects/statements/stop_1.uss delete mode 100644 dsl/src/test/resources/parsing/corrects/statements/stop_2.uss delete mode 100644 dsl/src/test/resources/parsing/corrects/statements/stop_3.uss delete mode 100644 dsl/src/test/resources/parsing/corrects/statements/summon.uss delete mode 100644 dsl/src/test/resources/parsing/corrects/statements/teleport.uss delete mode 100644 dsl/src/test/resources/parsing/corrects_with_custom/callback.uss delete mode 100644 dsl/src/test/resources/parsing/corrects_with_custom/custom.uss diff --git a/dsl/README.md b/dsl/README.md deleted file mode 100644 index 1e1fc3ae..00000000 --- a/dsl/README.md +++ /dev/null @@ -1,4 +0,0 @@ -# USS - DSL - - ![](https://img.shields.io/badge/Code%20overage-90%25-lime?style=for-the-badge&link=https://github.com/jamailun/UltimateSpellSystem/tree/master/dsl) - diff --git a/dsl/pom.xml b/dsl/pom.xml deleted file mode 100644 index b421010d..00000000 --- a/dsl/pom.xml +++ /dev/null @@ -1,57 +0,0 @@ - - - 4.0.0 - - ultimate-spell-system-dsl - 2.6.1-SNAPSHOT - - - fr.jamailun.paper - ultimate-spell-system - 2.6.0 - - - - 21 - 21 - UTF-8 - - - 0.8.12 - 3.5.2 - - - - - - org.jacoco - jacoco-maven-plugin - ${jacoco.version} - - - - prepare-agent - - - - - report - test - - report - - - - - - - org.apache.maven.plugins - maven-surefire-plugin - ${surefire.version} - - - - - diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/UltimateSpellSystemDSL.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/UltimateSpellSystemDSL.java deleted file mode 100644 index b95d7a02..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/UltimateSpellSystemDSL.java +++ /dev/null @@ -1,78 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl; - -import fr.jamailun.ultimatespellsystem.dsl.metadata.rules.DefaultMetadataRules; -import fr.jamailun.ultimatespellsystem.dsl.nodes.ExpressionNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.StatementNode; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.*; -import org.jetbrains.annotations.NotNull; - -import java.io.File; -import java.util.ArrayList; -import java.util.List; - -/** - * Central access to the DSL. - */ -public final class UltimateSpellSystemDSL { - private UltimateSpellSystemDSL() {} - - // Load the default metadata rules on class load. - static { - DefaultMetadataRules.initialize(); - } - - /** - * Parse a stream of tokens. - * @param tokens the tokens to parse. - * @return a parsed collection of statements. - */ - public static @NotNull List parse(@NotNull TokenStream tokens) { - List statements = new ArrayList<>(); - while(tokens.hasMore()) { - if(tokens.peek().getType() == TokenType.EOF) - break; - StatementNode node = StatementNode.parseNextStatement(tokens); - statements.add(node); - } - return statements; - } - - /** - * Parse a stream of characters. - * @param chars the characters to parse. - * @return a parsed collection of statements. - */ - public static @NotNull List parse(@NotNull CharStream chars) { - TokenStream tokens = Tokenizer.tokenize(chars); - return parse(tokens); - } - - /** - * Parse a string. - * @param string the string to parse. - * @return a parsed collection of statements. - */ - public static @NotNull List parse(@NotNull String string) { - return parse(CharStream.from(string)); - } - - /** - * Parse a file. - * @param file the file to read and parse. - * @return a parsed collection of statements. - */ - public static @NotNull List parse(@NotNull File file) { - return parse(CharStream.from(file)); - } - - /** - * Parse any expression... Will stop at the first one ! - * @param string string to parse. - * @return a non-null expression. - */ - public static @NotNull ExpressionNode parseExpression(@NotNull String string) { - TokenStream tokens = Tokenizer.tokenize(CharStream.from(string)); - return ExpressionNode.readNextExpression(tokens); - } - -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/errors/MetadataRuleFailureException.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/errors/MetadataRuleFailureException.java deleted file mode 100644 index be6c33f4..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/errors/MetadataRuleFailureException.java +++ /dev/null @@ -1,18 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.errors; - -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenPosition; -import org.jetbrains.annotations.NotNull; - -/** - * Exception for invalid metadata. - */ -public class MetadataRuleFailureException extends UssException { - /** - * New exception instance. - * @param pos token position. - * @param message metadata error message. - */ - public MetadataRuleFailureException(@NotNull TokenPosition pos, @NotNull String message) { - super(pos, message); - } -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/errors/ParsingException.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/errors/ParsingException.java deleted file mode 100644 index 07cdccd7..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/errors/ParsingException.java +++ /dev/null @@ -1,30 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.errors; - -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenPosition; -import org.jetbrains.annotations.NotNull; - -/** - * Exception throw in the parsing phase. - */ -public class ParsingException extends UssException { - - /** - * New exception instance with an unexpected character. - * @param pos token position. - * @param c unexpected character. - * @param message additional message. - */ - public ParsingException(@NotNull TokenPosition pos, char c, @NotNull String message) { - super(pos, "Unexpected character : '" + c + "'. " + message); - } - - /** - * New parsing exception. - * @param pos token position. - * @param message message to display. - */ - public ParsingException(@NotNull TokenPosition pos, @NotNull String message) { - super(pos, message); - } - -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/errors/SyntaxException.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/errors/SyntaxException.java deleted file mode 100644 index ee60e982..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/errors/SyntaxException.java +++ /dev/null @@ -1,50 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.errors; - -import fr.jamailun.ultimatespellsystem.dsl.tokenization.Token; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenPosition; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenType; - -import java.util.List; - -/** - * Syntax exception : the spell has a user error. - */ -public class SyntaxException extends UssException { - - /** - * Standard syntax exception. - * @param position token position. - * @param message exception description. - */ - public SyntaxException(TokenPosition position, String message) { - super(position, message); - } - - /** - * Standard syntax exception. - * @param token token source of the error. - * @param message exception description. - */ - public SyntaxException(Token token, String message) { - super(token, message); - } - - /** - * Bad token exception. - * @param token problematic token. - * @param expected expected token type. - */ - public SyntaxException(Token token, TokenType expected) { - super(token, "Expected a " + expected + "."); - } - - /** - * Bad token exception. - * @param token problematic token. - * @param expected expected token type list (OR). - */ - public SyntaxException(Token token, List expected) { - super(token, "Expected one of: " + expected + "."); - } - -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/errors/TreeValidationException.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/errors/TreeValidationException.java deleted file mode 100644 index 9e0c09b6..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/errors/TreeValidationException.java +++ /dev/null @@ -1,18 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.errors; - -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenPosition; - -/** - * Tree validation : relation between statements. - */ -public class TreeValidationException extends UssException { - - /** - * Tree validation failure. - * @param pos token position. - * @param message error description. - */ - public TreeValidationException(TokenPosition pos, String message) { - super(pos, message); - } -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/errors/TypeException.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/errors/TypeException.java deleted file mode 100644 index c3b87d5e..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/errors/TypeException.java +++ /dev/null @@ -1,39 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.errors; - -import fr.jamailun.ultimatespellsystem.dsl.nodes.ExpressionNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenPosition; - -/** - * Bad type in a spell. - */ -public class TypeException extends UssException { - - /** - * Unexpected expression type. - * @param expression expression source of tbe error. Must have a type set. - * @param expected expected type instead. - */ - public TypeException(ExpressionNode expression, TypePrimitive expected) { - super(expression.firstTokenPosition(), "Expression " + expression + " has type " + expression.getExpressionType() + ", expected " + expected); - } - - /** - * Unexpected expression type. - * @param expression expression source of tbe exception. Must have a type set. - * @param message exception details. - */ - public TypeException(ExpressionNode expression, String message) { - super(expression.firstTokenPosition(), "Expression " + expression + " of type " + expression.getExpressionType() + " : " + message); - } - - /** - * Bad token type. - * @param pos position of tbe token. - * @param message exception details. - */ - public TypeException(TokenPosition pos, String message) { - super(pos, message); - } - -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/errors/UnknownFunctionException.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/errors/UnknownFunctionException.java deleted file mode 100644 index f5a6cdcb..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/errors/UnknownFunctionException.java +++ /dev/null @@ -1,19 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.errors; - -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenPosition; -import org.jetbrains.annotations.NotNull; - -/** - * An exception threw when a function has not been registered. - */ -public class UnknownFunctionException extends UssException { - - /** - * New exception. - * @param pos token position. - * @param functionId ID of the unknown function. - */ - public UnknownFunctionException(@NotNull TokenPosition pos, @NotNull String functionId) { - super(pos, "Unknown function ID: '"+functionId+"'."); - } -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/errors/UssException.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/errors/UssException.java deleted file mode 100644 index c38802b6..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/errors/UssException.java +++ /dev/null @@ -1,31 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.errors; - -import fr.jamailun.ultimatespellsystem.dsl.tokenization.Token; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenPosition; -import org.jetbrains.annotations.NotNull; - -/** - * Abstract exception for USS related problems. - * Provides access to the position in the source. - */ -public abstract class UssException extends RuntimeException { - - /** - * New instance with a token position only. - * @param pos token position. - * @param message exception details. - */ - public UssException(@NotNull TokenPosition pos, @NotNull String message) { - super("At " + pos + ". " + message); - } - - /** - * New instance with a real token instance. - * @param token token source of the exception. - * @param message exception details. - */ - public UssException(@NotNull Token token, @NotNull String message) { - super("With " + token + " at " + token.pos() + ". " + message); - } - -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/metadata/MetadataRule.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/metadata/MetadataRule.java deleted file mode 100644 index 93477a50..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/metadata/MetadataRule.java +++ /dev/null @@ -1,25 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.metadata; - -import fr.jamailun.ultimatespellsystem.dsl.nodes.statements.MetadataStatement; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.variables.TypesContext; -import org.jetbrains.annotations.NotNull; - -/** - * A metadata rule uses the metadata statements to change the behaviour of the spell compilation. - */ -public interface MetadataRule { - - /** - * Get the name this rule will apply to. - * @return a non-null string. - */ - @NotNull String getName(); - - /** - * Apply this rule to a context. - * @param context the context. - * @param metadata the statement to apply the rule to. - */ - void apply(@NotNull TypesContext context, @NotNull MetadataStatement metadata); - -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/metadata/MetadataRulesManager.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/metadata/MetadataRulesManager.java deleted file mode 100644 index d9602473..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/metadata/MetadataRulesManager.java +++ /dev/null @@ -1,42 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.metadata; - -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Unmodifiable; - -import java.util.*; - -/** - * Register and expose all {@link MetadataRule}. - */ -public final class MetadataRulesManager { - private MetadataRulesManager() {} - - private static final Map> RULES = new HashMap<>(); - - /** - * Register a new rule. - * @param rule the rule to register. - */ - public static void registerRule(@NotNull MetadataRule rule) { - RULES.putIfAbsent(rule.getName(), new ArrayList<>()); - RULES.get(rule.getName()).add(rule); - } - - /** - * Get all rules for a name. - * @param name a non-null name. - * @return an unmodifiable list of rules. If not rule exist, the list will be empty. - */ - public static @NotNull @Unmodifiable List getRulesForName(@NotNull String name) { - return Collections.unmodifiableList(RULES.getOrDefault(name, Collections.emptyList())); - } - - /** - * List existing rules. - * @return an unmodifiable collection of names. - */ - public static @NotNull @Unmodifiable Collection existingKeys() { - return Collections.unmodifiableSet( RULES.keySet() ); - } - -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/metadata/rules/DefaultMetadataRules.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/metadata/rules/DefaultMetadataRules.java deleted file mode 100644 index 2fed0429..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/metadata/rules/DefaultMetadataRules.java +++ /dev/null @@ -1,24 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.metadata.rules; - -import fr.jamailun.ultimatespellsystem.dsl.metadata.MetadataRulesManager; - -/** - * Load the default ruleset for metadata statements. - */ -public final class DefaultMetadataRules { - private DefaultMetadataRules() {} - - private static boolean initialized = false; - - /** - * Initialize the metadata rules system. - */ - public static void initialize() { - if(initialized) return; - initialized = true; - - // Register rules - MetadataRulesManager.registerRule(new ParamDefinitionMetadata()); - } - -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/metadata/rules/ParamDefinitionMetadata.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/metadata/rules/ParamDefinitionMetadata.java deleted file mode 100644 index 9e2a3448..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/metadata/rules/ParamDefinitionMetadata.java +++ /dev/null @@ -1,41 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.metadata.rules; - -import fr.jamailun.ultimatespellsystem.dsl.errors.MetadataRuleFailureException; -import fr.jamailun.ultimatespellsystem.dsl.metadata.MetadataRule; -import fr.jamailun.ultimatespellsystem.dsl.nodes.statements.MetadataStatement; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.variables.TypesContext; -import org.jetbrains.annotations.NotNull; - -/** - * Apply for {@code @param(NAME, TYPE)} - */ -public class ParamDefinitionMetadata implements MetadataRule { - - @Override - public void apply(@NotNull TypesContext context, @NotNull MetadataStatement metadata) { - // Read objets - if(metadata.getParams().size() < 2) - throw new MetadataRuleFailureException(metadata.getPosition(), "Invalid number of parameters. Expected at least 2, got " + metadata.getParams().size() + "."); - if(!(metadata.getParams().getFirst() instanceof String name)) - throw new MetadataRuleFailureException(metadata.getPosition(), "For @param: invalid type for 'name'. Expected String, got " + metadata.getParams().getFirst()); - if(!(metadata.getParams().get(1) instanceof String type)) - throw new MetadataRuleFailureException(metadata.getPosition(), "For @param: invalid type for 'type'. Expected String, got " + metadata.getParams().get(1)); - boolean collection = false; - if(metadata.getParams().size() > 2) { - if(!(metadata.getParams().get(2) instanceof Boolean isColl)) - throw new MetadataRuleFailureException(metadata.getPosition(), "For @param: invalid type for 'type'. Expected String, got " + metadata.getParams().get(1)); - collection = isColl; - } - // Guarantee variable - TypePrimitive primitive = TypePrimitive.parsePrimitive(type); - if(primitive == null) - throw new MetadataRuleFailureException(metadata.getPosition(), "For @param, unknown primitive value '" + type + "'."); - context.promiseVariable(name, primitive.asType(collection)); - } - - @Override - public @NotNull String getName() { - return "param"; - } -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/ExpressionNode.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/ExpressionNode.java deleted file mode 100644 index 6b76bb6d..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/ExpressionNode.java +++ /dev/null @@ -1,253 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes; - -import fr.jamailun.ultimatespellsystem.dsl.errors.SyntaxException; -import fr.jamailun.ultimatespellsystem.dsl.errors.UnknownFunctionException; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.*; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.compute.AllEntitiesAroundExpression; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.compute.PositionOfExpression; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.compute.SizeOfExpression; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.*; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.litteral.*; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.operators.*; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Type; -import fr.jamailun.ultimatespellsystem.dsl.registries.EntityTypeRegistry; -import fr.jamailun.ultimatespellsystem.dsl.registries.FunctionDefinitionsRegistry; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.Token; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenPosition; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenStream; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenType; -import fr.jamailun.ultimatespellsystem.dsl.visitor.ExpressionVisitor; -import org.jetbrains.annotations.NotNull; - -import java.util.ArrayDeque; -import java.util.Deque; -import java.util.List; - -/** - * An "expression" is a typed element, used by {@link StatementNode statements}.
- * Types are statically checked.
- * This class can parse expressions using the {@link #readNextExpression(TokenStream)} method. - */ -public abstract class ExpressionNode extends Node { - - private final TokenPosition position; - - /** - * New instance of an expression, needs a position. - * @param position non-null position of the first token. - */ - protected ExpressionNode(@NotNull TokenPosition position) { - this.position = position; - } - - /** - * Get the position of the first token of the expression. - * @return a non-null token position. - */ - public @NotNull TokenPosition firstTokenPosition() { - return position; - } - - /** - * Get the {@link Type} of this expression. - * @return a valid and non-null Type. - */ - public abstract @NotNull Type getExpressionType(); - - /** - * Make a Visitor visit this node. - * @param visitor the non-null visitor to call. - */ - public abstract void visit(@NotNull ExpressionVisitor visitor); - - /** - * Extract the next Expression-Node from a tokens-stream. - * @param tokens the tokens-stream to create the next expression with. - * @return a non-null expression. - * @throws fr.jamailun.ultimatespellsystem.dsl.errors.UssException if a problems occurs. - */ - public static @NotNull ExpressionNode readNextExpression(@NotNull TokenStream tokens) { - return readNextExpression(tokens, false); - } - - /** - * Extract the next Expression-Node from a tokens-stream. - * @param tokens the tokens-stream to create the next expression with. - * @param allowCustom if true, an unknown Identifier will be returned as a specific literal. - * @return a non-null expression. - * @throws fr.jamailun.ultimatespellsystem.dsl.errors.UssException if a problems occurs. - */ - public static @NotNull ExpressionNode readNextExpression(@NotNull TokenStream tokens, boolean allowCustom) { - return readNextExpression(tokens, allowCustom, new MathParsingQueue(false), true); - } - - private static ExpressionNode readNextExpression(TokenStream tokens, boolean allowCustom, MathParsingQueue mathStack, boolean logicFirst) { - ExpressionNode raw = readNextExpressionBuffer(tokens, allowCustom); - // Check if the element is accessed ! - if(tokens.dropOptional(TokenType.SQUARE_BRACKET_OPEN)) { - ExpressionNode index = readNextExpression(tokens); - tokens.dropOrThrow(TokenType.SQUARE_BRACKET_CLOSE); - raw = new ArrayGetterExpression(raw, index); - } - - ExpressionNode withMath = tryConvertMathOperations(raw, tokens, mathStack); - return tryConvertLogicalExpression(withMath, tokens, logicFirst); - } - - private static @NotNull ExpressionNode readNextExpressionBuffer(@NotNull TokenStream tokens, boolean allowCustom) { - Token token = tokens.next(); - return switch (token.getType()) { - // Mono-operators - case OPE_NOT -> { - ExpressionNode nextExpression = readNextExpression(tokens); - yield new NotOperator(token, nextExpression); - } - case OPE_SUB -> { - TokenPosition position = tokens.position(); - ExpressionNode nextExpression = readNextExpression(tokens); - yield new SubOperator(position, new NumberExpression(position, 0), nextExpression); - } - // Literals - case VALUE_NUMBER -> new NumberExpression(token); - case TRUE, FALSE -> new BooleanExpression(token); - case VALUE_STRING -> new StringExpression(token); - case VALUE_DURATION -> new DurationExpression(token); - case NULL -> new NullExpression(token.pos()); - case IDENTIFIER -> { - String value = token.getContentString(); - - // EntityType ? - if(EntityTypeRegistry.isAllowed(value)) { - yield new EntityTypeExpression(token.pos(), value); - } else if("EntityType".equals(value)) { - tokens.dropOrThrow(TokenType.DOT); - Token real = tokens.nextOrThrow(TokenType.IDENTIFIER); - String v = real.getContentString(); - if(EntityTypeRegistry.isAllowed(v)) { - yield new EntityTypeExpression(token.pos(), v); - } else { - throw new SyntaxException(token, "Unknown (or disallowed) EntityType '" + v + "'."); - } - } - - // Parenthesis ? maybe a function. - if(tokens.dropOptional(TokenType.BRACKET_OPEN)) { - MonoOperator.MonoOpeType monoOpeType = MonoOperator.MonoOpeType.find(value.toUpperCase()); - if(monoOpeType != null) { - ExpressionNode child = ExpressionNode.readNextExpression(tokens, true); - tokens.dropOrThrow(TokenType.BRACKET_CLOSE); - yield new MathFunctionOperator(token.pos(), child, monoOpeType); - } - - FunctionDefinition functionDefinition = FunctionDefinitionsRegistry.find(value); - if(functionDefinition != null) { - FunctionCallExpression exp = FunctionCallExpression.readNextFunctionCall(functionDefinition, tokens); - tokens.dropOptional(TokenType.SEMI_COLON); - yield exp; - } - throw new UnknownFunctionException(token.pos(), value); - } - - // Custom value : checked at runtime ! - if(allowCustom) { - yield new RuntimeLiteral(token); - } - - throw new SyntaxException(token, "Expected an expression."); - } - case CHAR_AT -> LocationLiteral.readNextLocation(tokens); - // Var - case VALUE_VARIABLE -> new VariableExpression(token); - // Openers: '{{', '[[', '(' - case PROPERTY_OPEN -> PropertiesExpression.parseProperties(tokens); - case ARRAY_OPEN -> ArrayExpression.parseNextArrayConcat(tokens); - case BRACKET_OPEN -> ParenthesisExpression.parseParenthesis(tokens); - - // 'function'-expressions - case ALL -> AllEntitiesAroundExpression.parseAllExpression(tokens); - case POSITION -> PositionOfExpression.parsePositionOf(tokens); - case SIZEOF -> SizeOfExpression.parseSizeOf(tokens); - - // Other - default -> throw new SyntaxException(token, "Unexpected expression-start."); - }; - } - - private final static List LOW_PRIORITY_OPERATORS = List.of(TokenType.OPE_ADD, TokenType.OPE_SUB); - private final static List HIGH_PRIORITY_OPERATORS = List.of(TokenType.OPE_MUL, TokenType.OPE_DIV); - - private static ExpressionNode tryConvertMathOperations(ExpressionNode expr, @NotNull TokenStream tokens, MathParsingQueue stack) { - Token token = tokens.peek(); - - // Low-priority : push to stack - if(LOW_PRIORITY_OPERATORS.contains(token.getType()) && !stack.priority) { - tokens.drop(); - // push to stack - stack.expressionStack.push(expr); - stack.operandsStack.push(token); - // fetch next one - return readNextExpression(tokens, true, stack, true); - } - - // High-priority operators - if(HIGH_PRIORITY_OPERATORS.contains(token.getType())) { - tokens.drop(); - // don't push to stack. Get the next one and convert directly - ExpressionNode nextOne = readNextExpression(tokens, true, new MathParsingQueue(true), true); - BiOperator current = BiOperator.parseBiOperator(expr, token, nextOne); - // And redo (try to have more operators) - return tryConvertMathOperations(current, tokens, stack); - } - - // No operator after (EOE) : unstack the stack, build expression tree, return it. - return stack.deStack(expr); - } - - private static @NotNull ExpressionNode tryConvertLogicalExpression(ExpressionNode expr, @NotNull TokenStream tokens, boolean firstLevel) { - Token token = tokens.peek(); - return switch(token.getType()) { - case OPE_OR, OPE_AND, LIST_ADD, LIST_REM, LIST_REM_INDEX -> { - if(!firstLevel) - yield expr; - tokens.drop(); - ExpressionNode right = readNextExpression(tokens, false, new MathParsingQueue(false), true); - yield BiOperator.parseBiOperator(expr, token, right); - } - case COMP_NE, COMP_EQ, COMP_GT, COMP_LT, COMP_LE, COMP_GE, LIST_CONTAINS -> { - tokens.drop(); - ExpressionNode right = readNextExpression(tokens, false, new MathParsingQueue(false), false); - BiOperator newFormed = BiOperator.parseBiOperator(expr, token, right); - yield tryConvertLogicalExpression(newFormed, tokens, true); - } - default -> expr; - }; - } - - private static class MathParsingQueue { - final Deque expressionStack = new ArrayDeque<>(); - final Deque operandsStack = new ArrayDeque<>(); - final boolean priority; - - MathParsingQueue(boolean priority) { - this.priority = priority; - } - - @Override - public String toString() { - return "{"+(priority?"! ":"")+"E="+expressionStack+", O="+operandsStack+"}"; - } - - ExpressionNode deStack(ExpressionNode expr) { - ExpressionNode topRight = expr; - // Dépiler peu à peu - while( ! expressionStack.isEmpty()) { - ExpressionNode node = expressionStack.pop(); - Token ope = operandsStack.pop(); - // Fusion right operators - topRight = BiOperator.parseBiOperator(node, ope, topRight); - } - return topRight; - } - } - -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/Node.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/Node.java deleted file mode 100644 index ac3b0218..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/Node.java +++ /dev/null @@ -1,70 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes; - -import fr.jamailun.ultimatespellsystem.dsl.errors.TypeException; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.CollectionFilter; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.variables.TypesContext; -import org.jetbrains.annotations.NotNull; - -import java.util.ArrayList; -import java.util.List; - -/** - * A node is an element of the AST. - * It can be a statement of an expression. - */ -public abstract class Node { - - /** - * Validates the TYPE of the handled elements. No logic test is done here. - * @param context the typing context. - */ - public abstract void validateTypes(@NotNull TypesContext context); - - /** - * Assert an expression to be of a specific type. - * @param expression the expression to check. - * @param filter the filter for collection. - * @param type the expected type. - * @param otherTypes a variadic for other allowed types. - */ - protected void assertExpressionType(@NotNull ExpressionNode expression, @NotNull CollectionFilter filter, @NotNull TypePrimitive type, TypePrimitive... otherTypes) { - if(expression.getExpressionType().primitive() == TypePrimitive.NULL) - return; // Ignore NULL type : it is accepted by everything. - - List allowed = new ArrayList<>(List.of(otherTypes)); - allowed.add(type); - - if(!allowed.contains(expression.getExpressionType().primitive())) - throw new TypeException(expression, type); - - if(!filter.isValid(expression.getExpressionType())) { - throw new TypeException(expression, "Type is correct, but expected a "+filter+"."); - } - } - - /** - * Validate the type of expression, and then it to be of a specific type. - * @param expression the expression to check. - * @param filter the filter for collection. - * @param context the current context. - * @param type the expected type. - * @param otherTypes a variadic for other allowed types. - */ - protected void assertExpressionType(@NotNull ExpressionNode expression, @NotNull CollectionFilter filter, @NotNull TypesContext context, @NotNull TypePrimitive type, TypePrimitive... otherTypes) { - expression.validateTypes(context); - assertExpressionType(expression, filter, type, otherTypes); - } - - /** - * Validate the type of expression, and then it to be of a specific type. - * @param expression the expression to check. - * @param context the current context. - * @param type the expected type. - * @param otherTypes a variadic for other allowed types. - */ - protected void assertExpressionType(@NotNull ExpressionNode expression, @NotNull TypesContext context, @NotNull TypePrimitive type, TypePrimitive... otherTypes) { - assertExpressionType(expression, CollectionFilter.ANY, context, type, otherTypes); - } - -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/StatementNode.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/StatementNode.java deleted file mode 100644 index 9724ba41..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/StatementNode.java +++ /dev/null @@ -1,79 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes; - -import fr.jamailun.ultimatespellsystem.dsl.nodes.statements.blocks.*; -import fr.jamailun.ultimatespellsystem.dsl.errors.SyntaxException; -import fr.jamailun.ultimatespellsystem.dsl.nodes.statements.*; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.Token; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenStream; -import fr.jamailun.ultimatespellsystem.dsl.visitor.StatementVisitor; -import org.jetbrains.annotations.NotNull; - -/** - * A statement is an instruction in the code. It can use other statements, or {@link ExpressionNode expressions}.
- * Can be visited by a {@link StatementVisitor}. - * This class can parse a statement with the {@link #parseNextStatement(TokenStream)} method. - */ -public abstract class StatementNode extends Node { - - /** - * Make this statement be visited. - * @param visitor the visitor to use. - */ - public abstract void visit(@NotNull StatementVisitor visitor); - - /** - * Read a new statement from the tokens stream. - * @param tokens the stream of tokens. - * @return a non-null statement. - * @throws fr.jamailun.ultimatespellsystem.dsl.errors.UssException if a problem occurs. - */ - public static @NotNull StatementNode parseNextStatement(@NotNull TokenStream tokens) { - Token token = tokens.next(); - return switch (token.getType()) { - // Empty statement - case SEMI_COLON -> parseNextStatement(tokens); - - // Metadata - case CHAR_AT -> MetadataStatement.parseMetadata(tokens); - - // Blocks - case BRACES_OPEN -> BlockStatement.parseNextBlock(tokens); - case RUN -> RunLaterStatement.parseRunLater(tokens); - case REPEAT -> RepeatStatement.parseRepeat(tokens); - case CALLBACK -> CallbackStatement.parseCallback(tokens); - - // Variable set - case DEFINE -> DefineStatement.parseNextDefine(tokens); - case VALUE_VARIABLE -> { - tokens.back(); - yield DefineStatement.parseNextDefine(tokens); - } - - // Statements - case SEND -> SendStatement.parseSendStatement(tokens); - case STOP -> StopStatement.parseStop(tokens); - case SUMMON -> SummonStatement.parseSummonStatement(tokens); - case TELEPORT -> TeleportStatement.parseTeleport(tokens); - case PLAY -> PlayStatement.parsePlay(tokens); - case GIVE -> GiveStatement.parseNextGiveStatement(tokens); - - // Control-Flow - case IF -> IfElseStatement.parseIfStatement(tokens); - case ELSE -> throw new SyntaxException(token, "An ELSE must follow an IF (or the IF's child statement)."); - case FOR -> ForLoopStatement.parseForLoop(tokens); - case FOREACH -> ForeachLoopStatement.parseForLoop(tokens); - case WHILE -> WhileLoopStatement.parseWhileLoop(tokens, true); - case DO -> WhileLoopStatement.parseWhileLoop(tokens, false); - case BREAK -> BreakContinueStatement.parseNextBreakContinue(tokens, false); - case CONTINUE -> BreakContinueStatement.parseNextBreakContinue(tokens, true); - - default -> { - tokens.back(); - ExpressionNode expressionNode = ExpressionNode.readNextExpression(tokens, true); - yield new SimpleExpressionStatement(expressionNode); - } - //throw new SyntaxException(token, "Unexpected token to begin a statement."); - }; - } - -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/ArrayExpression.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/ArrayExpression.java deleted file mode 100644 index 5886a1c0..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/ArrayExpression.java +++ /dev/null @@ -1,87 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes.expressions; - -import fr.jamailun.ultimatespellsystem.dsl.errors.TypeException; -import fr.jamailun.ultimatespellsystem.dsl.nodes.ExpressionNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.CollectionFilter; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Type; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.variables.TypesContext; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.*; -import fr.jamailun.ultimatespellsystem.dsl.visitor.ExpressionVisitor; -import lombok.Getter; -import org.jetbrains.annotations.NotNull; - -import java.util.ArrayList; -import java.util.List; - -/** - * Raw array value. - */ -public class ArrayExpression extends ExpressionNode { - - @Getter - private final List elements; - private TypePrimitive typePrimitive; - - protected ArrayExpression(TokenPosition position, List elements) { - super(position); - this.elements = elements; - } - - @Override - public @NotNull Type getExpressionType() { - if(typePrimitive == null) - throw new TypeException(firstTokenPosition(), "Type of primitive has not been set."); - return typePrimitive.asType(true); - } - - @Override - public void visit(@NotNull ExpressionVisitor visitor) { - visitor.handleArray(this); - } - - @Override - public void validateTypes(@NotNull TypesContext contextParent) { - // avoid non-intentional propagation - TypesContext context = contextParent.childContext(); - - // Check type for all expressions : they must share the same type. - for(ExpressionNode node : elements) { - node.validateTypes(context); - - if(typePrimitive == null) { - typePrimitive = node.getExpressionType().primitive(); - } else { - assertExpressionType(node, CollectionFilter.MONO_ELEMENT, typePrimitive); - } - } - if(typePrimitive == null) - typePrimitive = TypePrimitive.NULL; - } - - @PreviousIndicator(expected = TokenType.ARRAY_OPEN) - public static ArrayExpression parseNextArrayConcat(TokenStream tokens) { - TokenPosition pos = tokens.position(); - List nodes = new ArrayList<>(); - boolean first = true; - while(tokens.hasMore()) { - Token peek = tokens.peek(); - if(peek.getType() == TokenType.ARRAY_CLOSE) - break; - if( ! first) { - tokens.dropOrThrow(TokenType.COMMA); - } - first = false; - ExpressionNode node = ExpressionNode.readNextExpression(tokens); - nodes.add(node); - } - tokens.dropOrThrow(TokenType.ARRAY_CLOSE); - return new ArrayExpression(pos, nodes); - } - - @Override - public String toString() { - return "ARRAY("+(typePrimitive==null?"? type":typePrimitive.asType())+")[" + elements + "]"; - } - -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/ArrayGetterExpression.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/ArrayGetterExpression.java deleted file mode 100644 index 2e73009d..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/ArrayGetterExpression.java +++ /dev/null @@ -1,55 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes.expressions; - -import fr.jamailun.ultimatespellsystem.dsl.errors.TypeException; -import fr.jamailun.ultimatespellsystem.dsl.nodes.ExpressionNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.CollectionFilter; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Type; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.variables.TypesContext; -import fr.jamailun.ultimatespellsystem.dsl.visitor.ExpressionVisitor; -import lombok.Getter; -import org.jetbrains.annotations.NotNull; - -/** - * Get array value at index. - */ -@Getter -public class ArrayGetterExpression extends ExpressionNode { - - private final ExpressionNode array; - private final ExpressionNode index; - - public ArrayGetterExpression(ExpressionNode array, ExpressionNode index) { - super(array.firstTokenPosition()); - this.array = array; - this.index = index; - } - - @Override - public @NotNull Type getExpressionType() { - return array.getExpressionType().asMonoElement(); - } - - @Override - public void validateTypes(@NotNull TypesContext context) { - // Index must be a number - assertExpressionType(index, CollectionFilter.MONO_ELEMENT, context, TypePrimitive.NUMBER); - - // Array must be a collection - array.validateTypes(context); - Type typeArray = array.getExpressionType(); - if( ! typeArray.is(TypePrimitive.NULL) && ! typeArray.isCollection()) { - throw new TypeException(this, "Cannot get the value of a non-array."); - } - } - - @Override - public void visit(@NotNull ExpressionVisitor visitor) { - visitor.handleArrayGet(this); - } - - @Override - public String toString() { - return array + "[" + index + "]"; - } -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/ParenthesisExpression.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/ParenthesisExpression.java deleted file mode 100644 index 766c96fe..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/ParenthesisExpression.java +++ /dev/null @@ -1,55 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes.expressions; - -import fr.jamailun.ultimatespellsystem.dsl.nodes.ExpressionNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Type; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.variables.TypesContext; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.PreviousIndicator; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenPosition; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenStream; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenType; -import fr.jamailun.ultimatespellsystem.dsl.visitor.ExpressionVisitor; -import lombok.Getter; -import org.jetbrains.annotations.NotNull; - -/** - * Group of parenthesis. - */ -@Getter -public class ParenthesisExpression extends ExpressionNode { - - private final ExpressionNode expression; - - protected ParenthesisExpression(TokenPosition position, ExpressionNode expression) { - super(position); - this.expression = expression; - } - - @Override - public @NotNull Type getExpressionType() { - return expression.getExpressionType(); - } - - @Override - public void visit(@NotNull ExpressionVisitor visitor) { - visitor.handleParenthesis(this); - } - - @Override - public void validateTypes(@NotNull TypesContext context) { - // Keep the same context. - expression.validateTypes(context); - } - - @Override - public String toString() { - return " (" + expression + ") "; - } - - @PreviousIndicator(expected = {TokenType.BRACKET_OPEN}) - public static ParenthesisExpression parseParenthesis(TokenStream tokens) { - TokenPosition pos = tokens.position(); - ExpressionNode expression = ExpressionNode.readNextExpression(tokens, true); - tokens.dropOrThrow(TokenType.BRACKET_CLOSE); - return new ParenthesisExpression(pos, expression); - } -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/PropertiesExpression.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/PropertiesExpression.java deleted file mode 100644 index 0bf4ec26..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/PropertiesExpression.java +++ /dev/null @@ -1,83 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes.expressions; - -import fr.jamailun.ultimatespellsystem.dsl.errors.SyntaxException; -import fr.jamailun.ultimatespellsystem.dsl.nodes.ExpressionNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Type; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.variables.TypesContext; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.*; -import fr.jamailun.ultimatespellsystem.dsl.visitor.ExpressionVisitor; -import lombok.Getter; -import org.jetbrains.annotations.NotNull; - -import java.util.HashMap; -import java.util.Map; - -/** - * Raw properties set. - */ -@Getter -public class PropertiesExpression extends ExpressionNode { - - private final Map expressions; - - public PropertiesExpression(TokenPosition pos, Map expressions) { - super(pos); - this.expressions = expressions; - } - - @Override - public @NotNull Type getExpressionType() { - return TypePrimitive.PROPERTIES_SET.asType(); - } - - @Override - public void visit(@NotNull ExpressionVisitor visitor) { - visitor.handlePropertiesSet(this); - } - - @Override - public String toString() { - return "{" + expressions + "}"; - } - - @Override - public void validateTypes(@NotNull TypesContext contextParent) { - TypesContext context = contextParent.childContext(); - for(ExpressionNode expression : expressions.values()) - expression.validateTypes(context); - } - - @PreviousIndicator(expected = {TokenType.PROPERTY_OPEN}) - public static PropertiesExpression parseProperties(TokenStream tokens) { - TokenPosition pos = tokens.position(); - Map expressions = new HashMap<>(); - while(tokens.hasMore()) { - if(tokens.peek().getType() == TokenType.PROPERTY_CLOSE) { - // EOP - break; - } - if( ! expressions.isEmpty()) { - tokens.dropOrThrow(TokenType.COMMA); - } - // KEY - String propKey; - Token word = tokens.next(); - if(word.getType() == TokenType.IDENTIFIER) { - propKey = word.getContentString(); - } else if(word.getType().letters) { - propKey = word.getType().name().toLowerCase(); - } else { - throw new SyntaxException(word, "Unexpected token for property-key."); - } - // : - tokens.dropOrThrow(TokenType.COLON); - // VALUE - ExpressionNode value = ExpressionNode.readNextExpression(tokens, true); - // build - expressions.put(propKey, value); - } - tokens.dropOrThrow(TokenType.PROPERTY_CLOSE); - return new PropertiesExpression(pos, expressions); - } -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/VariableExpression.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/VariableExpression.java deleted file mode 100644 index 8c723720..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/VariableExpression.java +++ /dev/null @@ -1,60 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes.expressions; - -import fr.jamailun.ultimatespellsystem.dsl.errors.SyntaxException; -import fr.jamailun.ultimatespellsystem.dsl.nodes.ExpressionNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Type; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.variables.TypesContext; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.variables.VariableDefinition; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.Token; -import fr.jamailun.ultimatespellsystem.dsl.visitor.ExpressionVisitor; -import org.jetbrains.annotations.NotNull; - -/** - * Variable reference expression. - */ -public class VariableExpression extends ExpressionNode { - - private final String varName; - private Type runtimeType; - - /** - * Create a variable expression, which is a REFERENCE to something else. - * The reference will be obtained during type validation. - * @param token the token of the variable itself. - */ - public VariableExpression(@NotNull Token token) { - super(token.pos()); - this.varName = token.getContentString(); - } - - /** - * Get the name of the variable. - * @return a non-null string. - */ - public @NotNull String getVariableName() { - return varName; - } - - @Override - public @NotNull Type getExpressionType() { - return runtimeType; - } - - @Override - public void validateTypes(@NotNull TypesContext context) { - VariableDefinition var = context.findVariable(varName); - if(var == null) - throw new SyntaxException(firstTokenPosition(), "Undefined variable '" + varName + "'."); - runtimeType = var.getType(context); - } - - @Override - public String toString() { - return "%" + varName; - } - - @Override - public void visit(@NotNull ExpressionVisitor visitor) { - visitor.handleVariable(this); - } -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/compute/AllEntitiesAroundExpression.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/compute/AllEntitiesAroundExpression.java deleted file mode 100644 index 6d0923f1..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/compute/AllEntitiesAroundExpression.java +++ /dev/null @@ -1,88 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.compute; - -import fr.jamailun.ultimatespellsystem.dsl.nodes.ExpressionNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.CollectionFilter; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Type; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.variables.TypesContext; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.PreviousIndicator; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenPosition; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenStream; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenType; -import fr.jamailun.ultimatespellsystem.dsl.visitor.ExpressionVisitor; -import lombok.Getter; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; - -/** - * 'all entities' within, around expression. Returns a collection of entities. - */ -@Getter -public class AllEntitiesAroundExpression extends ExpressionNode { - - private final ExpressionNode entityType; - private final ExpressionNode source; - private final ExpressionNode distance; - private final boolean including; - - protected AllEntitiesAroundExpression(TokenPosition pos, ExpressionNode entityType, boolean including, ExpressionNode source, ExpressionNode distance) { - super(pos); - this.entityType = entityType; - this.including = including; - this.source = source; - this.distance = distance; - } - - @Override - public @NotNull Type getExpressionType() { - return new Type(TypePrimitive.ENTITY, true); - } - - @Override - public void visit(@NotNull ExpressionVisitor visitor) { - visitor.handleAllAround(this); - } - - @Override - public void validateTypes(@NotNull TypesContext context) { - // Distance must be a number - assertExpressionType(distance, CollectionFilter.MONO_ELEMENT, context, TypePrimitive.NUMBER); - - // Scope can be entity-type OR custom - assertExpressionType(entityType, CollectionFilter.MONO_ELEMENT, context, TypePrimitive.ENTITY_TYPE, TypePrimitive.CUSTOM, TypePrimitive.STRING); - - // Source can be entity OR location - assertExpressionType(source, CollectionFilter.MONO_ELEMENT, context, TypePrimitive.ENTITY, TypePrimitive.LOCATION); - } - - @Override - public String toString() { - return "FETCH_ALL{" + entityType + " around " + source + (including ?"(STRICT)":"") + ", within "+ distance + "}"; - } - - /** - * Parse the next all-entities-around expression. - * @param tokens stream of tokens. - * @return a new instance. - */ - @PreviousIndicator(expected = {TokenType.ALL}) // all (SCOPE) within (DISTANCE) around (SOURCE) [[including]] - @Contract("_ -> new") - public static @NotNull AllEntitiesAroundExpression parseAllExpression(@NotNull TokenStream tokens) { - TokenPosition pos = tokens.position(); - - // Entity type - ExpressionNode scope = ExpressionNode.readNextExpression(tokens, true); - - // - tokens.dropOrThrow(TokenType.WITHIN); - ExpressionNode distance = ExpressionNode.readNextExpression(tokens); - - // DistanceSource - tokens.dropOrThrow(TokenType.AROUND); - ExpressionNode source = ExpressionNode.readNextExpression(tokens); - boolean including = tokens.dropOptional(TokenType.INCLUDING); - - return new AllEntitiesAroundExpression(pos, scope, including, source, distance); - } - -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/compute/PositionOfExpression.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/compute/PositionOfExpression.java deleted file mode 100644 index 069b126f..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/compute/PositionOfExpression.java +++ /dev/null @@ -1,59 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.compute; - -import fr.jamailun.ultimatespellsystem.dsl.nodes.ExpressionNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Type; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.variables.TypesContext; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.PreviousIndicator; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenPosition; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenStream; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenType; -import fr.jamailun.ultimatespellsystem.dsl.visitor.ExpressionVisitor; -import org.jetbrains.annotations.NotNull; - -/** - * Position of an entity. - */ -public class PositionOfExpression extends ExpressionNode { - - private final ExpressionNode entityNode; - private boolean isCollection = false; - - public PositionOfExpression(TokenPosition pos, ExpressionNode entityNode) { - super(pos); - this.entityNode = entityNode; - } - - public ExpressionNode getEntity() { - return entityNode; - } - - @Override - public @NotNull Type getExpressionType() { - return TypePrimitive.LOCATION.asType(isCollection); - } - - @Override - public void visit(@NotNull ExpressionVisitor visitor) { - visitor.handlePositionOf(this); - } - - @Override - public void validateTypes(@NotNull TypesContext context) { - assertExpressionType(entityNode, context, TypePrimitive.ENTITY); - isCollection = entityNode.getExpressionType().isCollection(); - } - - @PreviousIndicator(expected = TokenType.POSITION) - public static @NotNull PositionOfExpression parsePositionOf(@NotNull TokenStream tokens) { - TokenPosition pos = tokens.position(); - tokens.dropOrThrow(TokenType.OF); - ExpressionNode entityNode = ExpressionNode.readNextExpression(tokens); - return new PositionOfExpression(pos, entityNode); - } - - @Override - public String toString() { - return "position_of(" + entityNode + ")"; - } -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/compute/SizeOfExpression.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/compute/SizeOfExpression.java deleted file mode 100644 index 4159c16b..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/compute/SizeOfExpression.java +++ /dev/null @@ -1,61 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.compute; - -import fr.jamailun.ultimatespellsystem.dsl.nodes.ExpressionNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Type; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.variables.TypesContext; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.PreviousIndicator; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenPosition; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenStream; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenType; -import fr.jamailun.ultimatespellsystem.dsl.visitor.ExpressionVisitor; -import lombok.Getter; -import org.jetbrains.annotations.NotNull; - -/** - * Size of a collection. - */ -@Getter -public class SizeOfExpression extends ExpressionNode { - - private final ExpressionNode child; - - protected SizeOfExpression(TokenPosition position, ExpressionNode child) { - super(position); - this.child = child; - } - - @Override - public @NotNull Type getExpressionType() { - return TypePrimitive.NUMBER.asType(); - } - - @Override - public void visit(@NotNull ExpressionVisitor visitor) { - visitor.handleSizeOf(this); - } - - @Override - public void validateTypes(@NotNull TypesContext context) { - child.validateTypes(context); - // Should we only accept lists? - } - - @PreviousIndicator(expected = TokenType.SIZEOF) - public static @NotNull SizeOfExpression parseSizeOf(@NotNull TokenStream tokens) { - TokenPosition position = tokens.position(); - boolean parenthesis = tokens.dropOptional(TokenType.BRACKET_OPEN); - - ExpressionNode child = ExpressionNode.readNextExpression(tokens); - - if(parenthesis) - tokens.dropOrThrow(TokenType.BRACKET_CLOSE); - - return new SizeOfExpression(position, child); - } - - @Override - public String toString() { - return "size-of(" + child + ")"; - } -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/functions/FunctionArgument.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/functions/FunctionArgument.java deleted file mode 100644 index 08711ddc..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/functions/FunctionArgument.java +++ /dev/null @@ -1,18 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions; - -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; - -/** - * A declaration of a function argument. - * @param type the type of the argument. - * @param debugName the name of the argument. - * @param optional if true, argument is not mandatory. - */ -public record FunctionArgument(@NotNull FunctionType type, @NotNull String debugName, boolean optional) { - @Contract(pure = true) - @Override - public @NotNull String toString() { - return type + " " + debugName + (optional?"*":""); - } -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/functions/FunctionCallExpression.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/functions/FunctionCallExpression.java deleted file mode 100644 index 7bdabff8..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/functions/FunctionCallExpression.java +++ /dev/null @@ -1,99 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions; - -import fr.jamailun.ultimatespellsystem.dsl.errors.SyntaxException; -import fr.jamailun.ultimatespellsystem.dsl.errors.TypeException; -import fr.jamailun.ultimatespellsystem.dsl.nodes.ExpressionNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Type; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.variables.TypesContext; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.*; -import fr.jamailun.ultimatespellsystem.dsl.visitor.ExpressionVisitor; -import lombok.Getter; -import org.jetbrains.annotations.NotNull; - -import java.util.ArrayList; -import java.util.List; - -/** - * A function call statement. - */ -@Getter -public final class FunctionCallExpression extends ExpressionNode { - - private final FunctionDefinition function; - private final List arguments; - - public FunctionCallExpression(@NotNull TokenPosition position, @NotNull FunctionDefinition function, @NotNull List arguments) { - super(position); - this.function = function; - this.arguments = arguments; - } - - @Override - public void validateTypes(@NotNull TypesContext contextRaw) { - TypesContext context = contextRaw.childContext(); - - // Check argument amount - List listArgs = function.arguments(); - - // Then validate arguments types - for(int i = 0; i < arguments.size(); i++) { - FunctionArgument expected = listArgs.get(i); - ExpressionNode obtained = arguments.get(i); - obtained.validateTypes(context); - - FunctionType.TestResult result = expected.type().accepts(obtained.getExpressionType()); - if(result.isError()) - throw new TypeException(obtained, "Argument '" + expected.debugName() + "': " + result.getError()); - } - } - - @Override - public void visit(@NotNull ExpressionVisitor visitor) { - visitor.handleFunction(this); - } - - @Override - public @NotNull Type getExpressionType() { - return function.returnedType(); - } - - /** - * Parse a new function call expression from the tokens stream. - * @param functionDefinition found definition. - * @param tokens tokens streams. - * @return a new instance. - */ - @PreviousIndicator(expected = TokenType.BRACKET_OPEN) - public static @NotNull FunctionCallExpression readNextFunctionCall(@NotNull FunctionDefinition functionDefinition, @NotNull TokenStream tokens) { - List arguments = new ArrayList<>(); - TokenPosition position = tokens.position(); - - boolean first = true; - while(tokens.hasMore()) { - Token peek = tokens.peek(); - if(peek.getType() == TokenType.BRACKET_CLOSE) - break; - if( ! first) { - tokens.dropOrThrow(TokenType.COMMA); - } first = false; - - ExpressionNode argument = ExpressionNode.readNextExpression(tokens); - arguments.add(argument); - } - tokens.dropOrThrow(TokenType.BRACKET_CLOSE); - - // Assert obtained arguments count is expected - if(arguments.size() < functionDefinition.mandatoryArgumentsCount()) - throw new SyntaxException(position, "Invalid arguments count. Expected " + functionDefinition.arguments().size() + " mandatory, got " + arguments.size()); - if(arguments.size() > functionDefinition.arguments().size()) - throw new SyntaxException(position, "Invalid arguments count. Expected " + functionDefinition.arguments().size() + ", got " + arguments.size()); - - // Create and return node - return new FunctionCallExpression(position, functionDefinition, arguments); - } - - @Override - public @NotNull String toString() { - return "F-call{"+function.id()+" (" + arguments + ")}"; - } -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/functions/FunctionDefinition.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/functions/FunctionDefinition.java deleted file mode 100644 index df570903..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/functions/FunctionDefinition.java +++ /dev/null @@ -1,27 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions; - -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Type; -import org.jetbrains.annotations.NotNull; - -import java.util.List; - -/** - * Definition for a function to run. But because this is the DSL only, we don't care about really handling the functions. - * @param id the ID of the function. - * @param returnedType the type returned by this function. - * @param arguments the arguments. - */ -public record FunctionDefinition(@NotNull String id, @NotNull Type returnedType, @NotNull List arguments) { - - /** - * Get the amount of mandatory arguments. - * @return a non-negative integer. - */ - public int mandatoryArgumentsCount() { - return (int) arguments.stream() - .filter(a -> ! a.optional()) - .count(); - - } - -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/functions/FunctionType.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/functions/FunctionType.java deleted file mode 100644 index 983e02e9..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/functions/FunctionType.java +++ /dev/null @@ -1,96 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions; - -import com.google.common.base.Preconditions; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.CollectionFilter; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Type; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; -import lombok.AccessLevel; -import lombok.AllArgsConstructor; -import lombok.Getter; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; - -import java.util.List; - -/** - * A lax-collection type for a function. - */ -@AllArgsConstructor(access = AccessLevel.PRIVATE) -public class FunctionType { - - private final List primitives; - private final CollectionFilter collectionFilter; - - /** - * Create a new function-type, that accepts a restricted amount of type primitives. - * @param types varargs of allowed types. - * @return a new instance. - */ - @Contract("_ -> new") - public static @NotNull FunctionType accept(@NotNull TypePrimitive @NotNull ... types) { - Preconditions.checkArgument(types.length > 0, "Cannot have zero primitive."); - return new FunctionType(List.of(types), CollectionFilter.ANY); - } - - /** - * Create a new function-type, that accepts a restricted amount of type primitives as non-collection. - * @param types varargs of allowed types. - * @return a new instance. - */ - @Contract("_ -> new") - public static @NotNull FunctionType acceptOnlyMono(@NotNull TypePrimitive @NotNull ... types) { - Preconditions.checkArgument(types.length > 0, "Cannot have zero primitive."); - return new FunctionType(List.of(types), CollectionFilter.MONO_ELEMENT); - } - - /** - * Create a new function-type, that accepts a restricted amount of type primitives as collection. - * @param types varargs of allowed types. - * @return a new instance. - */ - @Contract("_ -> new") - public static @NotNull FunctionType acceptOnlyCollection(@NotNull TypePrimitive @NotNull ... types) { - Preconditions.checkArgument(types.length > 0, "Cannot have zero primitive."); - return new FunctionType(List.of(types), CollectionFilter.LIST); - } - - /** - * Compute a strict {@link Type} correspondance. - * @return a non-null, new Type instance. - */ - public @NotNull Type asType() { - return primitives.getFirst().asType(collectionFilter == CollectionFilter.LIST); - } - - public @NotNull TestResult accepts(@NotNull Type type) { - if( ! primitives.contains(type.primitive())) { - return TestResult.error("expected one of " + primitives + ", got " + type.primitive() + "."); - } - - if( ! collectionFilter.isValid(type)) { - if(collectionFilter == CollectionFilter.LIST) - return TestResult.error("expected a LIST, got " + type + "."); - return TestResult.error("did not expect a LIST, got " + type + "."); - } - - return TestResult.success(); - } - - @Getter @AllArgsConstructor(access = AccessLevel.PRIVATE) - public static final class TestResult { - private final String error; - public static @NotNull TestResult success() { - return new TestResult(null); - } - public static @NotNull TestResult error(@NotNull String error) { - return new TestResult(error); - } - public boolean isError() { - return error != null; - } - public boolean isSuccess() { - return error == null; - } - } - -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/litteral/BooleanExpression.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/litteral/BooleanExpression.java deleted file mode 100644 index bc8673d3..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/litteral/BooleanExpression.java +++ /dev/null @@ -1,44 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.litteral; - -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Type; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.Token; -import fr.jamailun.ultimatespellsystem.dsl.visitor.ExpressionVisitor; -import org.jetbrains.annotations.NotNull; - -/** - * A raw boolean literal. - */ -public class BooleanExpression extends LiteralExpression { - - private final boolean rawValue; - - /** - * New instance, from a token. - * @param token non-null token to use. - */ - public BooleanExpression(@NotNull Token token) { - super(token.pos()); - this.rawValue = token.getContentBoolean(); - } - - @Override - public @NotNull Boolean getRaw() { - return rawValue; - } - - @Override - public @NotNull Type getExpressionType() { - return TypePrimitive.BOOLEAN.asType(); - } - - @Override - public void visit(@NotNull ExpressionVisitor visitor) { - visitor.handleBooleanLiteral(this); - } - - @Override - public String toString() { - return PREFIX + (rawValue?"TRUE":"FALSE") + SUFFIX; - } -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/litteral/DurationExpression.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/litteral/DurationExpression.java deleted file mode 100644 index 09ac7de9..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/litteral/DurationExpression.java +++ /dev/null @@ -1,46 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.litteral; - -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Duration; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Type; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.Token; -import fr.jamailun.ultimatespellsystem.dsl.visitor.ExpressionVisitor; -import org.jetbrains.annotations.NotNull; - -/** - * A raw {@link Duration} literal. - */ -public class DurationExpression extends LiteralExpression { - - private final Duration duration; - - /** - * New instance, from a token. - * @param token token to use. - */ - public DurationExpression(@NotNull Token token) { - super(token.pos()); - this.duration = new Duration(token.getContentNumber(), token.getContentTimeUnit()); - } - - @Override - public Duration getRaw() { - return duration; - } - - @Override - public @NotNull Type getExpressionType() { - return TypePrimitive.DURATION.asType(); - } - - @Override - public String toString() { - return PREFIX + duration.amount() + " " + duration.timeUnit() + SUFFIX; - } - - @Override - public void visit(@NotNull ExpressionVisitor visitor) { - visitor.handleDurationLiteral(this); - } - -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/litteral/EntityTypeExpression.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/litteral/EntityTypeExpression.java deleted file mode 100644 index 067c27e1..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/litteral/EntityTypeExpression.java +++ /dev/null @@ -1,46 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.litteral; - -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Type; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenPosition; -import fr.jamailun.ultimatespellsystem.dsl.visitor.ExpressionVisitor; -import org.jetbrains.annotations.NotNull; - -/** - * A raw {@link org.bukkit.entity.EntityType} literal. - */ -public class EntityTypeExpression extends LiteralExpression { - - private final String type; - - /** - * New instance. - * @param position token position. - * @param type entity-type value. - */ - public EntityTypeExpression(@NotNull TokenPosition position, @NotNull String type) { - super(position); - this.type = type; - } - - @Override - public String getRaw() { - return type; - } - - @Override - public @NotNull Type getExpressionType() { - return TypePrimitive.ENTITY_TYPE.asType(); - } - - @Override - public String toString() { - return PREFIX + "EntityType." + type + SUFFIX; - } - - @Override - public void visit(@NotNull ExpressionVisitor visitor) { - visitor.handleEntityTypeLiteral(this); - } - -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/litteral/LiteralExpression.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/litteral/LiteralExpression.java deleted file mode 100644 index 0492727a..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/litteral/LiteralExpression.java +++ /dev/null @@ -1,38 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.litteral; - -import fr.jamailun.ultimatespellsystem.dsl.nodes.ExpressionNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.variables.TypesContext; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenPosition; -import org.jetbrains.annotations.NotNull; - -/** - * A literal is a raw value in the code, such as a number, a string, ... - * @param the underlying type to handle. - */ -public abstract class LiteralExpression extends ExpressionNode { - - /** Prefix to toString's */ - protected final static String PREFIX = "<"; - /** Suffix to toString's */ - protected final static String SUFFIX = ">"; - - /** - * New literal. - * @param position position of the corresponding (first) token. - */ - protected LiteralExpression(@NotNull TokenPosition position) { - super(position); - } - - @Override - public void validateTypes(@NotNull TypesContext context) { - // Nothing to do - } - - /** - * Get the underlying value to use. - * @return the literal. - */ - public abstract T getRaw(); - -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/litteral/LocationLiteral.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/litteral/LocationLiteral.java deleted file mode 100644 index b1529915..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/litteral/LocationLiteral.java +++ /dev/null @@ -1,105 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.litteral; - -import fr.jamailun.ultimatespellsystem.dsl.nodes.ExpressionNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Type; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.variables.TypesContext; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.PreviousIndicator; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenPosition; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenStream; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenType; -import fr.jamailun.ultimatespellsystem.dsl.visitor.ExpressionVisitor; -import lombok.Getter; -import org.jetbrains.annotations.NotNull; - -/** - * A raw {@link org.bukkit.Location} literal. - */ -@Getter -public class LocationLiteral extends ExpressionNode { - - private final ExpressionNode world; - private final ExpressionNode vectorX; - private final ExpressionNode vectorY; - private final ExpressionNode vectorZ; - private final ExpressionNode yaw; - private final ExpressionNode pitch; - - protected LocationLiteral(TokenPosition position, ExpressionNode world, ExpressionNode vectorX, ExpressionNode vectorY, ExpressionNode vectorZ, ExpressionNode yaw, ExpressionNode pitch) { - super(position); - this.world = world; - this.vectorX = vectorX; - this.vectorY = vectorY; - this.vectorZ = vectorZ; - this.yaw = yaw; - this.pitch = pitch; - } - - public boolean asYawAndPitch() { - return yaw != null && pitch != null; - } - - @Override - public @NotNull Type getExpressionType() { - return TypePrimitive.LOCATION.asType(); - } - - @Override - public void visit(@NotNull ExpressionVisitor visitor) { - visitor.handleLocationLiteral(this); - } - - @Override - public void validateTypes(@NotNull TypesContext context) { - assertExpressionType(world, context, TypePrimitive.STRING); - assertExpressionType(vectorX, context, TypePrimitive.NUMBER); - assertExpressionType(vectorY, context, TypePrimitive.NUMBER); - assertExpressionType(vectorZ, context, TypePrimitive.NUMBER); - - if(asYawAndPitch()) { - assertExpressionType(yaw, context, TypePrimitive.NUMBER); - assertExpressionType(pitch, context, TypePrimitive.NUMBER); - } - } - - /** - * Parse a new raw location. - * @param tokens stream of tokens. - * @return a new instance. - */ - @PreviousIndicator(expected = TokenType.CHAR_AT) - public static @NotNull LocationLiteral readNextLocation(@NotNull TokenStream tokens) { - TokenPosition position = tokens.position(); - // Open - tokens.dropOrThrow(TokenType.BRACKET_OPEN); - - // World + vector - ExpressionNode world = ExpressionNode.readNextExpression(tokens); - tokens.dropOrThrow(TokenType.COMMA); - ExpressionNode x = ExpressionNode.readNextExpression(tokens); - tokens.dropOrThrow(TokenType.COMMA); - ExpressionNode y = ExpressionNode.readNextExpression(tokens); - tokens.dropOrThrow(TokenType.COMMA); - ExpressionNode z = ExpressionNode.readNextExpression(tokens); - - // Optional yaw + pitch - ExpressionNode yaw = null; - ExpressionNode pitch = null; - if(tokens.dropOptional(TokenType.COMMA)) { - yaw = ExpressionNode.readNextExpression(tokens); - } - if(tokens.dropOptional(TokenType.COMMA)) { - pitch = ExpressionNode.readNextExpression(tokens); - } - - // Close - tokens.dropOrThrow(TokenType.BRACKET_CLOSE); - - return new LocationLiteral(position, world, x, y, z, yaw, pitch); - } - - @Override - public String toString() { - return "Loc{"+world+", ("+vectorX+","+vectorY+","+vectorZ+")}"; - } -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/litteral/NullExpression.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/litteral/NullExpression.java deleted file mode 100644 index c4a69478..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/litteral/NullExpression.java +++ /dev/null @@ -1,39 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.litteral; - -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Type; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenPosition; -import fr.jamailun.ultimatespellsystem.dsl.visitor.ExpressionVisitor; -import org.jetbrains.annotations.NotNull; - -/** - * The {@code NULL} representation. - */ -public class NullExpression extends LiteralExpression { - - /** - * New instance. - * @param pos position of the keyword. - */ - public NullExpression(@NotNull TokenPosition pos) { - super(pos); - } - - @Override - public Void getRaw() {return null;} - - @Override - public @NotNull Type getExpressionType() { - return TypePrimitive.NULL.asType(); - } - - @Override - public String toString() { - return "NULL"; - } - - @Override - public void visit(@NotNull ExpressionVisitor visitor) { - visitor.handleNullLiteral(this); - } -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/litteral/NumberExpression.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/litteral/NumberExpression.java deleted file mode 100644 index 3c314ed0..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/litteral/NumberExpression.java +++ /dev/null @@ -1,55 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.litteral; - -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Type; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.Token; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenPosition; -import fr.jamailun.ultimatespellsystem.dsl.visitor.ExpressionVisitor; -import org.jetbrains.annotations.NotNull; - -/** - * A raw number literal. - */ -public class NumberExpression extends LiteralExpression { - - private final Double rawValue; - - /** - * New literal, using a token. - * @param token token to use. - */ - public NumberExpression(@NotNull Token token) { - super(token.pos()); - this.rawValue = token.getContentNumber(); - } - - /** - * New instance. - * @param position position of the token. - * @param number value. - */ - public NumberExpression(@NotNull TokenPosition position, double number) { - super(position); - this.rawValue = number; - } - - @Override - public Double getRaw() { - return rawValue; - } - - @Override - public @NotNull Type getExpressionType() { - return TypePrimitive.NUMBER.asType(); - } - - @Override - public String toString() { - return PREFIX + rawValue + SUFFIX; - } - - @Override - public void visit(@NotNull ExpressionVisitor visitor) { - visitor.handleNumberLiteral(this); - } -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/litteral/RuntimeLiteral.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/litteral/RuntimeLiteral.java deleted file mode 100644 index fad6c634..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/litteral/RuntimeLiteral.java +++ /dev/null @@ -1,44 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.litteral; - -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Type; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.Token; -import fr.jamailun.ultimatespellsystem.dsl.visitor.ExpressionVisitor; -import org.jetbrains.annotations.NotNull; - -/** - * A literal, can be anything. Not really used... - */ -public class RuntimeLiteral extends LiteralExpression { - - private final String value; - - /** - * New literal runtime. - * @param token token to use. - */ - public RuntimeLiteral(@NotNull Token token) { - super(token.pos()); - this.value = token.getContentString(); - } - - @Override - public String getRaw() { - return value; - } - - @Override - public @NotNull Type getExpressionType() { - return TypePrimitive.CUSTOM.asType(); - } - - @Override - public String toString() { - return PREFIX + "?'" + value + "'" + SUFFIX; - } - - @Override - public void visit(@NotNull ExpressionVisitor visitor) { - visitor.handleRuntimeLiteral(this); - } -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/litteral/StringExpression.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/litteral/StringExpression.java deleted file mode 100644 index 64f4867a..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/litteral/StringExpression.java +++ /dev/null @@ -1,44 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.litteral; - -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Type; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.Token; -import fr.jamailun.ultimatespellsystem.dsl.visitor.ExpressionVisitor; -import org.jetbrains.annotations.NotNull; - -/** - * A raw string literal. - */ -public class StringExpression extends LiteralExpression { - - private final String rawValue; - - /** - * New raw string. - * @param token token to use. - */ - public StringExpression(@NotNull Token token) { - super(token.pos()); - this.rawValue = token.getContentString(); - } - - @Override - public String getRaw() { - return rawValue; - } - - @Override - public @NotNull Type getExpressionType() { - return TypePrimitive.STRING.asType(); - } - - @Override - public String toString() { - return PREFIX + "\"" + rawValue + "\"" + SUFFIX; - } - - @Override - public void visit(@NotNull ExpressionVisitor visitor) { - visitor.handleStringLiteral(this); - } -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/operators/AddOperator.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/operators/AddOperator.java deleted file mode 100644 index a03dc628..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/operators/AddOperator.java +++ /dev/null @@ -1,61 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.operators; - -import fr.jamailun.ultimatespellsystem.dsl.errors.TypeException; -import fr.jamailun.ultimatespellsystem.dsl.nodes.ExpressionNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Type; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.variables.TypesContext; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenPosition; -import org.jetbrains.annotations.NotNull; - -/** - * Addition operator. - */ -public class AddOperator extends BiOperator { - - /** - * New instance. - * @param pos token position. - * @param left first operand. - * @param right second operand - */ - public AddOperator(TokenPosition pos, ExpressionNode left, ExpressionNode right) { - super(pos, left, right); - } - - @Override - public @NotNull BiOpeType getType() { - return BiOpeType.ADD; - } - - @Override - public void validateTypes(@NotNull Type leftType, @NotNull Type rightType, @NotNull TypesContext context) { - // 1) One of them is a String : always compatible - if(leftType.is(TypePrimitive.STRING) || rightType.is(TypePrimitive.STRING)) { - producedType = TypePrimitive.STRING.asType(); - return; - } - // 1.b) Special case : Loc+number[] - if(leftType.is(TypePrimitive.LOCATION) || rightType.primitive() == TypePrimitive.NUMBER && rightType.isCollection()) { - producedType = TypePrimitive.LOCATION.asType(); - return; - } - - // 2) Some types cannot be added at all. - assertNotMathIncompatible(leftType); - assertNotMathIncompatible(rightType); - - // 3) Same type : always compatible - if(leftType.equals(rightType)) { - producedType = leftType; - return; - } - - throw new TypeException(this, "Incompatibles types for an ADD : " + leftType + " and " + rightType); - } - - @Override - public String toString() { - return "(" + left + "+" + right + ")"; - } -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/operators/BiOperator.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/operators/BiOperator.java deleted file mode 100644 index 1f27fa1a..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/operators/BiOperator.java +++ /dev/null @@ -1,108 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.operators; - -import fr.jamailun.ultimatespellsystem.dsl.errors.SyntaxException; -import fr.jamailun.ultimatespellsystem.dsl.nodes.ExpressionNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Type; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.variables.TypesContext; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.Token; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenPosition; -import fr.jamailun.ultimatespellsystem.dsl.visitor.ExpressionVisitor; -import org.jetbrains.annotations.NotNull; - -/** - * Operator between two elements. - */ -public abstract class BiOperator extends Operator { - - protected Type producedType = TypePrimitive.NULL.asType(); - - protected final ExpressionNode left; - protected final ExpressionNode right; - - protected BiOperator(@NotNull TokenPosition position, @NotNull ExpressionNode left, @NotNull ExpressionNode right) { - super(position); - this.left = left; - this.right = right; - } - - public abstract @NotNull BiOpeType getType(); - - @Override - public @NotNull Type getExpressionType() { - return producedType; - } - - @Override - public final void validateTypes(@NotNull TypesContext context) { - // Validate - left.validateTypes(context); - right.validateTypes(context); - - // Assert - Type leftType = left.getExpressionType(); - Type rightType = right.getExpressionType(); - - validateTypes(leftType, rightType, context); - } - - protected abstract void validateTypes(@NotNull Type leftType, @NotNull Type rightType, @NotNull TypesContext context); - - @Override - public void visit(@NotNull ExpressionVisitor visitor) { - visitor.handleBiOperator(this); - } - - public static @NotNull BiOperator parseBiOperator(@NotNull ExpressionNode left, @NotNull Token operand, @NotNull ExpressionNode right) { - TokenPosition pos = operand.pos(); - return switch (operand.getType()) { - case OPE_ADD -> new AddOperator(pos, left, right); - case OPE_SUB -> new SubOperator(pos, left, right); - case OPE_MUL, OPE_DIV -> new MulDivOperator(operand, left, right); - case COMP_EQ, COMP_NE, - COMP_GE, COMP_GT, - COMP_LE, COMP_LT, - OPE_AND, OPE_OR -> new LogicalOperator(operand, left, right); - case LIST_ADD, LIST_REM, LIST_REM_INDEX, LIST_CONTAINS -> new ListOperator(operand, left, right); - default -> throw new SyntaxException(operand, "Unknown Bi-operator."); - }; - } - - public @NotNull ExpressionNode getLeft() { - return left; - } - - public @NotNull ExpressionNode getRight() { - return right; - } - - public enum BiOpeType { - - // Math - - ADD, - SUB, - MUL, - DIV, - - // Logical - - EQUAL, - NOT_EQUAL, - GREATER_OR_EQ, - GREATER, - LESSER_OR_EQ, - LESSER, - - AND, - OR, - - // List - - LIST_ADD, - LIST_REM, - LIST_REM_INDEX, - LIST_CONTAINS - } - -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/operators/ListOperator.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/operators/ListOperator.java deleted file mode 100644 index 4a682153..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/operators/ListOperator.java +++ /dev/null @@ -1,79 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.operators; - -import fr.jamailun.ultimatespellsystem.dsl.errors.TypeException; -import fr.jamailun.ultimatespellsystem.dsl.nodes.ExpressionNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.VariableExpression; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Type; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.variables.TypesContext; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.variables.VariableDefinition; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.variables.VariableReference; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.Token; -import org.jetbrains.annotations.NotNull; - -/** - * A list operator. Can be one of a {@link BiOpeType} for lists. - */ -public class ListOperator extends BiOperator { - - private final BiOpeType opeType; - - public ListOperator(@NotNull Token operand, @NotNull ExpressionNode left, @NotNull ExpressionNode right) { - super(operand.pos(), left, right); - opeType = switch (operand.getType()) { - case LIST_ADD -> BiOpeType.LIST_ADD; - case LIST_REM -> BiOpeType.LIST_REM; - case LIST_REM_INDEX -> BiOpeType.LIST_REM_INDEX; - case LIST_CONTAINS -> BiOpeType.LIST_CONTAINS; - default -> throw new RuntimeException("Unreachable."); - }; - } - - @Override - public @NotNull BiOpeType getType() { - return opeType; - } - - @Override - protected void validateTypes(@NotNull Type leftType, @NotNull Type rightType, @NotNull TypesContext context) { - // Left must be a list, right cannot be null. - if(rightType.is(TypePrimitive.NULL)) - throw new TypeException(firstTokenPosition(), "Cannot apply an operator with a NULL-typed right operand (" + right + ")"); - if(! leftType.isCollection()) - throw new TypeException(firstTokenPosition(), "A list operator (" + opeType + ") can ONLY be applied on a LIST for the left operand. Left is " + leftType); - - // We can, eventually, help to figure-out what variable - if(opeType != BiOpeType.LIST_REM_INDEX) { - if(left.getExpressionType().is(TypePrimitive.NULL)) { - helpCompleteVariable(rightType, context); - } else if(leftType.primitive() != rightType.primitive()) { - throw new TypeException(firstTokenPosition(), "Cannot have heterogeneous lists. List is " + leftType + ", right operand is " + rightType); - } - } - - // if REM_INDEX, right must be numbers - if(opeType == BiOpeType.LIST_REM_INDEX && ! rightType.is(TypePrimitive.NUMBER)) - throw new TypeException(firstTokenPosition(), "A LIST_REM_INDEX operator can only accept a NUMBER for the right operant."); - - // Produced type is either the left side, either a BOOL for the contains operator. - if(opeType == BiOpeType.LIST_CONTAINS) { - producedType = TypePrimitive.BOOLEAN.asType(); - } else { - producedType = leftType; - } - } - - private void helpCompleteVariable(Type rightType, TypesContext context) { - if(left instanceof VariableExpression varExpr) { - VariableDefinition var = context.findVariable(varExpr.getVariableName()); - if(var != null) { - var.register(new VariableReference.Constant(rightType.asCollection(), firstTokenPosition())); - } - } - } - - @Override - public String toString() { - return left + " " + opeType + " " + right; - } -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/operators/LogicalOperator.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/operators/LogicalOperator.java deleted file mode 100644 index b0575072..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/operators/LogicalOperator.java +++ /dev/null @@ -1,75 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.operators; - -import fr.jamailun.ultimatespellsystem.dsl.errors.TypeException; -import fr.jamailun.ultimatespellsystem.dsl.nodes.ExpressionNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Type; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.variables.TypesContext; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.Token; -import org.jetbrains.annotations.NotNull; - -/** - * A logical operator, returning a boolean after comparing two expressions. - */ -public class LogicalOperator extends BiOperator { - - private final BiOpeType type; - - /** - * New instance. - * @param operator token to use. - * @param left first operand. - * @param right second operand - */ - public LogicalOperator(Token operator, ExpressionNode left, ExpressionNode right) { - super(operator.pos(), left, right); - this.type = switch (operator.getType()) { - case COMP_EQ -> BiOpeType.EQUAL; - case COMP_NE -> BiOpeType.NOT_EQUAL; - case COMP_LE -> BiOpeType.LESSER_OR_EQ; - case COMP_LT -> BiOpeType.LESSER; - case COMP_GE -> BiOpeType.GREATER_OR_EQ; - case COMP_GT -> BiOpeType.GREATER; - case OPE_AND -> BiOpeType.AND; - case OPE_OR -> BiOpeType.OR; - default -> throw new RuntimeException("Invalid logical operator : " + operator + " at " + operator.pos()); - }; - } - - @Override - public void validateTypes(@NotNull Type leftType, @NotNull Type rightType, @NotNull TypesContext context) { - // Do not allow collections - if(leftType.isCollection() || rightType.isCollection()) { - throw new TypeException(this, "A " + type + " cannot handle collections."); - } - - // Only allow same type (but still allow NULL :) ) - if(!(leftType.is(TypePrimitive.NULL) || rightType.is(TypePrimitive.NULL))) { - if (leftType.primitive() != rightType.primitive()) { - throw new TypeException(firstTokenPosition(), "Logical operator " + this + " has unequal types : " + leftType + " and " + rightType + "."); - } - } - - // If inequality, must be numeric - if(type == BiOpeType.GREATER || type == BiOpeType.GREATER_OR_EQ || type == BiOpeType.LESSER || type == BiOpeType.LESSER_OR_EQ) { - if(leftType.primitive() != TypePrimitive.NUMBER && leftType.primitive() != TypePrimitive.DURATION) { - throw new TypeException(this, "A comparison can only compare numeric values !"); - } - } - } - - @Override - public @NotNull BiOpeType getType() { - return type; - } - - @Override - public @NotNull Type getExpressionType() { - return TypePrimitive.BOOLEAN.asType(); - } - - @Override - public String toString() { - return "(" + left + " " + type + " " + right + ")"; - } -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/operators/MathFunctionOperator.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/operators/MathFunctionOperator.java deleted file mode 100644 index 3525b0ee..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/operators/MathFunctionOperator.java +++ /dev/null @@ -1,55 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.operators; - -import fr.jamailun.ultimatespellsystem.dsl.errors.TypeException; -import fr.jamailun.ultimatespellsystem.dsl.nodes.ExpressionNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Type; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenPosition; -import org.jetbrains.annotations.NotNull; - -/** - * Math-function mono-operator. - */ -public class MathFunctionOperator extends MonoOperator { - - private final MonoOpeType type; - - /** - * New instance. - * @param pos position of the token. - * @param expression expression to use. - * @param type type of operator. - */ - public MathFunctionOperator(@NotNull TokenPosition pos, @NotNull ExpressionNode expression, @NotNull MonoOpeType type) { - super(pos, expression); - this.type = type; - } - - @Override - public @NotNull MonoOpeType getType() { - return type; - } - - @Override - public void validateTypes(@NotNull Type childType) { - // No collection - if(childType.isCollection()) { - throw new TypeException(this, "A MathOperation("+type+") cannot handle collections."); - } - - // Only numbers - if(! childType.is(TypePrimitive.NUMBER)) { - throw new TypeException(this, "A MathOperation("+type+") can only handle numbers."); - } - } - - @Override - public @NotNull Type getExpressionType() { - return TypePrimitive.NUMBER.asType(); - } - - @Override - public String toString() { - return type + "(" + child + ")"; - } -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/operators/MonoOperator.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/operators/MonoOperator.java deleted file mode 100644 index b41790f9..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/operators/MonoOperator.java +++ /dev/null @@ -1,71 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.operators; - -import fr.jamailun.ultimatespellsystem.dsl.nodes.ExpressionNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Type; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.variables.TypesContext; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenPosition; -import fr.jamailun.ultimatespellsystem.dsl.visitor.ExpressionVisitor; -import lombok.Getter; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.Arrays; -import java.util.function.Function; - -/** - * Mono-operator, on a single expression. - */ -@Getter -public abstract class MonoOperator extends ExpressionNode { - - protected final ExpressionNode child; - - protected MonoOperator(TokenPosition position, ExpressionNode child) { - super(position); - this.child = child; - } - - /** - * Get this instance type of operation. - * @return a non-null type of mono-operation. - */ - public abstract @NotNull MonoOpeType getType(); - - @Override - public void visit(@NotNull ExpressionVisitor visitor) { - visitor.handleMonoOperator(this); - } - - @Override - public final void validateTypes(@NotNull TypesContext context) { - child.validateTypes(context); - - validateTypes(child.getExpressionType()); - } - - /** - * Validate the static-type of the code usage. - * @param childType the type to test. - */ - public abstract void validateTypes(@NotNull Type childType); - - public enum MonoOpeType { - NOT(x -> x), - SIN(x -> Math.sin(x.doubleValue())), - COS(x -> Math.cos(x.doubleValue())), - TAN(x -> Math.tan(x.doubleValue())), - SQRT(x -> Math.sqrt(x.doubleValue())), - ABS(x -> x instanceof Integer || x instanceof Long || x instanceof Short || x instanceof Byte ? Math.abs(x.longValue()) : Math.abs(x.doubleValue())), - ; - public final Function function; - MonoOpeType(Function function) { - this.function = function; - } - public static @Nullable MonoOpeType find(@NotNull String value) { - return Arrays.stream(values()) - .filter(v -> v.name().equalsIgnoreCase(value)) - .findAny().orElse(null); - } - } - -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/operators/MulDivOperator.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/operators/MulDivOperator.java deleted file mode 100644 index 8d982d50..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/operators/MulDivOperator.java +++ /dev/null @@ -1,69 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.operators; - -import fr.jamailun.ultimatespellsystem.dsl.errors.TypeException; -import fr.jamailun.ultimatespellsystem.dsl.nodes.ExpressionNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Type; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.variables.TypesContext; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.Token; -import org.jetbrains.annotations.NotNull; - -/** - * Multiplication or division. - */ -public class MulDivOperator extends BiOperator { - - private final BiOpeType type; - - /** - * New instance. - * @param operatorToken token to use. - * @param left first operand. - * @param right second operand - */ - public MulDivOperator(Token operatorToken, ExpressionNode left, ExpressionNode right) { - super(operatorToken.pos(), left, right); - type = switch (operatorToken.getType()) { - case OPE_MUL -> BiOpeType.MUL; - case OPE_DIV -> BiOpeType.DIV; - default -> throw new RuntimeException("Cannot create MulDivOperator with an operand: " + operatorToken + operatorToken.pos()); - }; - } - - @Override - public @NotNull BiOpeType getType() { - return type; - } - - @Override - public void validateTypes(@NotNull Type leftType, @NotNull Type rightType, @NotNull TypesContext context) { - // 1) Do not allow collections - if(leftType.isCollection() || rightType.isCollection()) { - throw new TypeException(this, "A "+type+" cannot handle collections."); - } - - // 2.a) Allow duration/duration - if(leftType.is(TypePrimitive.DURATION) && rightType.is(TypePrimitive.DURATION)) { - producedType = TypePrimitive.NUMBER.asType(); - return; - } - - // 2.b) Only allow number on the right. - if(! rightType.is(TypePrimitive.NUMBER)) { - throw new TypeException(this, "Right expression is of type " + rightType + " : must be a number for "+type+" operand."); - } - - // 3) Allow : (DURATION/LOCATION/NUMBER) with (NUMBER) - if(leftType.is(TypePrimitive.DURATION) || leftType.is(TypePrimitive.LOCATION) || leftType.is(TypePrimitive.NUMBER)) { - producedType = leftType; - return; - } - - throw new TypeException(this, "Incompatibles types for an SUB : " + leftType + " and " + rightType); - } - - @Override - public String toString() { - return "(" + left + (type==BiOpeType.MUL?"*":"/") + right + ")"; - } -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/operators/NotOperator.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/operators/NotOperator.java deleted file mode 100644 index dcfb4b78..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/operators/NotOperator.java +++ /dev/null @@ -1,51 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.operators; - -import fr.jamailun.ultimatespellsystem.dsl.errors.TypeException; -import fr.jamailun.ultimatespellsystem.dsl.nodes.ExpressionNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Type; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.Token; -import org.jetbrains.annotations.NotNull; - -/** - * A NOT Operator for a boolean child-expression. - */ -public class NotOperator extends MonoOperator { - - /** - * New instance. - * @param token token, for the position. - * @param expression expression to invert. - */ - public NotOperator(@NotNull Token token, ExpressionNode expression) { - super(token.pos(), expression); - } - - @Override - public @NotNull MonoOpeType getType() { - return MonoOpeType.NOT; - } - - @Override - public void validateTypes(@NotNull Type childType) { - // No collection - if(childType.isCollection()) { - throw new TypeException(this, "A NEGATION cannot handle collections."); - } - - // Only booleans - if(! childType.is(TypePrimitive.BOOLEAN)) { - throw new TypeException(this, "A NEGATION can only handle booleans."); - } - } - - @Override - public @NotNull Type getExpressionType() { - return TypePrimitive.BOOLEAN.asType(); - } - - @Override - public String toString() { - return "NOT(" + child + ")"; - } -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/operators/Operator.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/operators/Operator.java deleted file mode 100644 index 8d3f931f..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/operators/Operator.java +++ /dev/null @@ -1,43 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.operators; - -import fr.jamailun.ultimatespellsystem.dsl.errors.TypeException; -import fr.jamailun.ultimatespellsystem.dsl.nodes.ExpressionNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Type; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenPosition; -import org.jetbrains.annotations.NotNull; - -/** - * Operator : application of something on another expression. - */ -public abstract class Operator extends ExpressionNode { - - /** - * Saved output type. Cache it here. - */ - protected Type producedType; - - /** - * New operator instance, at a position. - * @param position position to use. - */ - protected Operator(@NotNull TokenPosition position) { - super(position); - } - - /** - * Check the type can be used for math. - * @param a type to use. - */ - protected void assertNotMathIncompatible(@NotNull Type a) { - switch (a.primitive()) { - case NULL, BOOLEAN, ENTITY_TYPE, ENTITY, STRING - -> throw new TypeException(this, "has type " + getExpressionType() + ". Type incompatible with a math operator."); - default -> {/* Nothing*/} - } - } - - @Override - public @NotNull Type getExpressionType() { - return producedType; - } -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/operators/SubOperator.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/operators/SubOperator.java deleted file mode 100644 index 0152131d..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/expressions/operators/SubOperator.java +++ /dev/null @@ -1,59 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.operators; - -import fr.jamailun.ultimatespellsystem.dsl.errors.TypeException; -import fr.jamailun.ultimatespellsystem.dsl.nodes.ExpressionNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Type; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.variables.TypesContext; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenPosition; -import org.jetbrains.annotations.NotNull; - -import java.util.List; - -/** - * Subtraction operation between two expressions. - */ -public class SubOperator extends BiOperator { - /** - * New instance. - * @param pos token position. - * @param left first expression. - * @param right second expression. - */ - public SubOperator(TokenPosition pos, ExpressionNode left, ExpressionNode right) { - super(pos, left, right); - } - - @Override - public @NotNull BiOpeType getType() { - return BiOpeType.SUB; - } - - private final static List ALLOWED = List.of(TypePrimitive.NUMBER, TypePrimitive.DURATION, TypePrimitive.LOCATION); - - @Override - public void validateTypes(@NotNull Type leftType, @NotNull Type rightType, @NotNull TypesContext context) { - // No collections ! - if(leftType.isCollection() || rightType.isCollection()) { - throw new TypeException(this, "A NEGATION cannot handle collections."); - } - - if(!ALLOWED.contains(leftType.primitive())) - throw new TypeException(this, "SUB cannot handle L=" + leftType); - if(!ALLOWED.contains(rightType.primitive())) - throw new TypeException(this, "SUB cannot handle R=" + rightType); - - // Otherwise same type : always compatible - if(leftType.primitive() == rightType.primitive()) { - producedType = leftType; - return; - } - - throw new TypeException(this, "Incompatibles types for an SUB : " + leftType + " and " + rightType); - } - - @Override - public String toString() { - return "(" + left + "-" + right + ")"; - } -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/BlockStatement.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/BlockStatement.java deleted file mode 100644 index c4d9f1b4..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/BlockStatement.java +++ /dev/null @@ -1,65 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes.statements; - -import fr.jamailun.ultimatespellsystem.dsl.nodes.StatementNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.variables.TypesContext; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.PreviousIndicator; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenStream; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenType; -import fr.jamailun.ultimatespellsystem.dsl.visitor.StatementVisitor; -import lombok.Getter; -import lombok.RequiredArgsConstructor; -import org.jetbrains.annotations.NotNull; - -import java.util.ArrayList; -import java.util.List; -import java.util.StringJoiner; - -/** - * A block statement is a sequence of statements between brackets. - */ -@Getter -@RequiredArgsConstructor -public class BlockStatement extends StatementNode { - - protected final List children; - - @Override - public void validateTypes(@NotNull TypesContext context) { - TypesContext contextChild = context.childContext(); - for(StatementNode child : children) { - child.validateTypes(contextChild); - } - } - - @Override - public void visit(@NotNull StatementVisitor visitor) { - visitor.handleBlock(this); - } - - /** - * Parse a block statement. - * @param tokens streams of tokens. - * @return a new instance. - */ - @PreviousIndicator(expected = {TokenType.BRACES_OPEN}) - public static @NotNull BlockStatement parseNextBlock(@NotNull TokenStream tokens) { - List list = new ArrayList<>(); - - while(tokens.hasMore()) { - if(tokens.peek().getType() == TokenType.BRACES_CLOSE) { - break; - } - list.add(StatementNode.parseNextStatement(tokens)); - } - tokens.dropOrThrow(TokenType.BRACES_CLOSE, "A '}' is required after a block statement."); - - return new BlockStatement(list); - } - - @Override - public String toString() { - StringJoiner sj = new StringJoiner("; ", "{", "}"); - children.forEach(c -> sj.add(c.toString())); - return sj.toString(); - } -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/BreakContinueStatement.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/BreakContinueStatement.java deleted file mode 100644 index 33e2f6bf..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/BreakContinueStatement.java +++ /dev/null @@ -1,47 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes.statements; - -import fr.jamailun.ultimatespellsystem.dsl.nodes.StatementNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.variables.TypesContext; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.PreviousIndicator; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenStream; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenType; -import fr.jamailun.ultimatespellsystem.dsl.visitor.StatementVisitor; -import lombok.Getter; -import lombok.RequiredArgsConstructor; -import org.jetbrains.annotations.NotNull; - -/** - * Either a {@code break} or a {@code continue}. - */ -@RequiredArgsConstructor -@Getter -public class BreakContinueStatement extends StatementNode { - - private final boolean isContinue; - - @Override - public void visit(@NotNull StatementVisitor visitor) { - visitor.handleBreakContinue(this); - } - - @Override - public void validateTypes(@NotNull TypesContext context) { - // We don't have anything to do ! - } - - @Override - public String toString() { - return isContinue ? "continue" : "break"; - } - - /** - * Parse a break/continue statement. - * @param tokens streams of tokens. - * @return a new instance. - */ - @PreviousIndicator(expected = {TokenType.BREAK, TokenType.CONTINUE}) - public static @NotNull BreakContinueStatement parseNextBreakContinue(@NotNull TokenStream tokens, boolean isContinue) { - tokens.dropOrThrow(TokenType.SEMI_COLON); - return new BreakContinueStatement(isContinue); - } -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/DefineStatement.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/DefineStatement.java deleted file mode 100644 index 4cb8a4c0..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/DefineStatement.java +++ /dev/null @@ -1,71 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes.statements; - -import fr.jamailun.ultimatespellsystem.dsl.nodes.ExpressionNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.StatementNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.variables.TypesContext; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.PreviousIndicator; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.Token; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenStream; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenType; -import fr.jamailun.ultimatespellsystem.dsl.visitor.StatementVisitor; -import lombok.Getter; -import lombok.RequiredArgsConstructor; -import org.jetbrains.annotations.NotNull; - -/** - * Define statement will set a variable to something. - */ -@Getter -@RequiredArgsConstructor -public class DefineStatement extends StatementNode { - - private final String varName; - private final ExpressionNode expression; - - @Override - public void validateTypes(@NotNull TypesContext context) { - expression.validateTypes(context); - // Register variable - context.registerVariable(varName, expression); - } - - @Override - public void visit(@NotNull StatementVisitor visitor) { - visitor.handleDefine(this); - } - - @Override - public String toString() { - return "DEFINE{%" + varName + " <- " + expression + "}"; - } - - /** - * Parse a define statement. - * @param tokens streams of tokens. - * @return a new instance. - */ - @PreviousIndicator(expected = {TokenType.DEFINE}) - public static @NotNull StatementNode parseNextDefine(@NotNull TokenStream tokens) { - // %VAR_NAME - Token varToken = tokens.nextOrThrow(TokenType.VALUE_VARIABLE); - String varName = varToken.getContentString(); - - // = - if(tokens.dropOptional(TokenType.LIST_ADD, TokenType.LIST_REM, TokenType.LIST_REM_INDEX, TokenType.LIST_CONTAINS)) { - // Wait, this is not a define statement: it's a list-ope ! - tokens.back(); - tokens.back(); - StatementNode statement = new SimpleExpressionStatement( ExpressionNode.readNextExpression(tokens) ); - tokens.dropOptional(TokenType.SEMI_COLON); - return statement; - } - tokens.dropOrThrow(TokenType.EQUAL); - - ExpressionNode expression = ExpressionNode.readNextExpression(tokens); - - // optional ; - tokens.dropOptional(TokenType.SEMI_COLON); - - return new DefineStatement(varName, expression); - } -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/GiveStatement.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/GiveStatement.java deleted file mode 100644 index c3204dd2..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/GiveStatement.java +++ /dev/null @@ -1,96 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes.statements; - -import fr.jamailun.ultimatespellsystem.dsl.nodes.ExpressionNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.StatementNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.litteral.NumberExpression; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.variables.TypesContext; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.PreviousIndicator; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenStream; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenType; -import fr.jamailun.ultimatespellsystem.dsl.visitor.StatementVisitor; -import lombok.Getter; -import lombok.RequiredArgsConstructor; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -/** - * A give-statement, to five an ItemStack to a Player. - */ -@Getter -@RequiredArgsConstructor -public class GiveStatement extends StatementNode { - - private final @NotNull ExpressionNode target; - private final @Nullable ExpressionNode optAmount; - private final @Nullable ExpressionNode optType; - private final @Nullable ExpressionNode optProperties; - - @Override - public void visit(@NotNull StatementVisitor visitor) { - visitor.handleGive(this); - } - - @Override - public void validateTypes(@NotNull TypesContext context) { - assertExpressionType(target, context, TypePrimitive.ENTITY); - if(optAmount != null) - assertExpressionType(optAmount, context, TypePrimitive.NUMBER); - if(optType != null) - assertExpressionType(optType, context, TypePrimitive.STRING, TypePrimitive.CUSTOM); - if(optProperties != null) - assertExpressionType(optProperties, context, TypePrimitive.PROPERTIES_SET); - } - - @Override - public String toString() { - return "GIVE{" - + (getOptAmount()==null?"":getOptAmount()+" ") - + (getOptType()==null?"":getOptType()+" ") - + "TO " + getTarget() - + (getOptProperties()==null?"":" WITH: " + getOptProperties())+"}"; - } - - /** - * Parse a give statement. - * @param tokens streams of tokens. - * @return a new instance. - */ - @PreviousIndicator(expected = TokenType.GIVE) // GIVE [[] ] TO [WITH: ] - public static @NotNull GiveStatement parseNextGiveStatement(@NotNull TokenStream tokens) { - // Amount + type. both are optional, but 'amount' is even more optional. - ExpressionNode amount, type; - if(tokens.dropOptional(TokenType.TO)) { - // No amount + type - amount = null; - type = null; - } else { - ExpressionNode node = ExpressionNode.readNextExpression(tokens, true); - if(tokens.dropOptional(TokenType.TO)) { - type = node; - amount = new NumberExpression(tokens.position(), 1); - } else { - amount = node; - type = ExpressionNode.readNextExpression(tokens, true); - tokens.dropOrThrow(TokenType.TO); - } - } - - // Now, target - ExpressionNode target = ExpressionNode.readNextExpression(tokens); - - // With ? - ExpressionNode properties; - if(tokens.dropOptional(TokenType.WITH)) { - tokens.dropOrThrow(TokenType.COLON); - properties = ExpressionNode.readNextExpression(tokens); - } else { - properties = null; - } - - tokens.dropOptional(TokenType.SEMI_COLON); - - // create - return new GiveStatement(target, amount, type, properties); - } -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/IncrementStatement.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/IncrementStatement.java deleted file mode 100644 index 0f4ff738..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/IncrementStatement.java +++ /dev/null @@ -1,58 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes.statements; - -import fr.jamailun.ultimatespellsystem.dsl.errors.SyntaxException; -import fr.jamailun.ultimatespellsystem.dsl.errors.TypeException; -import fr.jamailun.ultimatespellsystem.dsl.nodes.StatementNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Type; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.variables.TypesContext; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.variables.VariableDefinition; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.*; -import fr.jamailun.ultimatespellsystem.dsl.visitor.StatementVisitor; -import lombok.Getter; -import lombok.RequiredArgsConstructor; -import org.jetbrains.annotations.NotNull; - -/** - * Either {@code increment} or {@code decrement}. - */ -@Getter -@RequiredArgsConstructor -public class IncrementStatement extends StatementNode { - - private final TokenPosition tokenPosition; - private final String varName; - private final boolean positive; - - @Override - public void validateTypes(@NotNull TypesContext context) { - VariableDefinition variableDefinition = context.findVariable(varName); - if(variableDefinition == null) - throw new SyntaxException(tokenPosition, "Unknown variable to " + (positive?"increment":"decrement") + " : '" + varName + "'."); - Type type = variableDefinition.getType(context); - if(type.primitive() != TypePrimitive.NUMBER) - throw new TypeException(tokenPosition, "For " + (positive?"increment":"decrement") + " %"+varName+", expected NUMBER. Got type " + type + "."); - } - - @Override - public void visit(@NotNull StatementVisitor visitor) { - visitor.handleIncrement(this); - } - - /** - * Parse a increment/decrement statement. - * @param tokens streams of tokens. - * @return a new instance. - */ - @PreviousIndicator(expected = {TokenType.INCREMENT, TokenType.DECREMENT}) - public static @NotNull IncrementStatement parseIncrementOrDecrement(@NotNull TokenStream tokens, boolean increment) { - Token var = tokens.nextOrThrow(TokenType.VALUE_VARIABLE); - tokens.dropOptional(TokenType.SEMI_COLON); - return new IncrementStatement(var.pos(), var.getContentString(), increment); - } - - @Override - public String toString() { - return (positive ?"++":"--") + "%" + varName; - } -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/MetadataStatement.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/MetadataStatement.java deleted file mode 100644 index 40e08b13..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/MetadataStatement.java +++ /dev/null @@ -1,89 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes.statements; - -import fr.jamailun.ultimatespellsystem.dsl.metadata.MetadataRulesManager; -import fr.jamailun.ultimatespellsystem.dsl.nodes.StatementNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Duration; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.variables.TypesContext; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.*; -import fr.jamailun.ultimatespellsystem.dsl.visitor.StatementVisitor; -import lombok.Getter; -import lombok.RequiredArgsConstructor; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.annotations.Unmodifiable; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.StringJoiner; - -/** - * A metadata statement of a spell. - * Should not be "executed" as such. - */ -@RequiredArgsConstructor -@Getter -public class MetadataStatement extends StatementNode { - - private final TokenPosition position; - private final @NotNull String name; - private final @NotNull @Unmodifiable List params; - - /** - * Parse a metadata statement. - * @param tokens streams of tokens. - * @return a new instance. - */ - @PreviousIndicator(expected = TokenType.CHAR_AT) - public static @NotNull MetadataStatement parseMetadata(@NotNull TokenStream tokens) { - TokenPosition position = tokens.position(); - List parameters = new ArrayList<>(); - - String name = tokens.nextOrThrow(TokenType.IDENTIFIER).getContentString(); - if(tokens.dropOptional(TokenType.BRACKET_OPEN)) { - Object raw; - while ((raw = readNextRaw(tokens)) != null) { - parameters.add(raw); - tokens.dropOptional(TokenType.COMMA); - } - tokens.dropOrThrow(TokenType.BRACKET_CLOSE); - } - - return new MetadataStatement(position, name, Collections.unmodifiableList(parameters)); - } - - private static @Nullable Object readNextRaw(@NotNull TokenStream tokens) { - Token token = tokens.peek(); - if(token.getType().isRawValue()) { - tokens.drop(); - return switch(token.getType()) { - case TRUE -> true; - case FALSE -> false; - case IDENTIFIER, VALUE_STRING -> token.getContentString(); - case VALUE_DURATION -> new Duration(token.getContentNumber(), token.getContentTimeUnit()); - case VALUE_NUMBER -> token.getContentNumber(); - default -> throw new RuntimeException("Not reachable (" + token + ")"); - }; - } - return null; - } - - @Override - public void visit(@NotNull StatementVisitor visitor) { - visitor.handleMetadata(this); - } - - @Override - public void validateTypes(@NotNull TypesContext context) { - MetadataRulesManager.getRulesForName(getName()) - .forEach(rule -> rule.apply(context, this)); - } - - @Override - public String toString() { - String prefix = "@" + getName() + "("; - StringJoiner sj = new StringJoiner(", "); - params.forEach(p -> sj.add(p.toString())); - return prefix + sj + ")"; - } -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/PlayStatement.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/PlayStatement.java deleted file mode 100644 index a882115f..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/PlayStatement.java +++ /dev/null @@ -1,97 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes.statements; - -import fr.jamailun.ultimatespellsystem.dsl.errors.SyntaxException; -import fr.jamailun.ultimatespellsystem.dsl.nodes.ExpressionNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.StatementNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.CollectionFilter; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.variables.TypesContext; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.PreviousIndicator; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.Token; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenStream; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenType; -import fr.jamailun.ultimatespellsystem.dsl.visitor.StatementVisitor; -import lombok.Getter; -import lombok.RequiredArgsConstructor; -import org.jetbrains.annotations.NotNull; - -/** - * A play statement : with a specific {@link Type}. - */ -@Getter -@RequiredArgsConstructor -public class PlayStatement extends StatementNode { - - private final Type type; - private final ExpressionNode location, properties; - - @Override - public void validateTypes(@NotNull TypesContext context) { - assertExpressionType(location, context, TypePrimitive.LOCATION, TypePrimitive.ENTITY); - assertExpressionType(properties, CollectionFilter.MONO_ELEMENT, context, TypePrimitive.PROPERTIES_SET); - } - - /** - * Parse a play statement. - * @param tokens streams of tokens. - * @return a new instance. - */ - @PreviousIndicator(expected = TokenType.PLAY) // PLAY AT WITH: ; - public static @NotNull PlayStatement parsePlay(@NotNull TokenStream tokens) { - Type type = readType(tokens); - tokens.dropOrThrow(TokenType.AT); - ExpressionNode location = ExpressionNode.readNextExpression(tokens); - tokens.dropOrThrow(TokenType.WITH); - tokens.dropOptional(TokenType.COLON); - ExpressionNode properties = ExpressionNode.readNextExpression(tokens); - tokens.dropOptional(TokenType.SEMI_COLON); - return new PlayStatement(type, location, properties); - } - - private static @NotNull Type readType(@NotNull TokenStream tokens) { - Token next = tokens.next(); - String nextValue = next.getContentString(); - return switch(nextValue.toLowerCase()) { - case "block", "b", "bloc" -> Type.BLOCK; - case "particle", "p", "part" -> Type.PARTICLE; - case "sound", "s" -> Type.SOUND; - case "animation", "a", "anim" -> Type.ANIMATION; - default -> throw new SyntaxException(next, "Expected either 'block', 'particle' or 'sound' after a 'PLAY' statement."); - }; - } - - @Override - public void visit(@NotNull StatementVisitor visitor) { - visitor.handlePlay(this); - } - - /** - * A type of {@link PlayStatement}. - */ - public enum Type { - /** - * An in-world block, changed for the clients. - */ - BLOCK, - - /** - * A particle-play, sent to clients. - */ - PARTICLE, - - /** - * A sound, played to nearby players. - */ - SOUND, - - /** - * Complex animation. - */ - ANIMATION - } - - @Override - public String toString() { - return "Play_"+type+" :: " + properties; - } -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/SendAttributeStatement.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/SendAttributeStatement.java deleted file mode 100644 index 278a25f9..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/SendAttributeStatement.java +++ /dev/null @@ -1,89 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes.statements; - -import fr.jamailun.ultimatespellsystem.dsl.nodes.ExpressionNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.CollectionFilter; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.variables.TypesContext; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.PreviousIndicator; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenStream; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenType; -import fr.jamailun.ultimatespellsystem.dsl.visitor.StatementVisitor; -import lombok.Getter; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.Optional; - -/** - * Send a bukkit Attribute to a Bukkit Entity. - */ -@Getter -public class SendAttributeStatement extends SendStatement { - - private final ExpressionNode numericValue; - private final ExpressionNode attributeType; - private final @Nullable ExpressionNode attributeMode; - private final ExpressionNode duration; - - public SendAttributeStatement(ExpressionNode target, ExpressionNode numericValue, ExpressionNode attributeType, @Nullable ExpressionNode attributeMode, ExpressionNode duration) { - super(target); - this.numericValue = numericValue; - this.attributeType = attributeType; - this.attributeMode = attributeMode; - this.duration = duration; - } - - @Override - public void validateTypes(@NotNull TypesContext context) { - super.validateTypes(context); - - assertExpressionType(numericValue, CollectionFilter.MONO_ELEMENT, context, TypePrimitive.NUMBER); - assertExpressionType(attributeType, CollectionFilter.MONO_ELEMENT, context, TypePrimitive.CUSTOM, TypePrimitive.STRING); - assertExpressionType(duration, CollectionFilter.MONO_ELEMENT, context, TypePrimitive.DURATION); - if(attributeMode != null) - assertExpressionType(attributeMode, CollectionFilter.MONO_ELEMENT, context, TypePrimitive.CUSTOM, TypePrimitive.STRING); - } - - public Optional getAttributeMode() { - return Optional.ofNullable(attributeMode); - } - - @Override - public void visit(@NotNull StatementVisitor visitor) { - visitor.handleSendAttribute(this); - } - - /** - * Parse a send-attribute statement. Called by {@link SendStatement#parseSendStatement(TokenStream)}. - * @param tokens streams of tokens. - * @return a new instance. - */ - @PreviousIndicator(expected = {TokenType.SEND/* + ATTRIBUTE */}) - public static @NotNull SendAttributeStatement parseAttributeEffect(@NotNull ExpressionNode target, @NotNull TokenStream tokens) { - // Value - ExpressionNode numericValue = ExpressionNode.readNextExpression(tokens); - - // Type - ExpressionNode attributeType = ExpressionNode.readNextExpression(tokens, true); - - // Syntax: "[mode] for " - ExpressionNode mode = null; - if( ! tokens.dropOptional(TokenType.FOR)) { - mode = ExpressionNode.readNextExpression(tokens, true); - tokens.dropOrThrow(TokenType.FOR); - } - - ExpressionNode duration = ExpressionNode.readNextExpression(tokens); - - // Optional EOL - tokens.dropOptional(TokenType.SEMI_COLON); - - // return - return new SendAttributeStatement(target, numericValue, attributeType, mode, duration); - } - - @Override - public String toString() { - return "SEND_ATTRIBUTE{to="+target+", attr=" + numericValue + " " + attributeType + (attributeMode==null?"":" ("+attributeMode + ")") + ", for=" + duration + "}"; - } -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/SendEffectStatement.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/SendEffectStatement.java deleted file mode 100644 index fdef6063..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/SendEffectStatement.java +++ /dev/null @@ -1,82 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes.statements; - -import fr.jamailun.ultimatespellsystem.dsl.nodes.ExpressionNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.CollectionFilter; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.variables.TypesContext; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.PreviousIndicator; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenStream; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenType; -import fr.jamailun.ultimatespellsystem.dsl.visitor.StatementVisitor; -import lombok.Getter; -import org.jetbrains.annotations.NotNull; - -import java.util.Optional; - -/** - * Send a potion effect to a Bukkit entity. - */ -public class SendEffectStatement extends SendStatement { - - @Getter private final ExpressionNode effectType; - @Getter private final ExpressionNode effectDuration; - private final ExpressionNode effectPower; // nullable ! - - public SendEffectStatement(ExpressionNode target, ExpressionNode effectType, ExpressionNode effectDuration, ExpressionNode effectPower) { - super(target); - this.effectType = effectType; - this.effectDuration = effectDuration; - this.effectPower = effectPower; - } - - @Override - public void validateTypes(@NotNull TypesContext context) { - super.validateTypes(context); - - assertExpressionType(effectType, CollectionFilter.MONO_ELEMENT, context, TypePrimitive.STRING, TypePrimitive.CUSTOM); - assertExpressionType(effectDuration, CollectionFilter.MONO_ELEMENT, context, TypePrimitive.DURATION); - if(effectPower != null) - assertExpressionType(effectPower, CollectionFilter.MONO_ELEMENT, context, TypePrimitive.NUMBER); - } - - public Optional getEffectPower() { - return Optional.ofNullable(effectPower); - } - - @Override - public void visit(@NotNull StatementVisitor visitor) { - visitor.handleSendEffect(this); - } - - /** - * Parse a send-effect statement. Called by {@link SendStatement#parseSendStatement(TokenStream)}. - * @param tokens streams of tokens. - * @return a new instance. - */ - @PreviousIndicator(expected = {TokenType.SEND/* + EFFECT */}) - public static @NotNull SendEffectStatement parseSendEffect(@NotNull ExpressionNode target, @NotNull TokenStream tokens) { - // Effect type - ExpressionNode effectType = ExpressionNode.readNextExpression(tokens, true); - - // If FOR just after : no power. - ExpressionNode effectPower; - if( ! tokens.dropOptional(TokenType.FOR)) { - effectPower = ExpressionNode.readNextExpression(tokens); - tokens.dropOrThrow(TokenType.FOR); - } else effectPower = null; - - // Duration - ExpressionNode effectDuration = ExpressionNode.readNextExpression(tokens); - - // Optional EOL - tokens.dropOptional(TokenType.SEMI_COLON); - - // return - return new SendEffectStatement(target, effectType, effectDuration, effectPower); - } - - @Override - public String toString() { - return "SEND_EFFECT{to="+target+", effect=" + effectType + (effectPower==null?"":", power="+effectPower) + ", for=" + effectDuration + "}"; - } -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/SendMessageStatement.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/SendMessageStatement.java deleted file mode 100644 index 50789411..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/SendMessageStatement.java +++ /dev/null @@ -1,56 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes.statements; - -import fr.jamailun.ultimatespellsystem.dsl.nodes.ExpressionNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.variables.TypesContext; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.PreviousIndicator; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenStream; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenType; -import fr.jamailun.ultimatespellsystem.dsl.visitor.StatementVisitor; -import lombok.Getter; -import org.jetbrains.annotations.NotNull; - -/** - * Send a message to a player. - */ -@Getter -public class SendMessageStatement extends SendStatement { - - private final ExpressionNode message; - - public SendMessageStatement(@NotNull ExpressionNode target, @NotNull ExpressionNode message) { - super(target); - this.message = message; - } - - @Override - public void validateTypes(@NotNull TypesContext context) { - super.validateTypes(context); - assertExpressionType(message, context, TypePrimitive.STRING); - } - - @Override - public void visit(@NotNull StatementVisitor visitor) { - visitor.handleSendMessage(this); - } - - /** - * Parse a send-message statement. Called by {@link SendStatement#parseSendStatement(TokenStream)}. - * @param tokens streams of tokens. - * @return a new instance. - */ - @PreviousIndicator(expected = {TokenType.SEND/* + MESSAGE */}) - public static @NotNull SendMessageStatement parseSendMessage(@NotNull ExpressionNode target, @NotNull TokenStream tokens) { - ExpressionNode message = ExpressionNode.readNextExpression(tokens); - - // Optional EOL - tokens.dropOptional(TokenType.SEMI_COLON); - - return new SendMessageStatement(target, message); - } - - @Override - public String toString() { - return "SEND_MSG{to="+target+", " + message + "}"; - } -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/SendNbtStatement.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/SendNbtStatement.java deleted file mode 100644 index b15f4dc6..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/SendNbtStatement.java +++ /dev/null @@ -1,68 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes.statements; - -import fr.jamailun.ultimatespellsystem.dsl.nodes.ExpressionNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.CollectionFilter; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.variables.TypesContext; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.PreviousIndicator; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenStream; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenType; -import fr.jamailun.ultimatespellsystem.dsl.visitor.StatementVisitor; -import lombok.Getter; -import org.jetbrains.annotations.NotNull; - -/** - * Send a NBT k/v to a Bukkit entity. - */ -public class SendNbtStatement extends SendStatement { - - @Getter private final ExpressionNode nbtName; - @Getter private final ExpressionNode nbtValue; - @Getter private final ExpressionNode nbtDuration; - - public SendNbtStatement(ExpressionNode target, ExpressionNode nbtName, ExpressionNode nbtValue, ExpressionNode nbtDuration) { - super(target); - this.nbtName = nbtName; - this.nbtValue = nbtValue; - this.nbtDuration = nbtDuration; - } - - @Override - public void validateTypes(@NotNull TypesContext context) { - super.validateTypes(context); - - assertExpressionType(nbtName, CollectionFilter.MONO_ELEMENT, context, TypePrimitive.STRING, TypePrimitive.CUSTOM); - assertExpressionType(nbtDuration, CollectionFilter.MONO_ELEMENT, context, TypePrimitive.DURATION); - nbtValue.validateTypes(context.childContext()); - } - - @Override - public void visit(@NotNull StatementVisitor visitor) { - visitor.handleSendNbt(this); - } - - /** - * Parse a send-nbt statement. Called by {@link SendStatement#parseSendStatement(TokenStream)}. - * @param tokens streams of tokens. - * @return a new instance. - */ - @PreviousIndicator(expected = {TokenType.SEND/* + NBT */}) // = for ; - public static @NotNull SendNbtStatement parseSendNbt(@NotNull ExpressionNode target, @NotNull TokenStream tokens) { - ExpressionNode nbtName = ExpressionNode.readNextExpression(tokens, true); - tokens.dropOrThrow(TokenType.EQUAL); - ExpressionNode nbtValue = ExpressionNode.readNextExpression(tokens, true); - tokens.dropOrThrow(TokenType.FOR); - ExpressionNode nbtDuration = ExpressionNode.readNextExpression(tokens); - - // Optional EOL - tokens.dropOptional(TokenType.SEMI_COLON); - - // return - return new SendNbtStatement(target, nbtName, nbtValue, nbtDuration); - } - - @Override - public String toString() { - return "SEND_NBT{to="+target+", name=" + nbtName + ", val=" + nbtValue + ", for=" + nbtDuration + "}"; - } -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/SendStatement.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/SendStatement.java deleted file mode 100644 index 65e46461..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/SendStatement.java +++ /dev/null @@ -1,55 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes.statements; - -import fr.jamailun.ultimatespellsystem.dsl.errors.SyntaxException; -import fr.jamailun.ultimatespellsystem.dsl.nodes.ExpressionNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.StatementNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.variables.TypesContext; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.PreviousIndicator; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.Token; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenStream; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenType; -import lombok.Getter; -import lombok.RequiredArgsConstructor; -import org.jetbrains.annotations.NotNull; - -/** - * Abstract send statement. - */ -@Getter -@RequiredArgsConstructor -public abstract class SendStatement extends StatementNode { - - protected final ExpressionNode target; - - @Override - public void validateTypes(@NotNull TypesContext context) { - assertExpressionType(target, context, TypePrimitive.ENTITY); - } - - /** - * Parse a metadata statement. - * @param tokens streams of tokens. - * @return a new instance. - */ - @PreviousIndicator(expected = {TokenType.SEND}) // SEND (to) TARGET (...) - public static @NotNull StatementNode parseSendStatement(@NotNull TokenStream tokens) { - // Optional "to" - tokens.dropOptional(TokenType.TO); - - // Read target expression - ExpressionNode target = ExpressionNode.readNextExpression(tokens); - - // Type of send - Token token = tokens.next(); - String type = token.getContentString(); - return switch (type.toLowerCase()) { - case "message" -> SendMessageStatement.parseSendMessage(target, tokens); - case "effect" -> SendEffectStatement.parseSendEffect(target, tokens); - case "attribute", "attributes" -> SendAttributeStatement.parseAttributeEffect(target, tokens); - case "nbt" -> SendNbtStatement.parseSendNbt(target, tokens); - default -> throw new SyntaxException(token, "Expected SEND type to be one of (message, effect, attribute, nbt)."); - }; - } - -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/SimpleExpressionStatement.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/SimpleExpressionStatement.java deleted file mode 100644 index 92bd77ff..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/SimpleExpressionStatement.java +++ /dev/null @@ -1,40 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes.statements; - -import fr.jamailun.ultimatespellsystem.dsl.nodes.ExpressionNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.StatementNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.variables.TypesContext; -import fr.jamailun.ultimatespellsystem.dsl.visitor.StatementVisitor; -import lombok.Getter; -import org.jetbrains.annotations.NotNull; - -/** - * Wraps an {@link ExpressionNode} as a {@link StatementNode}. - */ -@Getter -public class SimpleExpressionStatement extends StatementNode { - - private final @NotNull ExpressionNode child; - - /** - * Create a new instance. - * @param child wrapped expression, as a statement. - */ - public SimpleExpressionStatement(@NotNull ExpressionNode child) { - this.child = child; - } - - @Override - public void visit(@NotNull StatementVisitor visitor) { - visitor.handleSimpleExpression(this); - } - - @Override - public void validateTypes(@NotNull TypesContext context) { - child.validateTypes(context); - } - - @Override - public String toString() { - return "{" + child + "}"; - } -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/StopStatement.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/StopStatement.java deleted file mode 100644 index f453d987..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/StopStatement.java +++ /dev/null @@ -1,57 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes.statements; - -import fr.jamailun.ultimatespellsystem.dsl.nodes.ExpressionNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.StatementNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.CollectionFilter; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.variables.TypesContext; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.PreviousIndicator; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenStream; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenType; -import fr.jamailun.ultimatespellsystem.dsl.visitor.StatementVisitor; -import lombok.AllArgsConstructor; -import lombok.Getter; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -/** - * A {@code stop} statement will stop the spell execution. - */ -@AllArgsConstructor -@Getter -public class StopStatement extends StatementNode { - - private final @Nullable ExpressionNode exitCodeNode; - - @Override - public void validateTypes(@NotNull TypesContext context) { - if(exitCodeNode != null) - assertExpressionType(exitCodeNode, CollectionFilter.MONO_ELEMENT, context, TypePrimitive.NUMBER); - } - - @Override - public void visit(@NotNull StatementVisitor visitor) { - visitor.handleStop(this); - } - - /** - * Parse a STOP statement. - * @param tokens streams of tokens. - * @return a new instance. - */ - @PreviousIndicator(expected = TokenType.STOP) - public static @NotNull StopStatement parseStop(@NotNull TokenStream tokens) { - if(tokens.dropOptional(TokenType.SEMI_COLON)) { - return new StopStatement(null); - } else { - ExpressionNode exitNode = ExpressionNode.readNextExpression(tokens); - tokens.dropOrThrow(TokenType.SEMI_COLON); - return new StopStatement(exitNode); - } - } - - @Override - public String toString() { - return "STOP" + (exitCodeNode==null?"":"(" + exitCodeNode + ")"); - } -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/SummonStatement.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/SummonStatement.java deleted file mode 100644 index a921c1b1..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/SummonStatement.java +++ /dev/null @@ -1,104 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes.statements; - -import fr.jamailun.ultimatespellsystem.dsl.nodes.ExpressionNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.StatementNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.CollectionFilter; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.variables.TypesContext; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.*; -import fr.jamailun.ultimatespellsystem.dsl.visitor.StatementVisitor; -import lombok.Getter; -import lombok.RequiredArgsConstructor; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.Optional; - -/** - * Summon an entity (by the caster). - */ -@RequiredArgsConstructor -public class SummonStatement extends StatementNode { - - @Getter private final @NotNull ExpressionNode entityType; - private final @Nullable ExpressionNode optSource; // nullable - private final @Nullable Token optVarName; // nullable - @Getter private final @NotNull ExpressionNode duration; - private final @Nullable ExpressionNode optProperties; // nullable - - @Override - public void validateTypes(@NotNull TypesContext context) { - assertExpressionType(entityType, CollectionFilter.MONO_ELEMENT, context, TypePrimitive.ENTITY_TYPE); - assertExpressionType(duration, CollectionFilter.MONO_ELEMENT, context, TypePrimitive.DURATION); - if(optProperties != null) - assertExpressionType(optProperties, CollectionFilter.MONO_ELEMENT, context, TypePrimitive.PROPERTIES_SET); - - // Register varName - if(optVarName != null) { - context.registerVariable(optVarName.getContentString(), optVarName.pos(), TypePrimitive.ENTITY.asType()); - } - } - - @Override - public void visit(@NotNull StatementVisitor visitor) { - visitor.handleSummon(this); - } - - /** - * Parse a summon statement. - * @param tokens streams of tokens. - * @return a new instance. - */ - // SUMMON (ENTITY_TYPE) [AT (POSITION/ENTITY)] [[AS (VAR_NAME)]] FOR (DURATION) [WITH : (PROPS)] - @PreviousIndicator(expected = {TokenType.SUMMON}) - public static @NotNull SummonStatement parseSummonStatement(@NotNull TokenStream tokens) { - //IRON_GOLEM as %ig for 10 seconds with: - ExpressionNode entityType = ExpressionNode.readNextExpression(tokens); - - ExpressionNode source = null; - if(tokens.dropOptional(TokenType.AT)) { - source = ExpressionNode.readNextExpression(tokens); - } - - // AS (VARIABLE) - Token varName = null; - if(tokens.dropOptional(TokenType.AS)) { - varName = tokens.nextOrThrow(TokenType.VALUE_VARIABLE); - } - - tokens.dropOrThrow(TokenType.FOR); - ExpressionNode duration = ExpressionNode.readNextExpression(tokens); - - ExpressionNode optProperties = null; - if(tokens.dropOptional(TokenType.WITH)) { - tokens.dropOrThrow(TokenType.COLON); - optProperties = ExpressionNode.readNextExpression(tokens); - } - - tokens.dropOptional(TokenType.SEMI_COLON); - - return new SummonStatement(entityType, source, varName, duration, optProperties); - } - - @Override - public String toString() { - return "SUMMON{" + entityType - + (optSource != null ? " AT " + optSource : "") - + (optVarName != null ? " AS %" + optVarName.getContentString() : "") - + " FOR " + duration - + (optProperties !=null?" WITH " + optProperties : "") - + "}"; - } - - public Optional getVarName() { - return optVarName == null ? Optional.empty() : Optional.of(optVarName.getContentString()); - } - - public Optional getProperties() { - return Optional.ofNullable(optProperties); - } - - public Optional getSource() { - return Optional.ofNullable(optSource); - } -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/TeleportStatement.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/TeleportStatement.java deleted file mode 100644 index 2b0ec572..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/TeleportStatement.java +++ /dev/null @@ -1,55 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes.statements; - -import fr.jamailun.ultimatespellsystem.dsl.nodes.ExpressionNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.StatementNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.CollectionFilter; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.variables.TypesContext; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.PreviousIndicator; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenStream; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenType; -import fr.jamailun.ultimatespellsystem.dsl.visitor.StatementVisitor; -import lombok.Getter; -import lombok.RequiredArgsConstructor; -import org.jetbrains.annotations.NotNull; - -/** - * Teleport a bukkit entity to a location (or another entity). - */ -@Getter -@RequiredArgsConstructor -public class TeleportStatement extends StatementNode { - - private final ExpressionNode entity; - private final ExpressionNode target; - - @Override - public void validateTypes(@NotNull TypesContext context) { - assertExpressionType(entity, context, TypePrimitive.ENTITY); - assertExpressionType(target, CollectionFilter.MONO_ELEMENT, context, TypePrimitive.ENTITY, TypePrimitive.LOCATION); - } - - @Override - public void visit(@NotNull StatementVisitor visitor) { - visitor.handleTeleport(this); - } - - /** - * Parse a teleport statement. - * @param tokens streams of tokens. - * @return a new instance. - */ - @PreviousIndicator(expected = TokenType.TELEPORT) - public static @NotNull TeleportStatement parseTeleport(@NotNull TokenStream tokens) { - ExpressionNode entity = ExpressionNode.readNextExpression(tokens); - tokens.dropOrThrow(TokenType.TO); - ExpressionNode target = ExpressionNode.readNextExpression(tokens); - tokens.dropOptional(TokenType.SEMI_COLON); - return new TeleportStatement(entity, target); - } - - @Override - public String toString() { - return "TELEPORT " + entity + " TO " + target; - } -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/blocks/BlockHolder.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/blocks/BlockHolder.java deleted file mode 100644 index 299c25ec..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/blocks/BlockHolder.java +++ /dev/null @@ -1,34 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes.statements.blocks; - -import fr.jamailun.ultimatespellsystem.dsl.nodes.StatementNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.statements.BlockStatement; -import org.jetbrains.annotations.NotNull; - -import java.util.List; - -/** - * Wraps another statement. - */ -public abstract class BlockHolder extends StatementNode { - - protected final StatementNode child; - - /** - * New instance. - * @param child child "block". - */ - protected BlockHolder(@NotNull StatementNode child) { - if(child instanceof BlockStatement || child instanceof BlockHolder) - this.child = child; - else - this.child = new BlockStatement(List.of(child)); - } - - /** - * Get the child of the block statement. - * @return the child statement, often a block. - */ - public final @NotNull StatementNode getChild() { - return child; - } -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/blocks/CallbackStatement.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/blocks/CallbackStatement.java deleted file mode 100644 index cff0ae94..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/blocks/CallbackStatement.java +++ /dev/null @@ -1,108 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes.statements.blocks; - -import fr.jamailun.ultimatespellsystem.dsl.errors.SyntaxException; -import fr.jamailun.ultimatespellsystem.dsl.nodes.StatementNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Type; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.variables.TypesContext; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.variables.VariableDefinition; -import fr.jamailun.ultimatespellsystem.dsl.objects.CallbackEvent; -import fr.jamailun.ultimatespellsystem.dsl.registries.CallbackEventRegistry; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.*; -import fr.jamailun.ultimatespellsystem.dsl.visitor.StatementVisitor; -import lombok.Getter; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.Optional; - -/** - * A statement used to trigger an action happens. - */ -@Getter -public class CallbackStatement extends BlockHolder { - - private final TokenPosition firstPosition; - private final String listenVariableName; - private final CallbackEvent callbackType; - private final @Nullable String outputVariable; - - public CallbackStatement(TokenPosition firstPosition, String listenVariableName, CallbackEvent callbackType, @Nullable String outputVariable, StatementNode child) { - super(child); - this.firstPosition = firstPosition; - this.listenVariableName = listenVariableName; - this.callbackType = callbackType; - this.outputVariable = outputVariable; - } - - @Override - public void validateTypes(@NotNull TypesContext context) { - // variable must exist and be an entity. - VariableDefinition input = context.findVariable(listenVariableName); - if(input == null) - throw new SyntaxException(firstPosition, "Unknown variable name: '" + listenVariableName + "'."); - Type inputType = input.getType(context); - if(!inputType.is(TypePrimitive.ENTITY)) - throw new SyntaxException(firstPosition, "Variable "+listenVariableName+" for a callback must be an entity. Current type is: " + inputType + "'."); - if(inputType.isCollection()) - throw new SyntaxException(firstPosition, "Variable "+listenVariableName+" for a callback must be an entity, not an array."); - - TypesContext childContext = context.childContext(); - // declare variable (if set) - if(outputVariable != null) { - assert callbackType.argument() != null; // compiler helper - childContext.registerVariable(outputVariable, firstPosition, callbackType.argument().type().asType()); - } - - // Validate child - child.validateTypes(childContext); - } - - public Optional getOutputVariable() { - return Optional.ofNullable(outputVariable); - } - - @Override - public void visit(@NotNull StatementVisitor visitor) { - visitor.handleCallback(this); - } - - /** - * Parse a callback statement. - * @param tokens streams of tokens. - * @return a new instance. - */ - @PreviousIndicator(expected = TokenType.CALLBACK) // CALLBACK % [ %]: {CHILD} - public static @NotNull CallbackStatement parseCallback(@NotNull TokenStream tokens) { - TokenPosition pos = tokens.position(); - String varName = tokens.nextOrThrow(TokenType.VALUE_VARIABLE).getContentString(); - - Token eventToken = tokens.next(); - if(eventToken.getType() != TokenType.VALUE_STRING && eventToken.getType() != TokenType.IDENTIFIER) { - throw new SyntaxException(eventToken, "Invalid token for callback type. Expected a string or an identifier. Got " + eventToken + "."); - } - String eventName = eventToken.getContentString(); - CallbackEvent eventType = CallbackEventRegistry.get(eventName); - if(eventType == null) { - throw new SyntaxException(eventToken, "Unregistered callback type: '" + eventName + "'."); - } - - String argVariable; - if(tokens.dropOptional(TokenType.COLON)) { - argVariable = null; - } else { - if(eventType.argument() == null) - throw new SyntaxException(tokens.position(), "Callback type " + eventType.name() + " does ot accept any argument. As such, a ':' was expected."); - if(eventType.argument().keyword() != tokens.peek().getType()) - throw new SyntaxException(tokens.position(), "Callback type " + eventType.name() + " only accept argument with keyword " + eventType.argument().keyword() + ". Got " + tokens.peek() + "."); - tokens.drop(); - argVariable = tokens.nextOrThrow(TokenType.VALUE_VARIABLE).getContentString(); - tokens.dropOrThrow(TokenType.COLON); - } - - StatementNode child = StatementNode.parseNextStatement(tokens); - tokens.dropOptional(TokenType.SEMI_COLON); - - return new CallbackStatement(pos, varName, eventType, argVariable, child); - } -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/blocks/ForLoopStatement.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/blocks/ForLoopStatement.java deleted file mode 100644 index 8b236bce..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/blocks/ForLoopStatement.java +++ /dev/null @@ -1,82 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes.statements.blocks; - -import fr.jamailun.ultimatespellsystem.dsl.nodes.ExpressionNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.StatementNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.CollectionFilter; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.variables.TypesContext; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.PreviousIndicator; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenStream; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenType; -import fr.jamailun.ultimatespellsystem.dsl.visitor.StatementVisitor; -import lombok.Getter; -import lombok.RequiredArgsConstructor; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -/** - * A for loop. - */ -@Getter -@RequiredArgsConstructor -public class ForLoopStatement extends StatementNode { - - private final @Nullable StatementNode initialization; - private final ExpressionNode condition; - private final @Nullable StatementNode iteration; - private final StatementNode child; - - @Override - public void validateTypes(@NotNull TypesContext context) { - TypesContext childContext = context.childContext(); - if(initialization != null) initialization.validateTypes(childContext); - assertExpressionType(condition, CollectionFilter.MONO_ELEMENT, childContext, TypePrimitive.BOOLEAN); - if(iteration != null) iteration.validateTypes(childContext); - child.validateTypes(childContext); - } - - @Override - public void visit(@NotNull StatementVisitor visitor) { - visitor.handleForLoop(this); - } - - /** - * Parse a for-loop statement. - * @param tokens streams of tokens. - * @return a new instance. - */ - @PreviousIndicator(expected = TokenType.FOR) - public static @NotNull ForLoopStatement parseForLoop(@NotNull TokenStream tokens) { - tokens.dropOrThrow(TokenType.BRACKET_OPEN); - - // Optional init - StatementNode init; - if(tokens.peek().getType() == TokenType.SEMI_COLON) { - init = null; - tokens.drop(); - } else { - init = StatementNode.parseNextStatement(tokens); - } - - // Required condition - ExpressionNode condition = ExpressionNode.readNextExpression(tokens); - tokens.dropOrThrow(TokenType.SEMI_COLON); - - // Optional iteration - StatementNode iterator; - if(tokens.dropOptional(TokenType.BRACKET_CLOSE)) { - iterator = null; - } else { - iterator = StatementNode.parseNextStatement(tokens); - tokens.dropOrThrow(TokenType.BRACKET_CLOSE); - } - StatementNode child = StatementNode.parseNextStatement(tokens); - - return new ForLoopStatement(init, condition, iterator, child); - } - - @Override - public String toString() { - return "FOR(" + initialization + "; " + condition + "; " + iteration + "): " + child; - } -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/blocks/ForeachLoopStatement.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/blocks/ForeachLoopStatement.java deleted file mode 100644 index b44bb7a2..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/blocks/ForeachLoopStatement.java +++ /dev/null @@ -1,75 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes.statements.blocks; - -import fr.jamailun.ultimatespellsystem.dsl.errors.TypeException; -import fr.jamailun.ultimatespellsystem.dsl.nodes.ExpressionNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.StatementNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.variables.TypesContext; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.PreviousIndicator; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.Token; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenStream; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenType; -import fr.jamailun.ultimatespellsystem.dsl.visitor.StatementVisitor; -import lombok.Getter; -import lombok.RequiredArgsConstructor; -import org.jetbrains.annotations.NotNull; - -/** - * Foreach iteration over a collection. - */ -@RequiredArgsConstructor -public class ForeachLoopStatement extends StatementNode { - - private final Token varName; - @Getter private final ExpressionNode source; - @Getter private final StatementNode child; - - public String getVariableName() { - return varName.getContentString(); - } - - @Override - public void validateTypes(@NotNull TypesContext context) { - TypesContext childContext = context.childContext(); - - // Source - source.validateTypes(context); - if(!source.getExpressionType().isCollection()) { - throw new TypeException(source, "A FOREACH statement must use a collection for the source."); - } - - // declare variable - childContext.registerVariable(varName.getContentString(), varName.pos(), source.getExpressionType().asMonoElement()); - - // Validate child - child.validateTypes(childContext); - } - - @Override - public void visit(@NotNull StatementVisitor visitor) { - visitor.handleForeachLoop(this); - } - - /** - * Parse a foreach statement. - * @param tokens streams of tokens. - * @return a new instance. - */ - @PreviousIndicator(expected = TokenType.FOREACH) // FOREACH( : ) - public static @NotNull ForeachLoopStatement parseForLoop(@NotNull TokenStream tokens) { - tokens.dropOrThrow(TokenType.BRACKET_OPEN); - - Token varName = tokens.nextOrThrow(TokenType.VALUE_VARIABLE); - tokens.dropOrThrow(TokenType.COLON); - ExpressionNode source = ExpressionNode.readNextExpression(tokens); - - tokens.dropOrThrow(TokenType.BRACKET_CLOSE); - StatementNode child = StatementNode.parseNextStatement(tokens); - - return new ForeachLoopStatement(varName, source, child); - } - - @Override - public String toString() { - return "FOREACH( %" + varName + " IN " + source + "): " + child; - } -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/blocks/IfElseStatement.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/blocks/IfElseStatement.java deleted file mode 100644 index d0b30ad2..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/blocks/IfElseStatement.java +++ /dev/null @@ -1,78 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes.statements.blocks; - -import fr.jamailun.ultimatespellsystem.dsl.nodes.ExpressionNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.StatementNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.CollectionFilter; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.variables.TypesContext; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.PreviousIndicator; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenStream; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenType; -import fr.jamailun.ultimatespellsystem.dsl.visitor.StatementVisitor; -import lombok.Getter; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.Optional; - -/** - * {@code if} statement. Can be linked to a ELSE. - */ -public class IfElseStatement extends BlockHolder { - - @Getter private final ExpressionNode condition; - private final StatementNode optElse; - - public IfElseStatement(@NotNull ExpressionNode condition, @NotNull StatementNode child, @Nullable StatementNode elseStatement) { - super(child); - this.condition = condition; - this.optElse = elseStatement; - } - - @Override - public void validateTypes(@NotNull TypesContext context) { - assertExpressionType(condition, CollectionFilter.MONO_ELEMENT, context, TypePrimitive.BOOLEAN); - child.validateTypes(context.childContext()); - if(optElse != null) - optElse.validateTypes(context); - } - - public Optional getElse() { - return Optional.ofNullable(optElse); - } - - @Override - public void visit(@NotNull StatementVisitor visitor) { - visitor.handleIf(this); - } - - /** - * Parse a new if+else statement. - * @param tokens streams of tokens. - * @return a new instance. - */ - @PreviousIndicator(expected = TokenType.IF) - public static @NotNull IfElseStatement parseIfStatement(@NotNull TokenStream tokens) { - // Condition - tokens.dropOrThrow(TokenType.BRACKET_OPEN); - ExpressionNode condition = ExpressionNode.readNextExpression(tokens); - tokens.dropOrThrow(TokenType.BRACKET_CLOSE); - - // Content - StatementNode child = StatementNode.parseNextStatement(tokens); - - StatementNode elseStatement = null; - if(tokens.dropOptional(TokenType.ELSE)) { - elseStatement = StatementNode.parseNextStatement(tokens); - } - - // Return - return new IfElseStatement(condition, child, elseStatement); - } - - @Override - public String toString() { - return "IF(" + condition +") : " + child - + (optElse==null ? "" : "\n ELSE : " + optElse); - } -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/blocks/RepeatStatement.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/blocks/RepeatStatement.java deleted file mode 100644 index b30cecbf..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/blocks/RepeatStatement.java +++ /dev/null @@ -1,111 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes.statements.blocks; - -import fr.jamailun.ultimatespellsystem.dsl.nodes.ExpressionNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.StatementNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.CollectionFilter; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.variables.TypesContext; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.PreviousIndicator; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenStream; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenType; -import fr.jamailun.ultimatespellsystem.dsl.visitor.StatementVisitor; -import lombok.Getter; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.Optional; - -/** - * Statement of a {@code repeat times}. - */ -public class RepeatStatement extends BlockHolder { - - /** - * Name of the variable set by this statement. - */ - public static final String INDEX_VARIABLE = "_repeat_index"; - - private final @Nullable ExpressionNode delay; // optional - @Getter private @Nullable final ExpressionNode totalCount; // either 'count' or 'totalDuration' - @Getter private @NotNull final ExpressionNode period; - @Getter private @Nullable final ExpressionNode totalDuration; - - public RepeatStatement(@NotNull StatementNode child, @Nullable ExpressionNode delay, @Nullable ExpressionNode totalCount, @NotNull ExpressionNode period, @Nullable ExpressionNode totalDuration) { - super(child); - this.delay = delay; - this.totalCount = totalCount; - this.period = period; - this.totalDuration = totalDuration; - } - - @Override - public void validateTypes(@NotNull TypesContext context) { - TypesContext childContext = context.childContext(); - childContext.promiseVariable(INDEX_VARIABLE, TypePrimitive.NUMBER.asType()); - - if(delay != null) - assertExpressionType(delay, CollectionFilter.MONO_ELEMENT, childContext, TypePrimitive.DURATION); - if(totalCount != null) - assertExpressionType(totalCount, CollectionFilter.MONO_ELEMENT, childContext, TypePrimitive.NUMBER); - assertExpressionType(period, CollectionFilter.MONO_ELEMENT, childContext, TypePrimitive.DURATION); - if(totalDuration != null) - assertExpressionType(totalDuration, CollectionFilter.MONO_ELEMENT, childContext, TypePrimitive.DURATION); - - child.validateTypes(childContext.childContext()); - } - - public Optional getDelay() { - return Optional.ofNullable(delay); - } - - /** - * Parse a "repeat N times" statement. - * @param tokens streams of tokens. - * @return a new instance. - */ - // REPEAT [[AFTER (DURATION)]] (COUNT) TIMES EVERY (FREQ): {} - // REPEAT [[AFTER (DURATION)]] EVERY (FREQ) FOR (DURATION): {} - @PreviousIndicator(expected = {TokenType.REPEAT}) - public static RepeatStatement parseRepeat(TokenStream tokens) { - ExpressionNode delay = null; - if(tokens.dropOptional(TokenType.AFTER)) { - delay = ExpressionNode.readNextExpression(tokens); - } - - ExpressionNode freq; - ExpressionNode count; - ExpressionNode duration; - - // 2nd syntax : EVERY f FOR d - if(tokens.dropOptional(TokenType.EVERY)) { - freq = ExpressionNode.readNextExpression(tokens); - tokens.dropOrThrow(TokenType.FOR); - duration = ExpressionNode.readNextExpression(tokens); - count = null; - } - // 1st syntax : c TIMES EVERY f - else { - count = ExpressionNode.readNextExpression(tokens); - tokens.dropOrThrow(TokenType.TIMES); - tokens.dropOrThrow(TokenType.EVERY); - freq = ExpressionNode.readNextExpression(tokens); - duration = null; - } - - // Always present: child nodes. - tokens.dropOrThrow(TokenType.COLON); - StatementNode child = StatementNode.parseNextStatement(tokens); - tokens.dropOptional(TokenType.SEMI_COLON); - return new RepeatStatement(child, delay, count, freq, duration); - } - - @Override - public void visit(@NotNull StatementVisitor visitor) { - visitor.handleRepeatRun(this); - } - - @Override - public String toString() { - return "RUN{"+(delay==null?"":" AFTER " + period)+" " + totalCount + " times every " + period + "}: " + child; - } -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/blocks/RunLaterStatement.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/blocks/RunLaterStatement.java deleted file mode 100644 index daa14263..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/blocks/RunLaterStatement.java +++ /dev/null @@ -1,61 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes.statements.blocks; - -import fr.jamailun.ultimatespellsystem.dsl.nodes.ExpressionNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.StatementNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.CollectionFilter; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.variables.TypesContext; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.PreviousIndicator; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenStream; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenType; -import fr.jamailun.ultimatespellsystem.dsl.visitor.StatementVisitor; -import org.jetbrains.annotations.NotNull; - -/** - * Run a block of code after a delay. - */ -public class RunLaterStatement extends BlockHolder { - - private final ExpressionNode duration; - - public RunLaterStatement(@NotNull StatementNode child, @NotNull ExpressionNode duration) { - super(child); - this.duration = duration; - } - - @Override - public void validateTypes(@NotNull TypesContext context) { - assertExpressionType(duration, CollectionFilter.MONO_ELEMENT, context, TypePrimitive.DURATION); - child.validateTypes(context.childContext()); - } - - public @NotNull ExpressionNode getDuration() { - return duration; - } - - /** - * Parse a "run later" statement. - * @param tokens streams of tokens. - * @return a new instance. - */ - // RUN AFTER (DURATION): {} - @PreviousIndicator(expected = {TokenType.RUN}) - public static RunLaterStatement parseRunLater(TokenStream tokens) { - tokens.dropOrThrow(TokenType.AFTER); - ExpressionNode duration = ExpressionNode.readNextExpression(tokens); - tokens.dropOrThrow(TokenType.COLON); - StatementNode child = StatementNode.parseNextStatement(tokens); - tokens.dropOptional(TokenType.SEMI_COLON); - return new RunLaterStatement(child, duration); - } - - @Override - public void visit(@NotNull StatementVisitor visitor) { - visitor.handleRunLater(this); - } - - @Override - public String toString() { - return "RUN{AFTER " + duration + "}: " + child; - } -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/blocks/WhileLoopStatement.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/blocks/WhileLoopStatement.java deleted file mode 100644 index fc9a4b56..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/statements/blocks/WhileLoopStatement.java +++ /dev/null @@ -1,79 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes.statements.blocks; - -import fr.jamailun.ultimatespellsystem.dsl.nodes.ExpressionNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.StatementNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.CollectionFilter; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.variables.TypesContext; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.PreviousIndicator; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenStream; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenType; -import fr.jamailun.ultimatespellsystem.dsl.visitor.StatementVisitor; -import lombok.Getter; -import lombok.RequiredArgsConstructor; -import org.jetbrains.annotations.NotNull; - -/** - * Classic while statement. - */ -@RequiredArgsConstructor -public class WhileLoopStatement extends StatementNode { - - private final ExpressionNode nodeCondition; - @Getter private final StatementNode child; - @Getter private final boolean whileFirst; - - @Override - public void validateTypes(@NotNull TypesContext context) { - TypesContext childContext = context.childContext(); - - assertExpressionType(nodeCondition, CollectionFilter.MONO_ELEMENT, childContext, TypePrimitive.BOOLEAN); - child.validateTypes(childContext); - } - - @Override - public void visit(@NotNull StatementVisitor visitor) { - visitor.handleWhileLoop(this); - } - - /** - * Parse a "while-loop" statement. Can be either a while/do or a do/while. - * @param tokens streams of tokens. - * @return a new instance. - */ - // WHILE() - // DO WHILE() - @PreviousIndicator(expected = {TokenType.WHILE, TokenType.DO}) - public static WhileLoopStatement parseWhileLoop(TokenStream tokens, boolean wasWhile) { - ExpressionNode condition = null; - - if(wasWhile) { - tokens.dropOrThrow(TokenType.BRACKET_OPEN); - condition = ExpressionNode.readNextExpression(tokens); - tokens.dropOrThrow(TokenType.BRACKET_CLOSE); - } - - StatementNode child = StatementNode.parseNextStatement(tokens); - - if( ! wasWhile) { - tokens.dropOrThrow(TokenType.WHILE); - tokens.dropOrThrow(TokenType.BRACKET_OPEN); - condition = ExpressionNode.readNextExpression(tokens); - tokens.dropOrThrow(TokenType.BRACKET_CLOSE); - tokens.dropOptional(TokenType.SEMI_COLON); - } - - return new WhileLoopStatement(condition, child, wasWhile); - } - - public ExpressionNode getCondition() { - return nodeCondition; - } - - @Override - public String toString() { - if(whileFirst) - return "WHILE(" + nodeCondition + ") DO " + child; - return "DO " + child + " WHILE(" + nodeCondition + ")"; - } -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/type/CollectionFilter.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/type/CollectionFilter.java deleted file mode 100644 index 3653cb36..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/type/CollectionFilter.java +++ /dev/null @@ -1,38 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes.type; - -import org.jetbrains.annotations.NotNull; - -/** - * Allow to check if a Type is a collection or not. - */ -public enum CollectionFilter { - - /** - * Only accepts mono-elements. - */ - MONO_ELEMENT, - - /** - * Only accept collections. - */ - LIST, - - /** - * Accepts both. - */ - ANY; - - /** - * Test if a type matches the filter. - * @param type the type to test. - * @return true if the type matches the filter. - */ - public boolean isValid(@NotNull Type type) { - return switch (this) { - case MONO_ELEMENT -> ! type.isCollection(); - case LIST -> type.isCollection(); - case ANY -> true; - }; - } - -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/type/Duration.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/type/Duration.java deleted file mode 100644 index 5e99023d..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/type/Duration.java +++ /dev/null @@ -1,136 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes.type; - -import com.google.common.base.Preconditions; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; - -import java.time.temporal.ChronoUnit; -import java.util.Objects; -import java.util.concurrent.TimeUnit; - -/** - * Represents a duration. - * @param amount the quantity of time unit. - * @param timeUnit the unit to use. - */ -public record Duration(double amount, TimeUnit timeUnit) { - - /** - * Convert the duration to a raw seconds-count. - * @return an amount of seconds. - */ - public double toSeconds() { - double factor = switch (timeUnit) { - case NANOSECONDS -> 1E-9; - case MICROSECONDS -> 1E-6; - case MILLISECONDS -> 1E-3; - case SECONDS -> 1; - case MINUTES -> 60; - case HOURS -> 3600; - case DAYS -> 86400; - }; - return amount * factor; - } - - /** - * Adds this duration with another one. - * @param other the other duration. - * @return a new instance of duration. - */ - @Contract("_ -> new") - public @NotNull Duration add(Duration other) { - if(other.timeUnit == timeUnit) - return new Duration(amount + other.amount, timeUnit); - return new Duration(toSeconds() + other.toSeconds(), TimeUnit.SECONDS); - } - - /** - * Subtracts this duration with another one. - * @param other the other duration. - * @return a new instance of duration. - */ - @Contract("_ -> new") - public @NotNull Duration sub(@NotNull Duration other) { - return new Duration(Math.max(0, toSeconds() - other.toSeconds()), TimeUnit.SECONDS); - } - - /** - * Multiply this duration by a lambda - * @param lambda numerical value. - * @return a new duration. - */ - @Contract("_ -> new") - public @NotNull Duration mul(double lambda) { - return new Duration(toSeconds() * lambda, TimeUnit.SECONDS); - } - - /** - * Divide this duration by a lambda - * @param lambda numerical value. Cannot be 0. - * @return a new duration. - */ - @Contract("_ -> new") - public @NotNull Duration div(double lambda) { - Preconditions.checkState(lambda != 0, "Cannot divide by 0."); - return new Duration(toSeconds() / lambda, TimeUnit.SECONDS); - } - - /** - * Divide the duration by another one. Produces a number. - * @param duration duration to divide this instance with. - * @return output value of the duration. - */ - public double div(@NotNull Duration duration) { - return toSeconds() / duration.toSeconds(); - } - - - /** - * Convert the duration to a raw milliseconds-count. - * @return an amount of milliseconds. - */ - public long toMs() { - return (long) (toSeconds() * 1000); - } - - /** - * Convert the duration to a raw ticks-count. - * @return an amount of ticks. - */ - public long toTicks() { - return (long) (toSeconds() * 20); - } - - /** - * For debug purposes, get the unit as a nice string. - * @return a non-null string. - */ - @Contract(pure = true) - public @NotNull String niceUnit() { - String s = amount > 1 ? "s" : ""; - return switch (timeUnit) { - case NANOSECONDS -> "nanosecond" + s; - case MICROSECONDS -> "microsecond" + s; - case MILLISECONDS -> "millisecond" + s; - case SECONDS -> "second" + s; - case MINUTES -> "minute" + s; - case HOURS -> "hour" + s; - case DAYS -> "day" + s; - }; - } - - @Override - public boolean equals(Object o) { - if (o == null || getClass() != o.getClass()) return false; - return toSeconds() == ((Duration)o).toSeconds(); - } - - @Override - public int hashCode() { - return Objects.hash(toSeconds()); - } - - public @NotNull java.time.Duration asJavaDuration() { - return java.time.Duration.of(toMs(), ChronoUnit.MILLIS); - } -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/type/SpellEntity.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/type/SpellEntity.java deleted file mode 100644 index 9dbb552d..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/type/SpellEntity.java +++ /dev/null @@ -1,79 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes.type; - -import net.kyori.adventure.text.Component; -import org.bukkit.Location; -import org.bukkit.entity.Entity; -import org.bukkit.potion.PotionEffect; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; - -import java.util.Optional; -import java.util.UUID; - -/** - * An entity-representation inside a spell. - */ -public interface SpellEntity { - - /** - * The Bukkit unique ID of the entity. - * @return a non-null value. - */ - @NotNull UUID getUniqueId(); - - /** - * Get the bukkit entity. - * @return a non-null optional. - */ - @Contract(pure = true) - @NotNull Optional getBukkitEntity(); - - /** - * Test is the entity exist within Bukkit. - * @return true if it's a Bukkit entity. - */ - default boolean isBukkit() { - return getBukkitEntity().isPresent(); - } - - /** - * Get the location of the entity. - * @return a non-null location. - */ - @NotNull Location getLocation(); - - /** - * Get the eye-location of the entity. - * @return a non-null location. - */ - @NotNull Location getEyeLocation(); - - /** - * Teleport the entity to another location. - * @param location the non-null location to use. - */ - void teleport(@NotNull Location location); - - /** - * Send a message. - * @param component the message to send. - */ - void sendMessage(@NotNull Component component); - - /** - * Remove the entity from the world. - */ - void remove(); - - /** - * Test ig the entity is valid, i.e. still exists and alive. - * @return true if the entity is alive and well. - */ - boolean isValid(); - - /** - * Add a potion effect. - * @param effect the effect to add. - */ - void addPotionEffect(@NotNull PotionEffect effect); -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/type/Type.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/type/Type.java deleted file mode 100644 index 8f56fff3..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/type/Type.java +++ /dev/null @@ -1,45 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes.type; - -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; - -/** - * Represents the type of an expression. - * @param primitive the kind of type. - * @param isCollection if true, this is a collection of primitives. - */ -public record Type(@NotNull TypePrimitive primitive, boolean isCollection) { - - /** - * Check if this type is of a primitive. - * @param primitive the primitive to compare this type with. - * @return true if the primitives are equals. - */ - public boolean is(TypePrimitive primitive) { - return this.primitive == primitive; - } - - @Contract(pure = true) - @Override - public @NotNull String toString() { - return primitive + (isCollection?"[]":""); - } - - /** - * Get this type as a non-list. - * @return a new instance of a type. - */ - @Contract(" -> new") - public @NotNull Type asMonoElement() { - return new Type(primitive, false); - } - - /** - * Get this type as a list. - * @return a new instance of a type. - */ - @Contract(" -> new") - public @NotNull Type asCollection() { - return new Type(primitive, true); - } -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/type/TypePrimitive.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/type/TypePrimitive.java deleted file mode 100644 index 45cf2437..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/type/TypePrimitive.java +++ /dev/null @@ -1,87 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes.type; - -import org.bukkit.Location; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -/** - * Enumeration of a possible types. - */ -public enum TypePrimitive { - - // Real Primitives - /** A String primitive. */ - STRING(String.class), - /** A number primitive. */ - NUMBER(Number.class), - /** A boolean primitive. */ - BOOLEAN(Boolean.class), - - // In-game - /** A temporal duration. */ - DURATION(Duration.class), - /** An in-game entity. */ - ENTITY(SpellEntity.class), - /** A Bukkit entity-type. */ - ENTITY_TYPE(String.class), - /** A Bukkit location. */ - LOCATION(Location.class), - - // Specials - /** A map of properties. */ - PROPERTIES_SET, - /** A string for custom values. */ - CUSTOM(String.class), - /** A {@code null} value. */ - NULL; - - public final Class clazz; - - TypePrimitive() { - this(null); - } - TypePrimitive(Class clazz) { - this.clazz = clazz; - } - - /** - * Convert this enumeration element into a new Type instance. - * @return a new, non-null Type instance. - */ - public @NotNull Type asType() { - return new Type(this, false); - } - - /** - * Convert this enumeration element into a new Type instance, possibly a collection. - * @param collection if true, the returned Type will be a collection. - * @return a new, non-null Type instance. - */ - @Contract("_ -> new") - public @NotNull Type asType(boolean collection) { - return new Type(this, collection); - } - - /** - * Parse a string to find the corresponding primitive. - * @param value the name of the primitive. - * @return null if no match. - */ - public static @Nullable TypePrimitive parsePrimitive(@NotNull String value) { - return switch (value.toLowerCase()) { - case "string" -> STRING; - case "number", "double", "float", "integer", "int", "short", "byte" -> NUMBER; - case "boolean", "bool" -> BOOLEAN; - case "duration", "time", "chrono" -> DURATION; - case "entity", "living_entity", "living-entity", "living" -> ENTITY; - case "entity_type" -> ENTITY_TYPE; - case "null" -> NULL; - case "loc", "location", "position", "pos" -> LOCATION; - case "map", "data", "properties", "properties-set", "properties_set" -> PROPERTIES_SET; - case "custom", "?", "any" -> CUSTOM; - default -> null; - }; - } - -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/type/variables/TypesContext.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/type/variables/TypesContext.java deleted file mode 100644 index eb5a80b2..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/type/variables/TypesContext.java +++ /dev/null @@ -1,89 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes.type.variables; - -import fr.jamailun.ultimatespellsystem.dsl.errors.SyntaxException; -import fr.jamailun.ultimatespellsystem.dsl.nodes.ExpressionNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Type; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenPosition; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.HashMap; -import java.util.Map; - -/** - * A context for type validation. - */ -public class TypesContext { - - private final Map vars = new HashMap<>(); - - /** - * Create a new context, and register the {@code %caster} variable. - */ - public TypesContext() { - promiseVariable("caster", TypePrimitive.ENTITY.asType()); - } - - /** - * Register a new variable. - * @param varName the name of the variable. - * @param variable the expression defining the variable. - */ - public void registerVariable(@NotNull String varName, @NotNull ExpressionNode variable) { - if("caster".equals(varName)) { - throw new SyntaxException(variable.firstTokenPosition(), "Cannot override variable '%" + varName + "'."); - } - - vars.putIfAbsent(varName, new VariableDefinition(varName)); - vars.get(varName).register(new VariableReference.Dynamic(variable)); - vars.get(varName).getType(this); - } - - /** - * Guarantee a variable will be set by a runtime implementation. - * @param name the name of the variable. - * @param type the type of the variable. - */ - public void promiseVariable(@NotNull String name, @NotNull Type type) { - vars.putIfAbsent(name, new VariableDefinition(name)); - vars.get(name).register(new VariableReference.Constant(type, TokenPosition.unknown())); - } - - /** - * Register a variable, with an already guaranteed type. - * @param varName the variable name. - * @param position the position of the declaration. - * @param type the type of variable. - */ - public void registerVariable(@NotNull String varName, @NotNull TokenPosition position, @NotNull Type type) { - if("caster".equals(varName)) { - throw new SyntaxException(position, "Cannot override variable '%" + varName + "'."); - } - - vars.putIfAbsent(varName, new VariableDefinition(varName)); - vars.get(varName).register(new VariableReference.Constant(type, position)); - } - - /** - * Lookup for a specific variable. - * @param varName the name of the variable to look for. - * @return {@code null} if nothing was found. - */ - public @Nullable VariableDefinition findVariable(@NotNull String varName) { - return vars.get(varName); - } - - /** - * Create a new context. This allows sub-scopes to be independents. - * @return a new instance of context, copying the current variables. - */ - @Contract(" -> new") - public @NotNull TypesContext childContext() { - TypesContext child = new TypesContext(); - child.vars.putAll(vars); - return child; - } - -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/type/variables/VariableDefinition.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/type/variables/VariableDefinition.java deleted file mode 100644 index 3412f072..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/type/variables/VariableDefinition.java +++ /dev/null @@ -1,59 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes.type.variables; - -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Type; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; -import lombok.RequiredArgsConstructor; -import org.jetbrains.annotations.NotNull; - -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - -/** - * Definition of a variable. Internal representation. - */ -@RequiredArgsConstructor -public class VariableDefinition { - - private final List references = new ArrayList<>(); - private final String name; - - private transient Type computedType; - - /** - * Register a reference to this definition. - * @param reference non-null reference. - */ - public void register(@NotNull VariableReference reference) { - references.add(reference); - computedType = null; - } - - /** - * Get the representation type of this variable. - * @param context current context. - * @return a {@link TypePrimitive#NULL} type if unset. - */ - public @NotNull Type getType(@NotNull TypesContext context) { - if(computedType != null) return computedType; - - // We need ot compute the type - for(VariableReference reference : references) { - Type type = reference.getType(context); - if(type.is(TypePrimitive.NULL) && !type.isCollection()) { - // Nothing here - continue; - } - if(computedType == null || computedType.is(TypePrimitive.NULL)) { - computedType = type; - // We CAN overload a variable that as NULL. - } else if(!computedType.is(TypePrimitive.NULL) && ! computedType.equals(type)) { - throw reference.exception("Cannot change type of an already defined variable (%"+name+"). Previous type: " + computedType + ", new type: " + type + "."); - } - } - - // If type not set, then it's a NULL. - return Objects.requireNonNullElseGet(computedType, TypePrimitive.NULL::asType); - } - -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/type/variables/VariableReference.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/type/variables/VariableReference.java deleted file mode 100644 index fa417be1..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/nodes/type/variables/VariableReference.java +++ /dev/null @@ -1,78 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes.type.variables; - -import fr.jamailun.ultimatespellsystem.dsl.errors.TypeException; -import fr.jamailun.ultimatespellsystem.dsl.nodes.ExpressionNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Type; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenPosition; -import lombok.Getter; -import lombok.RequiredArgsConstructor; -import org.jetbrains.annotations.NotNull; - -/** - * A reference to a variable.
- * Used internally to have a pseudo-type inference for variables. - */ -public abstract class VariableReference { - - /** - * Get the type of the variable. - * @param context current context. - * @return a non-null type. NULL if unset. - */ - public abstract @NotNull Type getType(@NotNull TypesContext context); - - /** - * Create a new specific exception. - * @param message exception message. - * @return a new instance of an exception. - */ - abstract @NotNull TypeException exception(@NotNull String message); - - /** - * Constant variable value. - */ - @Getter - @RequiredArgsConstructor - public static class Constant extends VariableReference { - private final Type type; - private final TokenPosition position; - @Override - public @NotNull Type getType(@NotNull TypesContext context) { - return type; - } - @Override - @NotNull TypeException exception(@NotNull String message) { - return new TypeException(position, message); - } - @Override - public String toString() { - return "type(" + type + ")"; - } - } - - /** - * Dynamic reference. - */ - @RequiredArgsConstructor - public static class Dynamic extends VariableReference { - private final ExpressionNode node; - private boolean computed = false; - @Override - public @NotNull Type getType(@NotNull TypesContext context) { - if(!computed) { - computed = true; - node.validateTypes(context); - } - return node.getExpressionType(); - } - @Override - @NotNull TypeException exception(@NotNull String message) { - return new TypeException(node, message); - } - @Override - public String toString() { - return "type_ref(" + (computed ? node.getExpressionType() : "->"+node) + ")"; - } - } - -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/objects/CallbackEvent.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/objects/CallbackEvent.java deleted file mode 100644 index c8e976da..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/objects/CallbackEvent.java +++ /dev/null @@ -1,58 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.objects; - -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenType; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -/** - * A type of callback event. - * @param name the non-null name, used in the DSL. Must not contain any space. - * @param argument optional argument value, able to be read in the callback scope. - */ -public record CallbackEvent(@NotNull String name, @Nullable CallbackArgument argument) { - - public CallbackEvent { - if(name.indexOf(' ') > -1) { - throw new RuntimeException("Invalid callback name. Cannot contain spaces."); - } - } - - /** - * Create a new callback event from arguments. - * @param name the non-null name of the callback. Must not contain any space. - * @param keyword the keyword to use for the argument. - * @param type the argument type of the argument. - * @return a new instance of a callback. - */ - @Contract("_,_,_ -> new") - public static @NotNull CallbackEvent of(@NotNull String name, @NotNull TokenType keyword, @NotNull TypePrimitive type) { - return new CallbackEvent(name, new CallbackArgument(keyword, type)); - } - - /** - * Create a new callback event without argument. - * @param name the non-null name of the callback. Must not contain any space. - * @return a new instance of a callback. - */ - @Contract("_ -> new") - public static @NotNull CallbackEvent of(@NotNull String name) { - return new CallbackEvent(name, null); - } - - /** - * An argument, able to be read in the callback scope. - * @param keyword keyword used by the argument. - * @param type type of the argument. - */ - public record CallbackArgument(@NotNull TokenType keyword, @NotNull TypePrimitive type) { - public CallbackArgument { - if(!keyword.letters) - throw new RuntimeException("Invalid keyword type. Should be a 'letters' keyword."); - if(type == TypePrimitive.NULL) - throw new RuntimeException("Invalid callback argument type. Cannot be null."); - } - } - -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/registries/CallbackEventRegistry.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/registries/CallbackEventRegistry.java deleted file mode 100644 index 874ce84d..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/registries/CallbackEventRegistry.java +++ /dev/null @@ -1,58 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.registries; - -import fr.jamailun.ultimatespellsystem.dsl.objects.CallbackEvent; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.*; - -/** - * Register new callback handling. - * @see #register(CallbackEvent) - */ -public final class CallbackEventRegistry { - private CallbackEventRegistry() {} - - private static final Map CALLBACKS = new HashMap<>(); - - /** - * Register a callback. - * @param callback a valid callback. - */ - public static void register(@NotNull CallbackEvent callback) { - CALLBACKS.put(prepare(callback.name()), callback); - } - - /** - * Find a callback. - * @param callbackName name of the callback. - * @return null if callback name does not exist. - */ - public static @Nullable CallbackEvent get(@NotNull String callbackName) { - return CALLBACKS.get(prepare(callbackName)); - } - - /** - * Test if a callback has been registered. - * @param callbackName the callback name to test. - * @return true if callback exists. - */ - public static boolean exists(@NotNull String callbackName) { - return CALLBACKS.containsKey(prepare(callbackName)); - } - - /** - * Remove a callback name. - * @param callbackName callback name to remove. - */ - public static void unregister(@NotNull String callbackName) { - CALLBACKS.remove(prepare(callbackName)); - } - - @Contract(pure = true) - private static @NotNull String prepare(@NotNull String input) { - return input.toLowerCase(); - } - -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/registries/EntityTypeRegistry.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/registries/EntityTypeRegistry.java deleted file mode 100644 index 262e89b5..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/registries/EntityTypeRegistry.java +++ /dev/null @@ -1,65 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.registries; - -import org.bukkit.entity.EntityType; -import org.jetbrains.annotations.NotNull; - -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; - -/** - * You may need to allow specific tokens as "EntityType". - * @see #allow(String) - */ -public final class EntityTypeRegistry { - private EntityTypeRegistry() {} - - private static final Set ALLOWED = new HashSet<>(); - - /** - * Allow a string to be allowed. - * @param entityType an Entity-Type string. - */ - public static void allow(@NotNull String entityType) { - ALLOWED.add(prepare(entityType)); - } - - /** - * Test if a string as been allowed. - * @param entityType the entity-type to test. - * @return true if the entity-type exists. - */ - public static boolean isAllowed(@NotNull String entityType) { - return ALLOWED.contains(prepare(entityType)); - } - - /** - * Disallow an entity type. - * @param entityType the type to disable. - */ - public static void disallow(@NotNull String entityType) { - ALLOWED.remove(prepare(entityType)); - } - - /** - * Prepare a string for a "clean" representation. - * @param string non-null string. - * @return a cleaned string. - */ - public static @NotNull String prepare(@NotNull String string) { - return string.toLowerCase().replace(' ', '_'); - } - - private static final Set FORBIDDEN = Set.of( - EntityType.PLAYER, EntityType.AREA_EFFECT_CLOUD, EntityType.MARKER, EntityType.LEASH_KNOT, EntityType.PAINTING, - EntityType.ITEM, EntityType.ITEM_FRAME, EntityType.ITEM_DISPLAY, EntityType.GLOW_ITEM_FRAME, EntityType.OMINOUS_ITEM_SPAWNER, - EntityType.FISHING_BOBBER, EntityType.TEXT_DISPLAY, EntityType.INTERACTION, EntityType.BLOCK_DISPLAY, EntityType.FIREWORK_ROCKET - ); - - static { - Arrays.stream(EntityType.values()) - .filter(e -> ! FORBIDDEN.contains(e)) - .forEach(e -> allow(e.name())); - } - -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/registries/FunctionDefinitionsRegistry.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/registries/FunctionDefinitionsRegistry.java deleted file mode 100644 index 0b969e0d..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/registries/FunctionDefinitionsRegistry.java +++ /dev/null @@ -1,55 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.registries; - -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.FunctionDefinition; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.HashMap; -import java.util.Map; - -/** - * A registry for {@link FunctionDefinition}. - */ -public final class FunctionDefinitionsRegistry { - private FunctionDefinitionsRegistry() {} - - private final static Map REGISTRY = new HashMap<>(); - - /** - * Register a new function definition. - * @param functionDefinition the non-null function definition to register - */ - public static void register(@NotNull FunctionDefinition functionDefinition) { - REGISTRY.put(functionDefinition.id(), functionDefinition); - } - - /** - * Register a new function definition, with a specific ID. - * @param key key to register. - * @param functionDefinition the non-null function definition to register - */ - public static void register(@NotNull String key, @NotNull FunctionDefinition functionDefinition) { - REGISTRY.put(key, functionDefinition); - } - - /** - * Test if a function exist. - * @param functionId the function ID to test. - * @return true if a function with this ID has already been registered. - * @see FunctionDefinition#id() - */ - public static boolean exists(@NotNull String functionId) { - return REGISTRY.containsKey(functionId); - } - - /** - * Find a function definition. - * @param functionId the function ID to use. - * @return {@code null} if no function with this ID has been registered. - * @see FunctionDefinition#id() - */ - public static @Nullable FunctionDefinition find(@NotNull String functionId) { - return REGISTRY.get(functionId); - } - -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/registries/RegistryException.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/registries/RegistryException.java deleted file mode 100644 index 03dd44e0..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/registries/RegistryException.java +++ /dev/null @@ -1,21 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.registries; - -import fr.jamailun.ultimatespellsystem.dsl.errors.UssException; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenPosition; -import org.jetbrains.annotations.NotNull; - -/** - * An exception triggered when a specific label has not been registered. - */ -public class RegistryException extends UssException { - - /** - * New instance about an unknown label. - * @param position token position - * @param label label cause of the exception. - */ - public RegistryException(@NotNull TokenPosition position, @NotNull String label) { - super(position, "Unknown label '" + label + "'. Did you properly register the provider ?"); - } - -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/tokenization/CharStream.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/tokenization/CharStream.java deleted file mode 100644 index 5259d0c4..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/tokenization/CharStream.java +++ /dev/null @@ -1,112 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.tokenization; - -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; - -import java.io.*; -import java.util.StringJoiner; - -/** - * A stream of {@link Character}. - */ -public class CharStream { - - private final char[] chars; - private int index = 0; - private final PositionProvider position = new PositionProvider(); - - public CharStream(char[] chars) { - this.chars = chars; - } - - /** - * Create a new character stream from a string. - * @param string the string to use. - * @return a new CharStream. - */ - @Contract("_ -> new") - public static @NotNull CharStream from(@NotNull String string) { - return new CharStream((string + "\n").toCharArray()); - } - - /** - * Create a new character stream from a file. - * @param file the file to use. - * @return a new CharStream. - */ - @Contract("_ -> new") - public static @NotNull CharStream from(@NotNull File file) { - if(!file.exists()) - throw new RuntimeException("File " + file + " does not exist."); - try(BufferedReader reader = new BufferedReader(new FileReader(file))) { - StringJoiner sj = new StringJoiner("\n"); - String line; - while ((line = reader.readLine()) != null) { - sj.add(line); - } - sj.add("\n"); - String fileContent = sj.toString(); - return from(fileContent); - } catch(IOException e) { - throw new RuntimeException("Cannot read file "+ file, e); - } - } - - /** - * Peek the next character. - * @return the character on current index. - */ - public char peek() { - return chars[index]; - } - - /** - * Get the current character, and move the index. - * @return the character on current index. - */ - public char next() { - char c = chars[index ++]; - position.column++; - if(c == '\n') { - position.column = 1; - position.line++; - } - return c; - } - - /** - * Drop the current character, by simply moving the index. - */ - public void drop() { - if(!hasMore()) - throw new RuntimeException("No more data."); - index++; - } - - /** - * Test if more character are remaining. - * @return {@code true} if more characters are remaining. - */ - public boolean hasMore() { - return index < chars.length - 1; - } - - private static class PositionProvider { - int column = 1; - int line = 1; - - @Contract(" -> new") - public @NotNull TokenPosition pos() { - return new TokenPosition(line, column); - } - } - - /** - * Get the current position of the token. - * @return the current position. - */ - public @NotNull TokenPosition pos() { - return position.pos(); - } - -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/tokenization/PreviousIndicator.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/tokenization/PreviousIndicator.java deleted file mode 100644 index cd12d26a..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/tokenization/PreviousIndicator.java +++ /dev/null @@ -1,23 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.tokenization; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * This is declarative-only. No check will be done. - *
- * Used to indicate to the developer what cas the expected previous token type. - */ -@Target(ElementType.METHOD) -@Retention(RetentionPolicy.SOURCE) -public @interface PreviousIndicator { - - /** - * Previous token. - * @return token types. - */ - TokenType[] expected(); - -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/tokenization/Token.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/tokenization/Token.java deleted file mode 100644 index 1291dc9c..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/tokenization/Token.java +++ /dev/null @@ -1,156 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.tokenization; - -import com.google.common.base.Preconditions; -import lombok.Getter; -import org.jetbrains.annotations.NotNull; - -import java.util.concurrent.TimeUnit; - -/** - * Internal representation of a token. - */ -public class Token { - - @Getter private final TokenType type; - private final TokenPosition position; - - private Double contentNumber; - private String contentString; - private TimeUnit contentTimeUnit; - - /** - * New token. - * @param type type of the token. - * @param position position. - */ - public Token(@NotNull TokenType type, @NotNull TokenPosition position) { - this.type = type; - this.position = position; - } - - /** - * New token from a raw string value. - * @param string textual content. - * @param position token position. - * @return a new instance. - */ - public static @NotNull Token fromString(@NotNull String string, @NotNull TokenPosition position) { - Token token = new Token(TokenType.VALUE_STRING, position); - token.contentString = string; - return token; - } - - /** - * New token from a variable value. - * @param string textual content. - * @param position token position. - * @return a new instance. - */ - public static @NotNull Token fromVariable(@NotNull String string, @NotNull TokenPosition position) { - Token token = new Token(TokenType.VALUE_VARIABLE, position); - token.contentString = string; - return token; - } - - /** - * New token from a raw identifier. - * @param string textual content. - * @param position token position. - * @return a new instance. - */ - public static @NotNull Token fromWord(@NotNull String string, @NotNull TokenPosition position) { - Token token = new Token(TokenType.IDENTIFIER, position); - token.contentString = string; - return token; - } - - /** - * New token from a raw numerical value. - * @param number numerical content. - * @param position token position. - * @return a new instance. - */ - public static @NotNull Token fromNumber(double number, @NotNull TokenPosition position) { - Token token = new Token(TokenType.VALUE_NUMBER, position); - token.contentNumber = number; - return token; - } - - /** - * New token from a raw duration value. - * @param number numerical value. - * @param tu time-unit value. - * @param position token position. - * @return a new instance. - */ - public static @NotNull Token fromDuration(double number, @NotNull TimeUnit tu, @NotNull TokenPosition position) { - Token token = new Token(TokenType.VALUE_DURATION, position); - token.contentNumber = number; - token.contentTimeUnit = tu; - return token; - } - - /** - * Get the boolean content, if it exists. - * @return a boolean value. - */ - public boolean getContentBoolean() { - return switch (type) { - case TRUE -> true; - case FALSE -> false; - default -> throw new RuntimeException("Cannot get the BOOL content of type " + type); - }; - } - - /** - * Get the numerical content, if it exists. - * @return a numerical value. - */ - public @NotNull Double getContentNumber() { - Preconditions.checkState(type == TokenType.VALUE_NUMBER || type == TokenType.VALUE_DURATION, "Cannot get the TIME_UNIT content of type " + type); - return contentNumber; - } - - /** - * Get the time-unit content, if it exists. - * @return a time-unit value. - */ - public @NotNull TimeUnit getContentTimeUnit() { - Preconditions.checkState(type == TokenType.VALUE_DURATION, "Cannot get the TIME_UNIT content of type " + type); - return contentTimeUnit; - } - - /** - * Get the textual content, if it exists. - * @return a textual value. - */ - public @NotNull String getContentString() { - Preconditions.checkState(type == TokenType.VALUE_STRING || type == TokenType.VALUE_VARIABLE || type == TokenType.IDENTIFIER, "Cannot get the STRING content of type " + type); - return contentString; - } - - /** - * Get the token position. - * @return a non-null position instance. - */ - public @NotNull TokenPosition pos() { - return position; - } - - @Override - public String toString() { - if(type == TokenType.IDENTIFIER) { - return "[" + contentString + "]"; - } - if(type == TokenType.VALUE_DURATION) { - return type + "(" + contentNumber + " " + contentTimeUnit + ")"; - } - if(type == TokenType.VALUE_VARIABLE || type == TokenType.VALUE_STRING) { - return type + "(\"" + contentString + "\")"; - } - if(type == TokenType.VALUE_NUMBER) { - return type + "(" + contentNumber + ")"; - } - return type.name(); - } -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/tokenization/TokenPosition.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/tokenization/TokenPosition.java deleted file mode 100644 index ad5b2615..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/tokenization/TokenPosition.java +++ /dev/null @@ -1,26 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.tokenization; - -import org.jetbrains.annotations.NotNull; - -/** - * Position in a source file / string. - * @param line the line of the element. - * @param col the column of the element. - */ -public record TokenPosition(int line, int col) { - @Override - public @NotNull String toString() { - if(line == -1 && col == -1) - return "(?:?)"; - return "("+line+":"+col+")"; - } - - private static final TokenPosition UNKNOWN = new TokenPosition(-1, -1); - /** - * Unknown position. - * @return an unknown position. - */ - public static @NotNull TokenPosition unknown() { - return UNKNOWN; - } -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/tokenization/TokenStream.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/tokenization/TokenStream.java deleted file mode 100644 index beb1e28d..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/tokenization/TokenStream.java +++ /dev/null @@ -1,126 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.tokenization; - -import com.google.common.base.Preconditions; -import fr.jamailun.ultimatespellsystem.dsl.errors.SyntaxException; -import org.jetbrains.annotations.NotNull; - -import java.util.List; -import java.util.StringJoiner; - -/** - * A stream of {@link Token}. - */ -public class TokenStream { - - private final List tokens; - private int index = 0; - - /** - * Create a new instance from a tokens list. - * @param tokens a non-null list of tokens. - */ - public TokenStream(@NotNull List tokens) { - this.tokens = tokens; - } - - /** - * Read the next character, don't move cursor. - * @return a non-null token. - * @throws IllegalStateException if no more data exist. - */ - public @NotNull Token peek() { - Preconditions.checkState(hasMore(), "No more data."); - return tokens.get(index); - } - - /** - * Read the next character, then move cursor to the next token. - * @return a non-null token. - * @throws IllegalStateException if no more data exist. - */ - public @NotNull Token next() { - Preconditions.checkState(hasMore(), "No more data."); - return tokens.get(index ++); - } - - /** - * Assert the next token is of a specific type, or throw. - * @param type expected type. - * @return a non-null token. - * @throws IllegalStateException if no more data exist. - * @throws SyntaxException if the next token does not match what was expected. - */ - public @NotNull Token nextOrThrow(@NotNull TokenType type) { - Token next = next(); - if(next.getType() != type) - throw new SyntaxException(next, type); - return next; - } - - /** - * Drop the current token, move the cursor. - * @throws IllegalStateException if no more data exist. - */ - public void drop() { - Preconditions.checkState(hasMore(), "No more data."); - index++; - } - - /** - * Assert the current token is of a specific type, then drop it. - * @param expectedType expected type for the current token. - * @throws IllegalStateException if no more data exist. - * @throws SyntaxException if the next token does not match what was expected. - */ - public void dropOrThrow(@NotNull TokenType expectedType) { - Token next = next(); - if(next.getType() != expectedType) - throw new SyntaxException(next, expectedType); - } - /** - * Assert the current token is of a specific type, then drop it if it matches - * @param types expected types for the current token. - * @return true if the next token does match what was expected. Or if no more data exists. - */ - public boolean dropOptional(@NotNull TokenType... types) { - if(hasMore() && List.of(types).contains(peek().getType())) { - drop(); - return true; - } - return false; - } - - /** - * Make the cursor go back. - * @throws IllegalStateException if the cursor is not at the beginning. - */ - public void back() { - Preconditions.checkState(index > 0, "Index is at start, cannot go back."); - index--; - } - - /** - * Test if more data exists. - * @return true if more data can be read. - */ - public boolean hasMore() { - return index < tokens.size(); - } - - @Override - public @NotNull String toString() { - StringJoiner sj = new StringJoiner(", "); - for(int i = index; i < tokens.size(); i++) - sj.add(tokens.get(i).toString()); - return "TokenStream{index="+index+", TOKENS = [" + sj + "] }"; - } - - /** - * Get the current token position. - * @return the current position. - * @throws IllegalStateException if no more data can be read. - */ - public @NotNull TokenPosition position() { - return peek().pos(); - } -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/tokenization/TokenType.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/tokenization/TokenType.java deleted file mode 100644 index a55f7d1c..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/tokenization/TokenType.java +++ /dev/null @@ -1,132 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.tokenization; - -/** - * Type of token. - */ -public enum TokenType { - - // == MONO-CHAR OPERATORS - - // BiOperators - OPE_ADD, // + - OPE_SUB, // - - OPE_MUL, // * - OPE_DIV, // / - - // MonoOperators - OPE_NOT, // ! - - // Others - ANTISLASH, // \ - COLON, // : - SEMI_COLON, // ; - COMMA, // , - DOT, // . - EQUAL, // = - BRACKET_OPEN, // ( - BRACKET_CLOSE, // ) - SQUARE_BRACKET_OPEN, // [ - SQUARE_BRACKET_CLOSE, // ] - BRACES_OPEN, // { - BRACES_CLOSE, // } - COMP_LT, // < - COMP_GT, // > - PROPERTY_OPEN, // {{ - PROPERTY_CLOSE, // }} - ARRAY_OPEN, // [[ - ARRAY_CLOSE, // ]] - CHAR_AT, // @ - - // == BI-CHAR OPERATORS - - COMP_LE, // <= - COMP_GE, // >= - COMP_EQ, // == - COMP_NE, // != - OPE_AND, // '&&' - OPE_OR, // '||' - - LIST_ADD, // :+ - LIST_REM, // :- - LIST_REM_INDEX, // :/ - LIST_CONTAINS, // :? - - // == KEYWORDS - - STOP(true), - IF(true), - ELSE(true), - FOR(true), - WHILE(true), - DO(true), - BREAK(true), - CONTINUE(true), - - DEFINE(true), - SEND(true), - TO(true), - ALL(true), - INCLUDING(true), - AROUND(true), - WITHIN(true), - RUN(true), - AFTER(true), - TIMES(true), - REPEAT(true), - EVERY(true), - SUMMON(true), - AT(true), - BY(true), - AS(true), - WITH(true), - POSITION(true), - OF(true), - TELEPORT(true), - FOREACH(true), - PLAY(true), - SIZEOF(true), - GIVE(true), - CALLBACK(true), - - INCREMENT(true), - DECREMENT(true), - - // == RAW VALUES - TRUE(true), - FALSE(true), - NULL(true), - - // == N-CHARS OPERATORS - - IDENTIFIER, // any combination of character that is NOT a string - VALUE_VARIABLE, // a WORD starting with a '%' - VALUE_STRING, // combination of characters between quotes - VALUE_NUMBER, - VALUE_DURATION, // number+ [s/ms/m/h/seconds] - - // == END OF FILE - EOF; - - public final boolean letters; - - TokenType() { - this(false); - } - TokenType(boolean letters) { - this.letters = letters; - } - - public Token toToken(TokenPosition position) { - return new Token(this, position); - } - - public boolean isRawValue() { - return this == IDENTIFIER || - this == VALUE_STRING || - this == VALUE_NUMBER || - this == VALUE_DURATION || - this == TRUE || - this == FALSE; - } - -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/tokenization/Tokenizer.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/tokenization/Tokenizer.java deleted file mode 100644 index f17b9383..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/tokenization/Tokenizer.java +++ /dev/null @@ -1,293 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.tokenization; - -import fr.jamailun.ultimatespellsystem.dsl.errors.ParsingException; -import org.jetbrains.annotations.NotNull; - -import java.util.*; -import java.util.concurrent.TimeUnit; -import java.util.function.Predicate; -import java.util.regex.Pattern; - -/** - * Internal tokenizer. Transforms a string into a list of {@link Token tokens}. - */ -public class Tokenizer { - - private final static Map OPERATORS_MONO = new HashMap<>(); - private final static Map OPERATORS_BI = new HashMap<>(); - private final static Map KEYWORDS = new HashMap<>(); - private final static Map TIME_UNITS = new HashMap<>(); - static { - OPERATORS_MONO.put('/', TokenType.OPE_DIV); - OPERATORS_MONO.put('\\', TokenType.ANTISLASH); - OPERATORS_MONO.put('+', TokenType.OPE_ADD); - OPERATORS_MONO.put('-', TokenType.OPE_SUB); - OPERATORS_MONO.put('*', TokenType.OPE_MUL); - OPERATORS_MONO.put('=', TokenType.EQUAL); - OPERATORS_MONO.put('!', TokenType.OPE_NOT); - OPERATORS_MONO.put(':', TokenType.COLON); - OPERATORS_MONO.put(';', TokenType.SEMI_COLON); - OPERATORS_MONO.put(',', TokenType.COMMA); - OPERATORS_MONO.put('.', TokenType.DOT); - OPERATORS_MONO.put('(', TokenType.BRACKET_OPEN); - OPERATORS_MONO.put(')', TokenType.BRACKET_CLOSE); - OPERATORS_MONO.put('[', TokenType.SQUARE_BRACKET_OPEN); - OPERATORS_MONO.put(']', TokenType.SQUARE_BRACKET_CLOSE); - OPERATORS_MONO.put('{', TokenType.BRACES_OPEN); - OPERATORS_MONO.put('}', TokenType.BRACES_CLOSE); - OPERATORS_MONO.put('<', TokenType.COMP_LT); - OPERATORS_MONO.put('>', TokenType.COMP_GT); - OPERATORS_MONO.put('@', TokenType.CHAR_AT); - - OPERATORS_BI.put("<=", TokenType.COMP_LE); - OPERATORS_BI.put(">=", TokenType.COMP_GE); - OPERATORS_BI.put("==", TokenType.COMP_EQ); - OPERATORS_BI.put("!=", TokenType.COMP_NE); - OPERATORS_BI.put("{{", TokenType.PROPERTY_OPEN); - OPERATORS_BI.put("}}", TokenType.PROPERTY_CLOSE); - OPERATORS_BI.put("&&", TokenType.OPE_AND); - OPERATORS_BI.put("||", TokenType.OPE_OR); - OPERATORS_BI.put("[[", TokenType.ARRAY_OPEN); - OPERATORS_BI.put("]]", TokenType.ARRAY_CLOSE); - - OPERATORS_BI.put(":+", TokenType.LIST_ADD); - OPERATORS_BI.put(":?", TokenType.LIST_CONTAINS); - OPERATORS_BI.put(":-", TokenType.LIST_REM); - OPERATORS_BI.put(":/", TokenType.LIST_REM_INDEX); - - // words - Arrays.stream(TokenType.values()) - .filter(t -> t.letters) - .forEach(t -> KEYWORDS.put(t.name().toLowerCase(), t)); - - // TimeUnits - putTimeUnit(TimeUnit.DAYS, "d", "D", "day", "days"); - putTimeUnit(TimeUnit.HOURS, "h", "H", "hour", "hours"); - putTimeUnit(TimeUnit.MINUTES, "m", "minute", "minutes"); - putTimeUnit(TimeUnit.SECONDS, "s", "sec", "secs", "second", "seconds"); - putTimeUnit(TimeUnit.MILLISECONDS, "ms", "milli", "millisecond", "milliseconds"); - } - - private final CharStream chars; - private final List tokens = new ArrayList<>(); - private boolean done = false; - - /** - * Tokenize a string. - * @param chars a stream of chars. - * @return a new token stream. - */ - public static @NotNull TokenStream tokenize(@NotNull CharStream chars) { - return new Tokenizer(chars).tokenize(); - } - - private final Predicate ALLOWED_WORD_START = Pattern.compile("[A-Za-z_]").asPredicate(); - private final Predicate ALLOWED_WORD_BODY = Pattern.compile("[A-Za-z_0-9]").asPredicate(); - - private Tokenizer(CharStream chars) { - this.chars = chars; - } - - private TokenStream tokenize() { - if(done) - return new TokenStream(tokens); - done = true; - - while(chars.hasMore()) { - char current = chars.next(); - - // Whitespace-trash - if(current == '\s' || current == '\t' || current == '\r' || current == '\n') - continue; - - // Comment - if(current == '#') { - skipUntilEOL(); - continue; - } - - // Basic symbols. - // All bi-operators start with one of the mono... let's use this fact. - // EDIT: just added AND and OR keywords start. - if(OPERATORS_MONO.containsKey(current) || current == '&' || current == '|') { - if(chars.hasMore()) { - char next = chars.peek(); - - // Number ? - if(current == '.' && isDigit(next)) { - tokens.add(Token.fromNumber(getNumber(current), chars.pos())); - continue; - } - - // Bi-operator ? - String symbol = String.valueOf(current) + next; - if(OPERATORS_BI.containsKey(symbol)) { - addRaw(OPERATORS_BI.get(symbol)); - chars.drop(); - continue; - } - } - addRaw(OPERATORS_MONO.get(current)); - continue; - } - - // String - if(current == '"') { - addString(); - continue; - } - - if(current == '%') { - if( ! chars.hasMore()) { - throw new ParsingException(chars.pos(), current, "Cannot end file with a '%' : expected a variable name."); - } - tokens.add(Token.fromVariable(getWord(null), chars.pos())); - continue; - } - - if(ALLOWED_WORD_START.test(String.valueOf(current))) { - TokenPosition position = chars.pos(); - String word = getWord(current); - - if(KEYWORDS.containsKey(word)) { - tokens.add(new Token(KEYWORDS.get(word), position)); - continue; - } - - if(TIME_UNITS.containsKey(word)) { - if(tokens.isEmpty() || last().getType() != TokenType.VALUE_NUMBER ) { - throw new ParsingException(chars.pos(), "Unexpected time unit '"+word+"'."); - } - // Replace number by duration - double number = last().getContentNumber(); - TimeUnit unit = TIME_UNITS.get(word); - tokens.removeLast(); - tokens.add(Token.fromDuration(number, unit, position)); - continue; - } - - tokens.add(Token.fromWord(word, position)); - - continue; - } - - if(isDigit(current)) { - tokens.add(Token.fromNumber(getNumber(current), chars.pos())); - continue; - } - - throw new ParsingException(chars.pos(), current, "Unknown character."); - } - - addRaw(TokenType.EOF); - return new TokenStream(tokens); - } - - private double getNumber(char first) { - StringBuilder sb = new StringBuilder(); - sb.append(first); // Can be a digit, a dot or a negative sign. - - boolean dot = first == '.'; - while(chars.hasMore()) { - char c = chars.peek(); - - // Dot - if(c == '.') { - if(dot) - throw new ParsingException(chars.pos(), c, "Cannot have multiple '.' in a number."); - dot = true; - sb.append('.'); - chars.drop(); - continue; - } - - // Number - if(isDigit(c)) { - sb.append(c); - chars.drop(); - continue; - } - - // EON - break; - } - return Double.parseDouble(sb.toString()); - } - - private void skipUntilEOL() { - while(chars.hasMore()) { - if(chars.next() == '\n') { - break; - } - } - } - - private String getWord(Character firstChar) { - StringBuilder content = new StringBuilder(); - if(firstChar != null) - content.append(firstChar); - - while(chars.hasMore()) { - if( ! ALLOWED_WORD_BODY.test(String.valueOf(chars.peek()))) { - // EOW - break; - } - content.append(chars.next()); - } - - return content.toString(); - } - - private void addString() { - StringBuilder sb = new StringBuilder(); - boolean escaped = false; - boolean closed = false; - while(chars.hasMore()) { - char c = chars.next(); - if(escaped) { - escaped = false; - sb.append(c); - continue; - } - if(c == '\\') { - escaped = true; - continue; - } - if(c == '"') { - // EOS - closed = true; - break; - } - if(c == '\n') { - // EOL ?? - throw new ParsingException(chars.pos(), "Unexpected carriage return in a string."); - } - - // Char - sb.append(c); - } - - if(!closed) - throw new ParsingException(chars.pos(), chars.peek(), "Cannot end file with a '\"' : expected a closing quote for the string."); - - tokens.add(Token.fromString(sb.toString(), chars.pos())); - } - - private static boolean isDigit(char c) { - return c >= '0' && c <= '9'; - } - - private void addRaw(TokenType type) { - tokens.add(type.toToken(chars.pos())); - } - - private static void putTimeUnit(TimeUnit unit, String... identifiers) { - for(String identifier : identifiers) - TIME_UNITS.put(identifier, unit); - } - - private Token last() { - return tokens.getLast(); - } - -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/validators/DslValidator.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/validators/DslValidator.java deleted file mode 100644 index 8060cbb6..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/validators/DslValidator.java +++ /dev/null @@ -1,45 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.validators; - -import fr.jamailun.ultimatespellsystem.dsl.nodes.StatementNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.variables.TypesContext; -import org.jetbrains.annotations.NotNull; - -import java.util.List; - -/** - * Validate the DSL tree. - */ -public final class DslValidator { - private DslValidator() {} - - /** - * Validate an AST. - * @param nodes the AST to validate. - */ - public static void validateDsl(@NotNull List nodes) { - validateType(nodes); - validateTree(nodes); - } - - /** - * Validate and propagate types. - * @param nodes the nodes to handle. - */ - public static void validateType(@NotNull List nodes) { - TypesContext context = new TypesContext(); - for (StatementNode node : nodes) { - node.validateTypes(context); - } - } - - /** - * Validate the tree structure. - * @param nodes the nodes to handle. - */ - public static void validateTree(@NotNull List nodes) { - StructureValidationVisitor visitor = new StructureValidationVisitor(); - for(StatementNode node : nodes) { - node.visit(visitor); - } - } -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/validators/StructureValidationVisitor.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/validators/StructureValidationVisitor.java deleted file mode 100644 index f58da5f7..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/validators/StructureValidationVisitor.java +++ /dev/null @@ -1,114 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.validators; - -import fr.jamailun.ultimatespellsystem.dsl.errors.TreeValidationException; -import fr.jamailun.ultimatespellsystem.dsl.nodes.StatementNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.statements.*; -import fr.jamailun.ultimatespellsystem.dsl.nodes.statements.blocks.*; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenPosition; -import fr.jamailun.ultimatespellsystem.dsl.visitor.StatementVisitor; -import org.jetbrains.annotations.NotNull; - -/** - * Structure validation. - */ -public class StructureValidationVisitor implements StatementVisitor { - private boolean stopMet = false; - private boolean breakMet = false; - private boolean metadataAllowed = true; - - private StructureValidationVisitor child() { - StructureValidationVisitor clone = new StructureValidationVisitor(); - clone.metadataAllowed = metadataAllowed; - clone.stopMet = stopMet; - clone.breakMet = breakMet; - return clone; - } - - @Override - public void handleMetadata(@NotNull MetadataStatement statement) { - if(!metadataAllowed) - throw new TreeValidationException(TokenPosition.unknown(), "Meta-data can only be the first statements."); - } - - @Override - public void handleStop(@NotNull StopStatement statement) { - handleMono(); - stopMet = true; - } - @Override - public void handleBreakContinue(@NotNull BreakContinueStatement statement) { - handleMono(); - breakMet = true; - } - - @Override - public void handleBlock(@NotNull BlockStatement statement) { - handleMono(); - StructureValidationVisitor child = child(); - statement.getChildren().forEach(n -> n.visit(child)); - } - - private void handleSub(@NotNull StatementNode child) { - child.visit(child()); - } - - private void handleMono() { - metadataAllowed = false; - if(stopMet) { - throw new TreeValidationException(TokenPosition.unknown(), "Cannot have a statement after a STOP."); - } - if(breakMet) { - throw new TreeValidationException(TokenPosition.unknown(), "Cannot have a statement in the block after a BREAK or a CONTINUE."); - } - } - - @Override - public void handleIf(@NotNull IfElseStatement statement) { - handleSub(statement.getChild()); - statement.getElse().ifPresent(this::handleSub); - } - @Override - public void handleForLoop(@NotNull ForLoopStatement statement) { - handleSub(statement.getChild()); - } - @Override - public void handleForeachLoop(@NotNull ForeachLoopStatement statement) { - handleSub(statement.getChild()); - } - @Override - public void handleWhileLoop(@NotNull WhileLoopStatement statement) { - handleSub(statement.getChild()); - } - @Override - public void handleRunLater(@NotNull RunLaterStatement statement) { - statement.getChild().visit(child()); - } - @Override - public void handleRepeatRun(@NotNull RepeatStatement statement) {statement.getChild().visit(child());} - @Override - public void handleCallback(@NotNull CallbackStatement statement) {statement.getChild().visit(child());} - - @Override - public void handleSendMessage(@NotNull SendMessageStatement statement) {handleMono();} - @Override - public void handleSendNbt(@NotNull SendNbtStatement statement) {handleMono();} - @Override - public void handleSendEffect(@NotNull SendEffectStatement statement) {handleMono();} - @Override - public void handleSendAttribute(@NotNull SendAttributeStatement statement) {handleMono();} - - @Override - public void handleDefine(@NotNull DefineStatement statement) {handleMono();} - @Override - public void handleSummon(@NotNull SummonStatement statement) {handleMono();} - @Override - public void handleIncrement(@NotNull IncrementStatement statement) {handleMono();} - @Override - public void handleTeleport(@NotNull TeleportStatement statement) {handleMono();} - @Override - public void handlePlay(@NotNull PlayStatement statement) {handleMono();} - @Override - public void handleGive(@NotNull GiveStatement statement) {handleMono();} - @Override - public void handleSimpleExpression(@NotNull SimpleExpressionStatement statement) {handleMono();} -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/visitor/ExpressionVisitor.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/visitor/ExpressionVisitor.java deleted file mode 100644 index 129b72c4..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/visitor/ExpressionVisitor.java +++ /dev/null @@ -1,45 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.visitor; - -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.*; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.compute.AllEntitiesAroundExpression; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.FunctionCallExpression; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.compute.PositionOfExpression; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.compute.SizeOfExpression; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.litteral.*; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.operators.BiOperator; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.operators.MonoOperator; -import org.jetbrains.annotations.NotNull; - -/** - * A visitor. Can interact with the node-tree. - */ -public interface ExpressionVisitor { - - // Literals - void handleNullLiteral(@NotNull NullExpression literal); - void handleBooleanLiteral(@NotNull BooleanExpression literal); - void handleNumberLiteral(@NotNull NumberExpression literal); - void handleStringLiteral(@NotNull StringExpression literal); - void handleEntityTypeLiteral(@NotNull EntityTypeExpression literal); - void handleRuntimeLiteral(@NotNull RuntimeLiteral literal); - void handleDurationLiteral(@NotNull DurationExpression literal); - void handleLocationLiteral(@NotNull LocationLiteral literal); - - // Operators-ish - void handleBiOperator(@NotNull BiOperator operator); - void handleMonoOperator(@NotNull MonoOperator operator); - void handleParenthesis(@NotNull ParenthesisExpression parenthesis); - void handleArrayGet(@NotNull ArrayGetterExpression arrayGetter); - - // Specifics - void handlePropertiesSet(@NotNull PropertiesExpression expression); - void handleArray(@NotNull ArrayExpression expression); - void handleVariable(@NotNull VariableExpression expression); - - // Functions - void handleAllAround(@NotNull AllEntitiesAroundExpression expression); - void handlePositionOf(@NotNull PositionOfExpression expression); - void handleSizeOf(@NotNull SizeOfExpression expression); - void handleFunction(@NotNull FunctionCallExpression expression); - -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/visitor/PrintingVisitor.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/visitor/PrintingVisitor.java deleted file mode 100644 index be7e80da..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/visitor/PrintingVisitor.java +++ /dev/null @@ -1,557 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.visitor; - -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.FunctionCallExpression; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.compute.SizeOfExpression; -import fr.jamailun.ultimatespellsystem.dsl.nodes.statements.blocks.*; -import fr.jamailun.ultimatespellsystem.dsl.nodes.ExpressionNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.StatementNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.*; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.compute.AllEntitiesAroundExpression; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.compute.PositionOfExpression; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.litteral.*; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.operators.BiOperator; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.operators.MonoOperator; -import fr.jamailun.ultimatespellsystem.dsl.nodes.statements.*; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.Duration; -import org.jetbrains.annotations.NotNull; - -import java.text.DecimalFormat; -import java.util.List; -import java.util.Map; - -/** - * Made to print content. - */ -public class PrintingVisitor implements StatementVisitor, ExpressionVisitor { - - private final static DecimalFormat formatNumber = new DecimalFormat("#.##"); - - private final int indentDelta; - private String indentBuffer; - private int currentIndent = 0; - private boolean dirty = true; - - private StringBuilder builder; - - private PrintingVisitor(int indent) { - this.indentDelta = indent; - } - - private @NotNull String visit(@NotNull List statements) { - builder = new StringBuilder(); - for(StatementNode statement : statements) { - statement.visit(this); - eol(); - } - return builder.toString(); - } - - /** - * Print multiple statements to sys-out, with an indentation of {@code 2}. - * @param statements the non-null statements to visit. - */ - public static void print(@NotNull List statements) { - print(statements, 2); - } - - /** - * Print multiple statements to sys-out. - * @param statements list of statements to print. - * @param indent specific indent to use. - */ - public static void print(@NotNull List statements, int indent) { - System.out.println(toString(statements, indent)); - } - - /** - * Print multiple statements to a String. - * @param statements list of statements to print. - * @return the print output. - */ - public static @NotNull String toString(@NotNull List statements) { - return toString(statements, 2); - } - - /** - * Print multiple statements to a String. - * @param statements list of statements to print. - * @param indent specific indent to use. - * @return the print output. - */ - public static @NotNull String toString(@NotNull List statements, int indent) { - return new PrintingVisitor(indent).visit(statements); - } - - private @NotNull String indent() { - if(dirty) { - indentBuffer = " ".repeat(currentIndent); - dirty = false; - } - return indentBuffer; - } - - private void right() { - currentIndent += indentDelta; - dirty = true; - } - - private void left() { - currentIndent -= indentDelta; - if(currentIndent < 0) { - currentIndent = 0; - } - dirty = true; - } - - private void eol() { - builder.append(";\n"); - } - - @Override - public void handleStop(@NotNull StopStatement statement) { - builder.append(indent()).append("stop"); - } - - @Override - public void handleSendMessage(@NotNull SendMessageStatement statement) { - builder.append(indent()).append("send to "); - statement.getTarget().visit(this); - builder.append(" message "); - statement.getMessage().visit(this); - } - - @Override - public void handleSendNbt(@NotNull SendNbtStatement statement) { - builder.append(indent()).append("send to "); - statement.getTarget().visit(this); - builder.append(" NBT "); - statement.getNbtName().visit(this); - builder.append(" = "); - statement.getNbtValue().visit(this); - builder.append(" for "); - statement.getNbtDuration().visit(this); - } - - @Override - public void handleSendEffect(@NotNull SendEffectStatement statement) { - builder.append(indent()).append("send to "); - statement.getTarget().visit(this); - builder.append(" effect "); - statement.getEffectType().visit(this); - statement.getEffectPower().ifPresent(e -> { - builder.append(" "); - e.visit(this); - }); - builder.append(" for "); - statement.getEffectDuration().visit(this); - } - - @Override - public void handleSendAttribute(@NotNull SendAttributeStatement statement) { - builder.append(indent()).append("send to "); - statement.getTarget().visit(this); - builder.append(" attribute "); - statement.getNumericValue().visit(this); - builder.append(" "); - statement.getAttributeType().visit(this); - statement.getAttributeMode().ifPresent(e -> { - builder.append(" ("); - e.visit(this); - builder.append(")"); - }); - builder.append(" for "); - statement.getDuration().visit(this); - } - - @Override - public void handleDefine(@NotNull DefineStatement statement) { - builder.append(indent()) - .append("define %") - .append(statement.getVarName()) - .append(" = "); - statement.getExpression().visit(this); - } - - @Override - public void handleRunLater(@NotNull RunLaterStatement statement) { - builder.append(indent()).append("run after "); - statement.getDuration().visit(this); - builder.append(" : "); - statement.getChild().visit(this); - } - - @Override - public void handleRepeatRun(@NotNull RepeatStatement statement) { - builder.append(indent()).append("run "); - statement.getDelay().ifPresent(e -> { - builder.append("after "); - e.visit(this); - builder.append(", "); - }); - if(statement.getTotalCount() != null) { - statement.getTotalCount().visit(this); - builder.append(" times every "); - statement.getPeriod().visit(this); - } else { - assert statement.getTotalDuration() != null; - builder.append("every "); - statement.getPeriod().visit(this); - builder.append(" for "); - statement.getTotalDuration().visit(this); - } - builder.append(" : "); - statement.getChild().visit(this); - } - - @Override - public void handleSummon(@NotNull SummonStatement statement) { - builder.append(indent()).append("summon "); - statement.getEntityType().visit(this); - statement.getSource().ifPresent(p -> { - builder.append(" at "); - p.visit(this); - }); - builder.append(" for "); - statement.getDuration().visit(this); - statement.getVarName().ifPresent(v -> builder.append(" as %").append(v)); - statement.getProperties().ifPresent(p -> { - builder.append(" with: "); - p.visit(this); - }); - } - - @Override - public void handleBlock(@NotNull BlockStatement statement) { - builder.append("{\n"); - right(); - for(StatementNode child : statement.getChildren()) { - child.visit(this); - eol(); - } - left(); - builder.append(indent()).append("}"); - } - - @Override - public void handleIncrement(@NotNull IncrementStatement statement) { - builder.append(statement.isPositive() ? "++" : "--") - .append("%").append(statement.getVarName()); - } - - @Override - public void handleTeleport(@NotNull TeleportStatement statement) { - builder.append("teleport "); - statement.getEntity().visit(this); - builder.append(" to "); - statement.getTarget().visit(this); - } - - @Override - public void handlePlay(@NotNull PlayStatement statement) { - builder.append("PLAY ") - .append(statement.getType()) - .append(" AT "); - statement.getLocation().visit(this); - builder.append(" WITH "); - statement.getProperties().visit(this); - } - - @Override - public void handleGive(@NotNull GiveStatement statement) { - builder.append("GIVE"); - if(statement.getOptAmount() != null) { - builder.append(" "); - statement.getOptAmount().visit(this); - } - if(statement.getOptType() != null) { - builder.append(" "); - statement.getOptType().visit(this); - } - builder.append(" TO "); - statement.getTarget().visit(this); - if(statement.getOptProperties() != null) { - builder.append(" WITH: "); - statement.getOptProperties().visit(this); - } - } - - @Override - public void handleCallback(@NotNull CallbackStatement statement) { - builder.append("CALLBACK %") - .append(statement.getListenVariableName()) - .append(" ON @") - .append(statement.getCallbackType().name()); - statement.getOutputVariable().ifPresent(output -> { - assert statement.getCallbackType().argument() != null; // compiler hint - builder.append(statement.getCallbackType().argument().keyword()) - .append(" %") - .append(output); - }); - builder.append(": "); - statement.getChild().visit(this); - } - - @Override - public void handleSimpleExpression(@NotNull SimpleExpressionStatement statement) { - builder.append("{"); - statement.getChild().visit(this); - builder.append("}"); - } - - @Override - public void handleMetadata(@NotNull MetadataStatement statement) { - builder.append(indent()).append("@").append(statement.getName()); - boolean big = statement.getParams().size() > 1; - if(big) builder.append("("); - boolean first = true; - for(Object node : statement.getParams()) { - if(first) first = false; else builder.append(", "); - builder.append(node); - } - if(big) builder.append(")"); - } - - @Override - public void handleIf(@NotNull IfElseStatement statement) { - builder.append(indent()).append("IF("); - statement.getCondition().visit(this); - builder.append("):"); - right(); - statement.getChild().visit(this); - left(); - builder.append("\n"); - - statement.getElse().ifPresent(e -> { - builder.append(indent()).append("ELSE : "); - right(); - e.visit(this); - left(); - builder.append("\n"); - }); - } - - @Override - public void handleForLoop(@NotNull ForLoopStatement statement) { - builder.append(indent()) - .append("FOR("); - if(statement.getInitialization() != null) statement.getInitialization().visit(this); - statement.getCondition().visit(this); - builder.append(";"); - if(statement.getIteration() != null) statement.getIteration().visit(this); - builder.append("):"); - statement.getChild().visit(this); - } - - @Override - public void handleForeachLoop(@NotNull ForeachLoopStatement statement) { - builder.append(indent()) - .append("FOREACH(%") - .append(statement.getVariableName()) - .append(" : "); - statement.getSource().visit(this); - builder.append("):"); - statement.getChild().visit(this); - } - - @Override - public void handleWhileLoop(@NotNull WhileLoopStatement statement) { - if(statement.isWhileFirst()) { - builder.append("WHILE("); - statement.getCondition().visit(this); - builder.append(") "); - } else { - builder.append("DO "); - } - statement.getChild().visit(this); - if(!statement.isWhileFirst()) { - builder.append(" WHILE("); - statement.getCondition().visit(this); - builder.append(") "); - } - } - - @Override - public void handleBreakContinue(@NotNull BreakContinueStatement statement) { - builder.append(statement.isContinue() ? "CONTINUE" : "BREAK"); - } - - @Override - public void handleNullLiteral(@NotNull NullExpression literal) { - builder.append("NULL"); - } - - @Override - public void handleBooleanLiteral(@NotNull BooleanExpression literal) { - builder.append(literal.getRaw()); - } - - @Override - public void handleNumberLiteral(@NotNull NumberExpression literal) { - double num = literal.getRaw(); - builder.append(formatNumber.format(num)); - } - - @Override - public void handleStringLiteral(@NotNull StringExpression literal) { - builder.append("\"").append(literal.getRaw()).append("\""); - } - - @Override - public void handleEntityTypeLiteral(@NotNull EntityTypeExpression literal) { - builder.append("EntityType.").append(literal.getRaw()); - } - - @Override - public void handleRuntimeLiteral(@NotNull RuntimeLiteral literal) { - builder.append("'").append(literal.getRaw()).append("'"); - } - - @Override - public void handleDurationLiteral(@NotNull DurationExpression literal) { - Duration duration = literal.getRaw(); - builder.append(formatNumber.format(duration.amount())) - .append(" ") - .append(duration.niceUnit()); - } - - @Override - public void handleLocationLiteral(@NotNull LocationLiteral literal) { - builder.append("Location("); - literal.getWorld().visit(this); builder.append(", "); - literal.getVectorX().visit(this); builder.append(", "); - literal.getVectorY().visit(this); builder.append(", "); - literal.getVectorZ().visit(this); - if(literal.asYawAndPitch()) { - builder.append(", "); - literal.getYaw().visit(this); - builder.append(", "); - literal.getPitch().visit(this); - } - builder.append(")"); - } - - @Override - public void handleBiOperator(@NotNull BiOperator operator) { - operator.getLeft().visit(this); - String ope = switch (operator.getType()) { - case ADD -> "+"; - case SUB -> "-"; - case MUL -> "*"; - case DIV -> "/"; - case EQUAL -> "=="; - case NOT_EQUAL -> "!="; - case GREATER_OR_EQ -> ">="; - case GREATER -> ">"; - case LESSER_OR_EQ -> "<="; - case LESSER -> "<"; - case AND -> "and"; - case OR -> "or"; - case LIST_ADD -> "append"; - case LIST_REM -> "remove"; - case LIST_CONTAINS -> "contains"; - case LIST_REM_INDEX -> "remove_idx"; - }; - builder.append(" ").append(ope).append(" "); - operator.getRight().visit(this); - } - - @Override - public void handleMonoOperator(@NotNull MonoOperator operator) { - String ope = operator.getType().name(); - builder.append(ope).append("("); - operator.getChild().visit(this); - builder.append(")"); - } - - @Override - public void handleParenthesis(@NotNull ParenthesisExpression parenthesis) { - builder.append("("); - parenthesis.getExpression().visit(this); - builder.append(")"); - } - - @Override - public void handleArrayGet(@NotNull ArrayGetterExpression arrayGetter) { - arrayGetter.getArray().visit(this); - builder.append("["); - arrayGetter.getIndex().visit(this); - builder.append("]"); - } - - @Override - public void handlePropertiesSet(@NotNull PropertiesExpression expression) { - builder.append("{{"); - if(expression.getExpressions().isEmpty()) { - builder.append("}}"); - return; - } - builder.append("\n"); - right(); - boolean first = true; - for(Map.Entry entry : expression.getExpressions().entrySet()) { - if(first) first = false; else builder.append(",\n"); - builder.append(indent()) - .append(entry.getKey()) - .append(" = "); - entry.getValue().visit(this); - } - builder.append("\n"); - left(); - builder.append(indent()).append("}}"); - } - - @Override - public void handleAllAround(@NotNull AllEntitiesAroundExpression expression) { - builder.append(""); - } - - @Override - public void handlePositionOf(@NotNull PositionOfExpression expression) { - builder.append("position of ("); - expression.getEntity().visit(this); - builder.append(")"); - } - - @Override - public void handleSizeOf(@NotNull SizeOfExpression expression) { - builder.append("sizeof("); - expression.getChild().visit(this); - builder.append(")"); - } - - @Override - public void handleFunction(@NotNull FunctionCallExpression expression) { - builder.append(":") - .append(expression.getFunction().id()) - .append("("); - boolean first = true; - for(ExpressionNode arg : expression.getArguments()) { - if(first) first = false; else builder.append(", "); - arg.visit(this); - } - builder.append(")"); - } - - @Override - public void handleArray(@NotNull ArrayExpression expression) { - builder.append("["); - boolean first = true; - for(ExpressionNode child : expression.getElements()) { - if(first) first = false; else builder.append(", "); - child.visit(this); - } - builder.append("]"); - } - - @Override - public void handleVariable(@NotNull VariableExpression expression) { - builder.append("%").append(expression.getVariableName()); - } -} diff --git a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/visitor/StatementVisitor.java b/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/visitor/StatementVisitor.java deleted file mode 100644 index 97f1f470..00000000 --- a/dsl/src/main/java/fr/jamailun/ultimatespellsystem/dsl/visitor/StatementVisitor.java +++ /dev/null @@ -1,35 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.visitor; - -import fr.jamailun.ultimatespellsystem.dsl.nodes.statements.blocks.*; -import fr.jamailun.ultimatespellsystem.dsl.nodes.statements.*; -import org.jetbrains.annotations.NotNull; - -/** - * A visitor. Can interact with the node-tree. - */ -public interface StatementVisitor { - - void handleStop(@NotNull StopStatement statement); - void handleSendAttribute(@NotNull SendAttributeStatement statement); - void handleSendEffect(@NotNull SendEffectStatement statement); - void handleSendMessage(@NotNull SendMessageStatement statement); - void handleSendNbt(@NotNull SendNbtStatement statement); - void handleDefine(@NotNull DefineStatement statement); - void handleRunLater(@NotNull RunLaterStatement statement); - void handleRepeatRun(@NotNull RepeatStatement statement); - void handleSummon(@NotNull SummonStatement statement); - void handleBlock(@NotNull BlockStatement statement); - void handleIncrement(@NotNull IncrementStatement statement); - void handleTeleport(@NotNull TeleportStatement statement); - void handlePlay(@NotNull PlayStatement statement); - void handleGive(@NotNull GiveStatement statement); - void handleCallback(@NotNull CallbackStatement statement); - void handleSimpleExpression(@NotNull SimpleExpressionStatement statement); - void handleMetadata(@NotNull MetadataStatement statement); - - void handleIf(@NotNull IfElseStatement statement); - void handleForLoop(@NotNull ForLoopStatement statement); - void handleForeachLoop(@NotNull ForeachLoopStatement statement); - void handleWhileLoop(@NotNull WhileLoopStatement statement); - void handleBreakContinue(@NotNull BreakContinueStatement statement); -} diff --git a/dsl/src/test/java/fr/jamailun/ultimatespellsystem/dsl/CorrectParsingTests.java b/dsl/src/test/java/fr/jamailun/ultimatespellsystem/dsl/CorrectParsingTests.java deleted file mode 100644 index 1e98c21f..00000000 --- a/dsl/src/test/java/fr/jamailun/ultimatespellsystem/dsl/CorrectParsingTests.java +++ /dev/null @@ -1,79 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl; - -import fr.jamailun.ultimatespellsystem.dsl.errors.UssException; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.FunctionArgument; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.FunctionDefinition; -import fr.jamailun.ultimatespellsystem.dsl.nodes.expressions.functions.FunctionType; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.TypePrimitive; -import fr.jamailun.ultimatespellsystem.dsl.objects.CallbackEvent; -import fr.jamailun.ultimatespellsystem.dsl.registries.CallbackEventRegistry; -import fr.jamailun.ultimatespellsystem.dsl.registries.FunctionDefinitionsRegistry; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenType; -import org.jetbrains.annotations.NotNull; -import org.junit.jupiter.api.Test; - -import java.io.File; -import java.util.List; - -/** - * Multiple tests for valid USS files. - */ -public class CorrectParsingTests extends ParsingTest { - - //@Test - void correctStatements() { - testFolder("corrects/statements"); - } - //@Test - void correctBlocks() { - testFolder("corrects/blocks"); - } - // @Test - void correctOperators() { - testFolder("corrects/operators"); - } - //@Test - void correctMix() { - testFolder("corrects/mix"); - } - //@Test - void correctMetadata() { - testFolder("corrects/metadata"); - } - - // @Test - void correctWithCustom() { - // Register "custom_add" - FunctionDefinition definition = new FunctionDefinition( - "custom_add", - TypePrimitive.NUMBER.asType(), - List.of( - new FunctionArgument(FunctionType.accept(TypePrimitive.NUMBER), "a", false), - new FunctionArgument(FunctionType.accept(TypePrimitive.NUMBER), "b", false) - ) - ); - FunctionDefinitionsRegistry.register(definition); - - // Callback - CallbackEventRegistry.register( - CallbackEvent.of("landed", TokenType.AT, TypePrimitive.LOCATION) - ); - - // Parse - testFolder("corrects_with_custom"); - } - - private void testFolder(@NotNull String folder) { - for(File file : listTests(folder)) { - try { - parseAndVerify(file); - addOk(); - } catch (UssException e) { - e.printStackTrace(); - addFails(file, toString(e)); - } - } - printResults(); - } - -} diff --git a/dsl/src/test/java/fr/jamailun/ultimatespellsystem/dsl/FailuresParsingTests.java b/dsl/src/test/java/fr/jamailun/ultimatespellsystem/dsl/FailuresParsingTests.java deleted file mode 100644 index ced2bd96..00000000 --- a/dsl/src/test/java/fr/jamailun/ultimatespellsystem/dsl/FailuresParsingTests.java +++ /dev/null @@ -1,59 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl; - -import fr.jamailun.ultimatespellsystem.dsl.errors.*; -import org.jetbrains.annotations.NotNull; -import org.junit.jupiter.api.Test; - -import java.io.File; - -/** - * Multiple tests for invalid USS files. - */ -public class FailuresParsingTests extends ParsingTest { - - // @Test - void badParsing() { - badParsing("bad_parsing", ParsingException.class); - } - - // @Test - void badSyntax() { - badParsing("bad_syntax", SyntaxException.class); - } - - // @Test - void badType() { - badParsing("bad_type", TypeException.class); - } - - // @Test - void badTreeValidation() { - badParsing("bad_tree", TreeValidationException.class); - } - - // @Test - void badMix() { - badParsing("bad_mix", UssException.class); - } - - private void badParsing(@NotNull String folder, @NotNull Class clazz) { - String title = "[! EXPECTED "+clazz.getSimpleName()+"] "; - for(File file : listTests(folder)) { - try { - parseAndVerify(file); - addFails(file, title + "Got not error."); - } catch(Exception exception) { - if(clazz.isAssignableFrom(exception.getClass())) { - System.out.println("Error: " + exception); - addOk(); - } else { - System.err.println("GOT " + exception.getClass() + ", expected " + clazz); - exception.printStackTrace(); - addFails(file, title + "Got " + toString(exception)); - } - } - } - printResults(); - } - -} diff --git a/dsl/src/test/java/fr/jamailun/ultimatespellsystem/dsl/ParsingTest.java b/dsl/src/test/java/fr/jamailun/ultimatespellsystem/dsl/ParsingTest.java deleted file mode 100644 index fde1d233..00000000 --- a/dsl/src/test/java/fr/jamailun/ultimatespellsystem/dsl/ParsingTest.java +++ /dev/null @@ -1,97 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl; - -import fr.jamailun.ultimatespellsystem.dsl.errors.UssException; -import fr.jamailun.ultimatespellsystem.dsl.nodes.StatementNode; -import fr.jamailun.ultimatespellsystem.dsl.nodes.type.variables.TypesContext; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.CharStream; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.TokenStream; -import fr.jamailun.ultimatespellsystem.dsl.tokenization.Tokenizer; -import fr.jamailun.ultimatespellsystem.dsl.validators.DslValidator; -import fr.jamailun.ultimatespellsystem.dsl.visitor.PrintingVisitor; -import org.jetbrains.annotations.NotNull; -import org.junit.jupiter.api.Assertions; - -import java.io.File; -import java.util.*; -import java.util.stream.Stream; - -/** - * Test framework for parsing tests. - */ -abstract class ParsingTest { - - protected final File PARSINGS_FILE = new File("src/test/resources/parsing"); - - protected @NotNull List listTests(@NotNull String subFolder) { - File directory = new File(PARSINGS_FILE, subFolder); - Assertions.assertTrue(directory.exists() && directory.isDirectory(), "Directory '" + subFolder + "' does not exist."); - - File[] children = directory.listFiles(); - if(children == null) { - return Collections.emptyList(); - } - return Stream.of(children) - .filter(File::isFile) - .sorted(Comparator.comparing(File::getName)) - .toList(); - } - - protected @NotNull String toString(@NotNull Exception e) { - return e.getClass().getSimpleName() + " : " + e.getMessage(); - } - - protected int countOk = 0; - protected final Map failures = new HashMap<>(); - - protected void addOk() { - countOk++; - } - protected void addFails(@NotNull File test, @NotNull String error) { - failures.put(test, error); - } - - protected void parseAndVerify(@NotNull File file) throws UssException { - System.out.println("\n\n ================[ " + file.getName() + "]================\n"); - // Tokenize - TokenStream tokens = Tokenizer.tokenize(CharStream.from(file)); - System.out.println(tokens + "\n"); - - // Parse - List nodes = UltimateSpellSystemDSL.parse(tokens); - - System.out.println(" ----------------------- "); - - // validate - TypesContext context = new TypesContext(); - for (StatementNode node : nodes) { - node.validateTypes(context); - System.out.println("> " + node); - } - DslValidator.validateTree(nodes); - - // The visitor works as expected. - PrintingVisitor.print(nodes); - } - - public static final String RESET = "\033[0m"; // Text Reset - public static final String RED_BOLD = "\033[1;31m"; // RED - public static final String RED = "\033[0;31m"; // RED - public static final String GREEN_BOLD = "\033[1;32m"; // GREEN - public static final String WHITE_BOLD = "\033[1;37m"; // WHITE - - protected void printResults() { - String color = failures.isEmpty() ? GREEN_BOLD : RED_BOLD; - System.out.println("\n" + WHITE_BOLD + "==================== [" + color + " RESULTS " + WHITE_BOLD + "] ====================" + RESET + "\n"); - System.out.println(color + "Success : " + countOk + RESET); - System.out.println(color + "Failures : " + failures.size() + RESET); - if(!failures.isEmpty()) { - System.out.println(); - failures.forEach((k, v) -> System.out.println(RED_BOLD + " - " + k.getName() + " > " + RED + v)); - } - System.out.println("\n" + WHITE_BOLD + "=====================================================" + RESET + "\n"); - - if(!failures.isEmpty()) - System.exit(42); - } - -} diff --git a/dsl/src/test/java/fr/jamailun/ultimatespellsystem/dsl/nodes/type/DurationTests.java b/dsl/src/test/java/fr/jamailun/ultimatespellsystem/dsl/nodes/type/DurationTests.java deleted file mode 100644 index b3f87e0b..00000000 --- a/dsl/src/test/java/fr/jamailun/ultimatespellsystem/dsl/nodes/type/DurationTests.java +++ /dev/null @@ -1,38 +0,0 @@ -package fr.jamailun.ultimatespellsystem.dsl.nodes.type; - -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -import java.util.concurrent.TimeUnit; - -/** - * Tests for {@link Duration} class. - */ -class DurationTests { - - //@Test - void testDurOpeDur() { - Duration a = new Duration(12, TimeUnit.HOURS); - Duration b = new Duration(60, TimeUnit.MINUTES); - Assertions.assertEquals(12, a.div(b)); - - Duration c = new Duration(1, TimeUnit.HOURS); - Duration d = new Duration(1, TimeUnit.SECONDS); - Assertions.assertEquals(new Duration(3601, TimeUnit.SECONDS), c.add(d)); - - Assertions.assertEquals(new Duration(2, TimeUnit.HOURS), c.add(c)); - } - - //@Test - void testDurDivLambda() { - Duration a = new Duration(12, TimeUnit.HOURS); - Assertions.assertEquals(new Duration(120, TimeUnit.MINUTES), a.div(6)); - } - - //@Test - void testDurMul() { - Duration a = new Duration(12, TimeUnit.MINUTES); - Assertions.assertEquals(new Duration(1, TimeUnit.HOURS), a.mul(5)); - } - -} diff --git a/dsl/src/test/resources/parsing/bad_mix/invalid_param_meta.uss b/dsl/src/test/resources/parsing/bad_mix/invalid_param_meta.uss deleted file mode 100644 index db31ab9e..00000000 --- a/dsl/src/test/resources/parsing/bad_mix/invalid_param_meta.uss +++ /dev/null @@ -1,3 +0,0 @@ -@param(12, ""); - -define %a = 2; diff --git a/dsl/src/test/resources/parsing/bad_mix/unknown_function.uss b/dsl/src/test/resources/parsing/bad_mix/unknown_function.uss deleted file mode 100644 index 055a585e..00000000 --- a/dsl/src/test/resources/parsing/bad_mix/unknown_function.uss +++ /dev/null @@ -1 +0,0 @@ -define %a = i_dont_exist("toto"); \ No newline at end of file diff --git a/dsl/src/test/resources/parsing/bad_parsing/bad_number.uss b/dsl/src/test/resources/parsing/bad_parsing/bad_number.uss deleted file mode 100644 index d1da7e46..00000000 --- a/dsl/src/test/resources/parsing/bad_parsing/bad_number.uss +++ /dev/null @@ -1 +0,0 @@ -define %a = 5..1; \ No newline at end of file diff --git a/dsl/src/test/resources/parsing/bad_parsing/bad_string.uss b/dsl/src/test/resources/parsing/bad_parsing/bad_string.uss deleted file mode 100644 index b807acac..00000000 --- a/dsl/src/test/resources/parsing/bad_parsing/bad_string.uss +++ /dev/null @@ -1,2 +0,0 @@ -define %a = "a -b"; \ No newline at end of file diff --git a/dsl/src/test/resources/parsing/bad_syntax/bad_else.uss b/dsl/src/test/resources/parsing/bad_syntax/bad_else.uss deleted file mode 100644 index 1efc7306..00000000 --- a/dsl/src/test/resources/parsing/bad_syntax/bad_else.uss +++ /dev/null @@ -1,3 +0,0 @@ -if(1 == 1) stop; -else stop; -else stop; diff --git a/dsl/src/test/resources/parsing/bad_syntax/bad_entity_type.uss b/dsl/src/test/resources/parsing/bad_syntax/bad_entity_type.uss deleted file mode 100644 index 6af8ceec..00000000 --- a/dsl/src/test/resources/parsing/bad_syntax/bad_entity_type.uss +++ /dev/null @@ -1,3 +0,0 @@ -# Unknown subtype of send'. - -summon I_DONT_EXIST for 4s; diff --git a/dsl/src/test/resources/parsing/bad_syntax/bad_send.uss b/dsl/src/test/resources/parsing/bad_syntax/bad_send.uss deleted file mode 100644 index e8e1f09f..00000000 --- a/dsl/src/test/resources/parsing/bad_syntax/bad_send.uss +++ /dev/null @@ -1,3 +0,0 @@ -# Unknown subtype of send'. - -send to %caster I_DONT_EXIST "I'm a failure"; diff --git a/dsl/src/test/resources/parsing/bad_syntax/bad_var.uss b/dsl/src/test/resources/parsing/bad_syntax/bad_var.uss deleted file mode 100644 index 7fa3c971..00000000 --- a/dsl/src/test/resources/parsing/bad_syntax/bad_var.uss +++ /dev/null @@ -1,2 +0,0 @@ -define %correct = 12; -%correct; \ No newline at end of file diff --git a/dsl/src/test/resources/parsing/bad_syntax/redefine_caster.uss b/dsl/src/test/resources/parsing/bad_syntax/redefine_caster.uss deleted file mode 100644 index 4ccdb855..00000000 --- a/dsl/src/test/resources/parsing/bad_syntax/redefine_caster.uss +++ /dev/null @@ -1 +0,0 @@ -define %caster = 2; diff --git a/dsl/src/test/resources/parsing/bad_tree/after_break.uss b/dsl/src/test/resources/parsing/bad_tree/after_break.uss deleted file mode 100644 index 865eb84b..00000000 --- a/dsl/src/test/resources/parsing/bad_tree/after_break.uss +++ /dev/null @@ -1,6 +0,0 @@ -for(%i = 1; %i < 3; increment %i) { - if(%i == 2) { - break; - send to %caster message "oops"; - } -} \ No newline at end of file diff --git a/dsl/src/test/resources/parsing/bad_tree/after_meta_1.uss b/dsl/src/test/resources/parsing/bad_tree/after_meta_1.uss deleted file mode 100644 index f4b62256..00000000 --- a/dsl/src/test/resources/parsing/bad_tree/after_meta_1.uss +++ /dev/null @@ -1,5 +0,0 @@ -@meta_flag -if(1==1){ - @meta_flag - send to %caster message "foo"; -} diff --git a/dsl/src/test/resources/parsing/bad_tree/after_meta_2.uss b/dsl/src/test/resources/parsing/bad_tree/after_meta_2.uss deleted file mode 100644 index b62c339f..00000000 --- a/dsl/src/test/resources/parsing/bad_tree/after_meta_2.uss +++ /dev/null @@ -1,5 +0,0 @@ -@meta_flag -{ - send to %caster message "foo"; -} -@meta_flag diff --git a/dsl/src/test/resources/parsing/bad_tree/after_stop_1.uss b/dsl/src/test/resources/parsing/bad_tree/after_stop_1.uss deleted file mode 100644 index 139cee45..00000000 --- a/dsl/src/test/resources/parsing/bad_tree/after_stop_1.uss +++ /dev/null @@ -1,2 +0,0 @@ -stop; -stop; \ No newline at end of file diff --git a/dsl/src/test/resources/parsing/bad_tree/after_stop_2.uss b/dsl/src/test/resources/parsing/bad_tree/after_stop_2.uss deleted file mode 100644 index 0b7a38ba..00000000 --- a/dsl/src/test/resources/parsing/bad_tree/after_stop_2.uss +++ /dev/null @@ -1,3 +0,0 @@ -send to %caster message "a"; -stop; -send to %caster message "b"; \ No newline at end of file diff --git a/dsl/src/test/resources/parsing/bad_tree/after_stop_3.uss b/dsl/src/test/resources/parsing/bad_tree/after_stop_3.uss deleted file mode 100644 index 9248fcef..00000000 --- a/dsl/src/test/resources/parsing/bad_tree/after_stop_3.uss +++ /dev/null @@ -1,5 +0,0 @@ -@meta_flag -stop; -{ - send to %caster message "foo"; -} \ No newline at end of file diff --git a/dsl/src/test/resources/parsing/bad_type/bad_collection_teleport.uss b/dsl/src/test/resources/parsing/bad_type/bad_collection_teleport.uss deleted file mode 100644 index 1bcf6687..00000000 --- a/dsl/src/test/resources/parsing/bad_type/bad_collection_teleport.uss +++ /dev/null @@ -1,4 +0,0 @@ - -define %coll = all entities within 10 around %caster; - -teleport %caster to %coll; diff --git a/dsl/src/test/resources/parsing/bad_type/bad_list_append.uss b/dsl/src/test/resources/parsing/bad_type/bad_list_append.uss deleted file mode 100644 index 60f785a2..00000000 --- a/dsl/src/test/resources/parsing/bad_type/bad_list_append.uss +++ /dev/null @@ -1,3 +0,0 @@ -%l = [[]]; -%l :+ "a"; -%l :+ true; diff --git a/dsl/src/test/resources/parsing/bad_type/bad_ope.uss b/dsl/src/test/resources/parsing/bad_type/bad_ope.uss deleted file mode 100644 index b7e3807c..00000000 --- a/dsl/src/test/resources/parsing/bad_type/bad_ope.uss +++ /dev/null @@ -1,5 +0,0 @@ -# Valid -define %x = 1 * 2; - -# Not valid -define %z = [[1]] * 2; \ No newline at end of file diff --git a/dsl/src/test/resources/parsing/bad_type/bad_ope_2.uss b/dsl/src/test/resources/parsing/bad_type/bad_ope_2.uss deleted file mode 100644 index 2f815f23..00000000 --- a/dsl/src/test/resources/parsing/bad_type/bad_ope_2.uss +++ /dev/null @@ -1,6 +0,0 @@ -# Valid -define %x = 1 + "1" -define %y = "1" + 1; - -# Not valid -define %z = 1 * "oops"; diff --git a/dsl/src/test/resources/parsing/bad_type/bad_ope_3.uss b/dsl/src/test/resources/parsing/bad_type/bad_ope_3.uss deleted file mode 100644 index d6d21b41..00000000 --- a/dsl/src/test/resources/parsing/bad_type/bad_ope_3.uss +++ /dev/null @@ -1,7 +0,0 @@ -# Valid -%a = true; -%b = !%a; - -# Invalid -%c = 14; -%d = !%c; diff --git a/dsl/src/test/resources/parsing/bad_type/increment_type.uss b/dsl/src/test/resources/parsing/bad_type/increment_type.uss deleted file mode 100644 index f2f8f169..00000000 --- a/dsl/src/test/resources/parsing/bad_type/increment_type.uss +++ /dev/null @@ -1,2 +0,0 @@ -define %i = "a"; -decrement %i; diff --git a/dsl/src/test/resources/parsing/bad_type/redefine_difftype.uss b/dsl/src/test/resources/parsing/bad_type/redefine_difftype.uss deleted file mode 100644 index d13c23cf..00000000 --- a/dsl/src/test/resources/parsing/bad_type/redefine_difftype.uss +++ /dev/null @@ -1,2 +0,0 @@ -define %a = 1; -define %a = "toto"; \ No newline at end of file diff --git a/dsl/src/test/resources/parsing/bad_type/stop_type.uss b/dsl/src/test/resources/parsing/bad_type/stop_type.uss deleted file mode 100644 index f0623a9a..00000000 --- a/dsl/src/test/resources/parsing/bad_type/stop_type.uss +++ /dev/null @@ -1 +0,0 @@ -stop "non"; \ No newline at end of file diff --git a/dsl/src/test/resources/parsing/corrects/blocks/for.uss b/dsl/src/test/resources/parsing/corrects/blocks/for.uss deleted file mode 100644 index abc070ed..00000000 --- a/dsl/src/test/resources/parsing/corrects/blocks/for.uss +++ /dev/null @@ -1,14 +0,0 @@ -for(define %i = 0; %i < 5; increment %i) { - send to %caster message "i=%i"; -} - -%x = 12; -for(; %x < 5; decrement %x) { - send to %caster message "x=%x"; -} - -%z = 8; -for(; %x > 5; ) { - decrement %z; - send to %caster message "z=%z"; -} \ No newline at end of file diff --git a/dsl/src/test/resources/parsing/corrects/blocks/for_break.uss b/dsl/src/test/resources/parsing/corrects/blocks/for_break.uss deleted file mode 100644 index 0c24ebbd..00000000 --- a/dsl/src/test/resources/parsing/corrects/blocks/for_break.uss +++ /dev/null @@ -1,5 +0,0 @@ -for(define %i = 0; %i < 5; increment %i) { - send to %caster message "[%i]"; - if(%i > 3) - break; -} \ No newline at end of file diff --git a/dsl/src/test/resources/parsing/corrects/blocks/foreach.uss b/dsl/src/test/resources/parsing/corrects/blocks/foreach.uss deleted file mode 100644 index d0356410..00000000 --- a/dsl/src/test/resources/parsing/corrects/blocks/foreach.uss +++ /dev/null @@ -1,6 +0,0 @@ -define %around = (all PLAYER within 50 around %caster); - -foreach(%p : %around) { - send to %caster message "Found " + %p; -} -send to %caster message "All = %around"; \ No newline at end of file diff --git a/dsl/src/test/resources/parsing/corrects/blocks/ifelse_p1.uss b/dsl/src/test/resources/parsing/corrects/blocks/ifelse_p1.uss deleted file mode 100644 index f6e36220..00000000 --- a/dsl/src/test/resources/parsing/corrects/blocks/ifelse_p1.uss +++ /dev/null @@ -1,7 +0,0 @@ -define %a = null; -if(%caster == %caster) - define %a = "a"; -else - define %a = "b"; - -send to %caster message %a; \ No newline at end of file diff --git a/dsl/src/test/resources/parsing/corrects/blocks/ifelse_p2.uss b/dsl/src/test/resources/parsing/corrects/blocks/ifelse_p2.uss deleted file mode 100644 index e2c674a3..00000000 --- a/dsl/src/test/resources/parsing/corrects/blocks/ifelse_p2.uss +++ /dev/null @@ -1,20 +0,0 @@ -define %a = 2; -define %even = null; - -if(%a == 0) { - define %even = true; -} else if(%a == 1) { - define %even = false; -} else if(%a == 2) { - define %even = true; -} else if(%a == 3) { - define %even = false; -} else if(%a == 4) { - define %even = true; -} else if(%a == 5) { - define %even = false; -} else { - send to %caster message "trop duuur !"; - stop; -} -send to %caster message "even ? %even"; diff --git a/dsl/src/test/resources/parsing/corrects/blocks/repeat.uss b/dsl/src/test/resources/parsing/corrects/blocks/repeat.uss deleted file mode 100644 index d69744ce..00000000 --- a/dsl/src/test/resources/parsing/corrects/blocks/repeat.uss +++ /dev/null @@ -1,13 +0,0 @@ -repeat after 1s 5 times every 2 seconds: { - send to %caster message "boum 1."; -} - -repeat 2 times every 5 seconds: { - send to %caster message "boum 2."; -} - -define %count = 1 + 1; -define %delay = 3sec; -repeat %count times every %delay: { - send to %caster message "boum 3."; -} diff --git a/dsl/src/test/resources/parsing/corrects/blocks/repeat_2.uss b/dsl/src/test/resources/parsing/corrects/blocks/repeat_2.uss deleted file mode 100644 index 39727800..00000000 --- a/dsl/src/test/resources/parsing/corrects/blocks/repeat_2.uss +++ /dev/null @@ -1,9 +0,0 @@ -repeat after 1s every 2 seconds for 2 m: { - send to %caster message "boum 1."; -} - -%dur = 1 minute; -%freq = 15s; -repeat every %freq for %dur: { - send %caster message "test"; -} diff --git a/dsl/src/test/resources/parsing/corrects/blocks/run_later.uss b/dsl/src/test/resources/parsing/corrects/blocks/run_later.uss deleted file mode 100644 index 37ec5afc..00000000 --- a/dsl/src/test/resources/parsing/corrects/blocks/run_later.uss +++ /dev/null @@ -1,9 +0,0 @@ -send to %caster message "Timer: &a1 minute."; -run after 1 minute: { - send to %caster message "Timer is over."; -} - -define %delay = 3sec; -run after %delay: { - send to %caster message "post 3 secs."; -} diff --git a/dsl/src/test/resources/parsing/corrects/blocks/while.uss b/dsl/src/test/resources/parsing/corrects/blocks/while.uss deleted file mode 100644 index 6bebbaee..00000000 --- a/dsl/src/test/resources/parsing/corrects/blocks/while.uss +++ /dev/null @@ -1,15 +0,0 @@ -define %i = 0; - -while(%i < 10) { - send to %caster message "&a+&f > i=%i"; - increment %i; - if(%i > 100) - continue; -} - -do { - send to %caster message "&c-&f > i=%i"; - decrement %i; -} while(%i > 0); - -send to %caster message "done"; diff --git a/dsl/src/test/resources/parsing/corrects/metadata/param_metadata.uss b/dsl/src/test/resources/parsing/corrects/metadata/param_metadata.uss deleted file mode 100644 index e637dc2b..00000000 --- a/dsl/src/test/resources/parsing/corrects/metadata/param_metadata.uss +++ /dev/null @@ -1,3 +0,0 @@ -@param(test, int) - -define %foo = 3 + %test; diff --git a/dsl/src/test/resources/parsing/corrects/mix/cercle.uss b/dsl/src/test/resources/parsing/corrects/mix/cercle.uss deleted file mode 100644 index dd98fbe4..00000000 --- a/dsl/src/test/resources/parsing/corrects/mix/cercle.uss +++ /dev/null @@ -1,12 +0,0 @@ -define %pos = position of %caster; - -define %pos = %pos + [[0,-1,0]]; -for(define %x = -5; %x <= 5; increment %x) { - for(define %z = -5; %z <= 5; increment %z) { - define %temp = %pos + [[%x, 0, %z]]; - play block at %pos with: {{ - type: MAGMA_BLOCK, - duration: 3 secs - }} - } -} \ No newline at end of file diff --git a/dsl/src/test/resources/parsing/corrects/mix/collections.uss b/dsl/src/test/resources/parsing/corrects/mix/collections.uss deleted file mode 100644 index e1e4bb58..00000000 --- a/dsl/src/test/resources/parsing/corrects/mix/collections.uss +++ /dev/null @@ -1,8 +0,0 @@ -define %msgs = [["a", "b", "c"]]; -send to %caster message %msgs; - -send to %caster message "1st is '" + %msgs[0] + "'"; - -for(define %i = 0; %i < sizeof(%msgs); increment %i) { - send to %caster message "&e MSG[%i] = '%a" + %msgs[%i] + "&e'"; -} diff --git a/dsl/src/test/resources/parsing/corrects/mix/empty.uss b/dsl/src/test/resources/parsing/corrects/mix/empty.uss deleted file mode 100644 index e69de29b..00000000 diff --git a/dsl/src/test/resources/parsing/corrects/mix/implicit_define.uss b/dsl/src/test/resources/parsing/corrects/mix/implicit_define.uss deleted file mode 100644 index 965dd96e..00000000 --- a/dsl/src/test/resources/parsing/corrects/mix/implicit_define.uss +++ /dev/null @@ -1,2 +0,0 @@ -define %a = 1; -%a = 2; \ No newline at end of file diff --git a/dsl/src/test/resources/parsing/corrects/mix/metadata.uss b/dsl/src/test/resources/parsing/corrects/mix/metadata.uss deleted file mode 100644 index 20c60e4d..00000000 --- a/dsl/src/test/resources/parsing/corrects/mix/metadata.uss +++ /dev/null @@ -1,5 +0,0 @@ -@name("a nice spell") -@color("&b") -@param("a", int) - -send to %caster message ""; diff --git a/dsl/src/test/resources/parsing/corrects/mix/null_recovery.uss b/dsl/src/test/resources/parsing/corrects/mix/null_recovery.uss deleted file mode 100644 index 7c825e60..00000000 --- a/dsl/src/test/resources/parsing/corrects/mix/null_recovery.uss +++ /dev/null @@ -1,6 +0,0 @@ -%a = 1; -%a = null; -%a = 1 - -send to %caster message "a = " + %a; - diff --git a/dsl/src/test/resources/parsing/corrects/mix/null_set.uss b/dsl/src/test/resources/parsing/corrects/mix/null_set.uss deleted file mode 100644 index f6e78789..00000000 --- a/dsl/src/test/resources/parsing/corrects/mix/null_set.uss +++ /dev/null @@ -1,7 +0,0 @@ -define %a = 1; -define %b = null; - -if(%b == null) - define %b = 2; - -define %c = %a + %b; diff --git a/dsl/src/test/resources/parsing/corrects/mix/particle_shape.uss b/dsl/src/test/resources/parsing/corrects/mix/particle_shape.uss deleted file mode 100644 index e27159a3..00000000 --- a/dsl/src/test/resources/parsing/corrects/mix/particle_shape.uss +++ /dev/null @@ -1,8 +0,0 @@ -define %pos = position of %caster; -play particle at %pos with: {{ - type: FIRE, - shape: {{ - type: "circle", - radius: 6.5 - }} -}} \ No newline at end of file diff --git a/dsl/src/test/resources/parsing/corrects/mix/test_allof.uss b/dsl/src/test/resources/parsing/corrects/mix/test_allof.uss deleted file mode 100644 index cc68297c..00000000 --- a/dsl/src/test/resources/parsing/corrects/mix/test_allof.uss +++ /dev/null @@ -1,6 +0,0 @@ -define %coll = all entities within 10 around %caster; - -send to %coll message "paf"; - -teleport %coll to %caster; - diff --git a/dsl/src/test/resources/parsing/corrects/mix/test_basic.uss b/dsl/src/test/resources/parsing/corrects/mix/test_basic.uss deleted file mode 100644 index 3aacf6fa..00000000 --- a/dsl/src/test/resources/parsing/corrects/mix/test_basic.uss +++ /dev/null @@ -1,4 +0,0 @@ -send to %caster message "&eT'es trop fort."; -send to %caster effect SPEED 2 for 4s; # valid - -define %truc = -12; diff --git a/dsl/src/test/resources/parsing/corrects/mix/test_complex_tp.uss b/dsl/src/test/resources/parsing/corrects/mix/test_complex_tp.uss deleted file mode 100644 index 33add40c..00000000 --- a/dsl/src/test/resources/parsing/corrects/mix/test_complex_tp.uss +++ /dev/null @@ -1,27 +0,0 @@ -# -- config test # -- config -define %delay = 2 seconds; -define %output = @("world", -50, 100, 50); - -# If monsters around, cancel -if(sizeof(all monsters within 5 around %caster) != 0) { - send to %caster message "&cDes monstres sont trop proches de toi."; - stop; -} - -# Intro -send to %caster message "&bTéléportation vers le &2Stronghold&b..."; -play sound at %caster with: {{ - type: BLOCK_BEACON_ACTIVATE, - pitch: 0.8 -}}; -send to %caster effect slowness 10 for %delay; -send to %caster effect resistance 10 for %delay; - -# Teleport after 5 seconds (sound effect + resistance for falling-damage) -run after %delay: { - teleport %caster to %output; - send to %caster effect resistance 5 for 2s; - play sound at %caster with: {{ - type: ITEM_CHORUS_FRUIT_TELEPORT - }}; -} \ No newline at end of file diff --git a/dsl/src/test/resources/parsing/corrects/mix/test_location_literal.uss b/dsl/src/test/resources/parsing/corrects/mix/test_location_literal.uss deleted file mode 100644 index 5275ac29..00000000 --- a/dsl/src/test/resources/parsing/corrects/mix/test_location_literal.uss +++ /dev/null @@ -1,2 +0,0 @@ -define %a = @("world", 1, 2, 3); -define %b = @("world", 1, -2, 3.5, 5, 5); diff --git a/dsl/src/test/resources/parsing/corrects/mix/test_null.uss b/dsl/src/test/resources/parsing/corrects/mix/test_null.uss deleted file mode 100644 index 7a7a8b28..00000000 --- a/dsl/src/test/resources/parsing/corrects/mix/test_null.uss +++ /dev/null @@ -1,5 +0,0 @@ -define %i = null; - -if(%i == null) { - send to %caster message "a"; -} \ No newline at end of file diff --git a/dsl/src/test/resources/parsing/corrects/mix/test_teleport.uss b/dsl/src/test/resources/parsing/corrects/mix/test_teleport.uss deleted file mode 100644 index 6f912ddd..00000000 --- a/dsl/src/test/resources/parsing/corrects/mix/test_teleport.uss +++ /dev/null @@ -1,6 +0,0 @@ -summon EntityType.PIG as %pig for 4s; - -run after 3900ms: { - send to %caster message "&e&owhoooooooosh"; - teleport %caster to %pig; -} \ No newline at end of file diff --git a/dsl/src/test/resources/parsing/corrects/operators/bool_operators.uss b/dsl/src/test/resources/parsing/corrects/operators/bool_operators.uss deleted file mode 100644 index 74f8342f..00000000 --- a/dsl/src/test/resources/parsing/corrects/operators/bool_operators.uss +++ /dev/null @@ -1,2 +0,0 @@ -%a = 7; -%b = (false || 1 == 1 && (4 >= 2) && !(%a > 10)); \ No newline at end of file diff --git a/dsl/src/test/resources/parsing/corrects/operators/conditions.uss b/dsl/src/test/resources/parsing/corrects/operators/conditions.uss deleted file mode 100644 index 3735c21a..00000000 --- a/dsl/src/test/resources/parsing/corrects/operators/conditions.uss +++ /dev/null @@ -1,13 +0,0 @@ -define %a = 55; -define %b = 56; - -# Nice separation with parenthesis -if((%a == 1) || (%a == 2)) - send to %caster message "A"; - -# No separation -if(%a == 3 || %b == 4) - send to %caster message "A"; - -#if(%a == 33 || true) -# send to %caster message "B"; diff --git a/dsl/src/test/resources/parsing/corrects/operators/list_append.uss b/dsl/src/test/resources/parsing/corrects/operators/list_append.uss deleted file mode 100644 index f47893a1..00000000 --- a/dsl/src/test/resources/parsing/corrects/operators/list_append.uss +++ /dev/null @@ -1,16 +0,0 @@ -# Type not set (i.e. NULL) -%l = [[]]; - -# Append a value to the list. -%l :+ 1; -%l :+ 2; - -# because its an expression... -(%l :+ 12) :+ 27; - -# ":?" == contains -%bool = %l :? 1; # true -%num = sizeof(%l); # 4 - -# ":-" == remove (value) -%l :- 1; diff --git a/dsl/src/test/resources/parsing/corrects/operators/math.uss b/dsl/src/test/resources/parsing/corrects/operators/math.uss deleted file mode 100644 index de5882e8..00000000 --- a/dsl/src/test/resources/parsing/corrects/operators/math.uss +++ /dev/null @@ -1,3 +0,0 @@ -define %c = cos(3.14); -define %s = cos(3.14); -define %t = tan(3.14); diff --git a/dsl/src/test/resources/parsing/corrects/operators/operator_priority.uss b/dsl/src/test/resources/parsing/corrects/operators/operator_priority.uss deleted file mode 100644 index ec147fc4..00000000 --- a/dsl/src/test/resources/parsing/corrects/operators/operator_priority.uss +++ /dev/null @@ -1,11 +0,0 @@ -define %a = 2; -define %b = 3; -define %c = 5; - -define %zz1 = %a + %b + %c; # (a+(b+c)) - -define %zz2 = %a + %b * %c; # (a+(b*c)) - -define %zz3 = %a / %b - %c; # ((a/b)-c) - -define %zz4 = %a / %b - %c; # ((a/b)-c) diff --git a/dsl/src/test/resources/parsing/corrects/operators/parenthesis.uss b/dsl/src/test/resources/parsing/corrects/operators/parenthesis.uss deleted file mode 100644 index 926375be..00000000 --- a/dsl/src/test/resources/parsing/corrects/operators/parenthesis.uss +++ /dev/null @@ -1,6 +0,0 @@ -define %a = 1; -define %b = 2; -define %c = 3; -define %d = 5; - -define %pp1 = %a - (%b + %c) * %d; # (a+(b+c)) diff --git a/dsl/src/test/resources/parsing/corrects/operators/type_operators.uss b/dsl/src/test/resources/parsing/corrects/operators/type_operators.uss deleted file mode 100644 index 52e7645f..00000000 --- a/dsl/src/test/resources/parsing/corrects/operators/type_operators.uss +++ /dev/null @@ -1,5 +0,0 @@ -%a = "1" + 1; -%a = 1 + "1"; - -%dur = 2 minutes * 2; -%n = 2 minutes / 2 minutes; diff --git a/dsl/src/test/resources/parsing/corrects/statements/define.uss b/dsl/src/test/resources/parsing/corrects/statements/define.uss deleted file mode 100644 index 177aef2e..00000000 --- a/dsl/src/test/resources/parsing/corrects/statements/define.uss +++ /dev/null @@ -1,12 +0,0 @@ -# Some declarations -define %as_str = "a"; -define %b = 1; -define %a = 1 + 21 / 3; -define %cc = %a - (%a + %b); - -# Broken-lines : code still valid -define - %z - = 6 - / 2 - ; diff --git a/dsl/src/test/resources/parsing/corrects/statements/give.uss b/dsl/src/test/resources/parsing/corrects/statements/give.uss deleted file mode 100644 index add81e9a..00000000 --- a/dsl/src/test/resources/parsing/corrects/statements/give.uss +++ /dev/null @@ -1,10 +0,0 @@ -give EMERALD to %caster; -give 2 EMERALD to %caster; - -give 3 STONE_AXE to %caster with: {{ - name: "nice &6axe", - lore: [[ - "line 1", - "line 2 !" - ]] -}}; diff --git a/dsl/src/test/resources/parsing/corrects/statements/increment.uss b/dsl/src/test/resources/parsing/corrects/statements/increment.uss deleted file mode 100644 index 56090ecd..00000000 --- a/dsl/src/test/resources/parsing/corrects/statements/increment.uss +++ /dev/null @@ -1,3 +0,0 @@ -define %i = 0; -increment %i; -decrement %i; diff --git a/dsl/src/test/resources/parsing/corrects/statements/play.uss b/dsl/src/test/resources/parsing/corrects/statements/play.uss deleted file mode 100644 index 63ffedb3..00000000 --- a/dsl/src/test/resources/parsing/corrects/statements/play.uss +++ /dev/null @@ -1,17 +0,0 @@ -# Play at '%caster' location - -play PARTICLE at %caster with: {{ - type: lava, - count: 12 -}}; - -play "sound" at %caster with: {{ - type: ENTITY_POLAR_BEAR_WARNING, - volume: 1.1, - pitch: 0.8 -}}; - -play BLOCK at %caster with: {{ - type: MAGMA_BLOCK, - duration: 2 seconds -}}; diff --git a/dsl/src/test/resources/parsing/corrects/statements/send.uss b/dsl/src/test/resources/parsing/corrects/statements/send.uss deleted file mode 100644 index 5a10c889..00000000 --- a/dsl/src/test/resources/parsing/corrects/statements/send.uss +++ /dev/null @@ -1,22 +0,0 @@ -# --- Message - -send to %caster message "Simple message"; - -define %msg = "&cRed message !"; -send to %caster message %msg; - -send to %caster message [["message 1", "message 2", "message 3"]]; - -# --- Effect - -send to %caster effect LEVITATION 2 for 3 seconds; -send to %caster effect POISON for 4 seconds; - -define %dur = 1 minute; -define %pow = 2 + 2; -send to %caster effect "strength" %pow for %dur; - -# --- Attributes - -send to %caster attribute 2 ARMOR for 5 s; -send to %caster attribute %pow "MAX_HEALTH" ADD_NUMBER for %dur; diff --git a/dsl/src/test/resources/parsing/corrects/statements/send_nbt.uss b/dsl/src/test/resources/parsing/corrects/statements/send_nbt.uss deleted file mode 100644 index 2eed25bc..00000000 --- a/dsl/src/test/resources/parsing/corrects/statements/send_nbt.uss +++ /dev/null @@ -1 +0,0 @@ -send %caster nbt "test" = 12 for 12s; \ No newline at end of file diff --git a/dsl/src/test/resources/parsing/corrects/statements/stop_1.uss b/dsl/src/test/resources/parsing/corrects/statements/stop_1.uss deleted file mode 100644 index 28faeb67..00000000 --- a/dsl/src/test/resources/parsing/corrects/statements/stop_1.uss +++ /dev/null @@ -1,2 +0,0 @@ -# Exit with code -stop 3.14; diff --git a/dsl/src/test/resources/parsing/corrects/statements/stop_2.uss b/dsl/src/test/resources/parsing/corrects/statements/stop_2.uss deleted file mode 100644 index 32eff907..00000000 --- a/dsl/src/test/resources/parsing/corrects/statements/stop_2.uss +++ /dev/null @@ -1,2 +0,0 @@ -# Exit normally -stop; diff --git a/dsl/src/test/resources/parsing/corrects/statements/stop_3.uss b/dsl/src/test/resources/parsing/corrects/statements/stop_3.uss deleted file mode 100644 index 99d552aa..00000000 --- a/dsl/src/test/resources/parsing/corrects/statements/stop_3.uss +++ /dev/null @@ -1,3 +0,0 @@ -# Exit with code -define %code = 90/8; -stop %code; diff --git a/dsl/src/test/resources/parsing/corrects/statements/summon.uss b/dsl/src/test/resources/parsing/corrects/statements/summon.uss deleted file mode 100644 index b8a219d2..00000000 --- a/dsl/src/test/resources/parsing/corrects/statements/summon.uss +++ /dev/null @@ -1,9 +0,0 @@ -summon IRON_GOLEM at %caster as %ent for 5 minutes with: {{ - name: "Michel" -}}; - -summon DOLPHIN at %caster for 3 seconds with: {{}}; - -define %type = ZOMBIE; -define %dur = 3 days; -summon %type at %caster for %dur; diff --git a/dsl/src/test/resources/parsing/corrects/statements/teleport.uss b/dsl/src/test/resources/parsing/corrects/statements/teleport.uss deleted file mode 100644 index bac5a143..00000000 --- a/dsl/src/test/resources/parsing/corrects/statements/teleport.uss +++ /dev/null @@ -1,4 +0,0 @@ -teleport %caster to %caster; - -teleport all monsters within 50 around %caster to %caster + [[0,10,0]]; -# same as teleport (all monsters within 50) around %caster to (%caster + [[0,10,0]]); diff --git a/dsl/src/test/resources/parsing/corrects_with_custom/callback.uss b/dsl/src/test/resources/parsing/corrects_with_custom/callback.uss deleted file mode 100644 index 65c9f487..00000000 --- a/dsl/src/test/resources/parsing/corrects_with_custom/callback.uss +++ /dev/null @@ -1,6 +0,0 @@ -summon arrow at %caster as %ar for 5s; - -callback %ar LANDED at %pos: { - send %caster message "landed at %pos."; - teleport %caster to %pos; -} diff --git a/dsl/src/test/resources/parsing/corrects_with_custom/custom.uss b/dsl/src/test/resources/parsing/corrects_with_custom/custom.uss deleted file mode 100644 index 603239cf..00000000 --- a/dsl/src/test/resources/parsing/corrects_with_custom/custom.uss +++ /dev/null @@ -1,4 +0,0 @@ -define %a = 1; -define %b = 2; - -define %res = custom_add(%a, %b); From 0d3d43d6fbe2208531775cf567da3660a8442986 Mon Sep 17 00:00:00 2001 From: "timothe.rosaz" Date: Sun, 2 Nov 2025 12:13:47 +0100 Subject: [PATCH 36/38] Preparation for tests framework, register basic structs --- .../plugin/runner/AbstractSpellRuntime.java | 8 +++- .../runner/structs/ConsoleDefinition.java | 11 ++---- .../runner/structs/ConsoleInstance.java | 4 +- .../runner/structs/EntityDefinition.java | 7 ---- .../extension/ExtensionParsingTests.java | 39 ++----------------- .../extension/ParseAndCompileTest.java | 31 ++++++++++++++- .../extension/VanillaParsingTests.java | 24 ++++++++++++ .../extension}/entities/summon-orb.uss | 0 .../extension}/various/damage.uss | 0 .../extension}/various/entity_set_unset.uss | 0 .../extension}/various/operators.uss | 0 .../extension}/various/repeat.uss | 0 .../extension}/various/strike.uss | 0 .../spells/vanilla/console/console.uss | 1 + .../vanilla}/loops/basic_incr.uss | 0 .../vanilla}/loops/for_break.uss | 0 .../vanilla}/loops/while_breaks.uss | 0 17 files changed, 70 insertions(+), 55 deletions(-) create mode 100644 plugin/src/test/java/fr/jamailun/ultimatespellsystem/extension/VanillaParsingTests.java rename plugin/src/test/resources/{old => spells/extension}/entities/summon-orb.uss (100%) rename plugin/src/test/resources/{old => spells/extension}/various/damage.uss (100%) rename plugin/src/test/resources/{old => spells/extension}/various/entity_set_unset.uss (100%) rename plugin/src/test/resources/{old => spells/extension}/various/operators.uss (100%) rename plugin/src/test/resources/{old => spells/extension}/various/repeat.uss (100%) rename plugin/src/test/resources/{old => spells/extension}/various/strike.uss (100%) create mode 100644 plugin/src/test/resources/spells/vanilla/console/console.uss rename plugin/src/test/resources/{extension-parsing => spells/vanilla}/loops/basic_incr.uss (100%) rename plugin/src/test/resources/{extension-parsing => spells/vanilla}/loops/for_break.uss (100%) rename plugin/src/test/resources/{extension-parsing => spells/vanilla}/loops/while_breaks.uss (100%) diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/AbstractSpellRuntime.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/AbstractSpellRuntime.java index 26ae95a3..dd42c148 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/AbstractSpellRuntime.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/AbstractSpellRuntime.java @@ -3,6 +3,8 @@ import fr.jamailun.ultimatespellsystem.api.runner.*; import fr.jamailun.ultimatespellsystem.api.runner.structs.Struct; import fr.jamailun.ultimatespellsystem.api.spells.Spell; +import fr.jamailun.ultimatespellsystem.plugin.runner.structs.ConsoleDefinition; +import fr.jamailun.ultimatespellsystem.plugin.runner.structs.EntityDefinition; import fr.jamailun.ultimatespellsystem.plugin.runner.structs.StructsLibrary; import lombok.Getter; import org.jetbrains.annotations.Contract; @@ -45,8 +47,12 @@ public abstract class AbstractSpellRuntime implements SpellRuntime { variables = new VariablesSetImpl(); functions = new FunctionsSetImpl(); this.spell = spell; - this.structsLibrary = new StructsLibrary(); + structsLibrary = new StructsLibrary(); inFunction = false; + + // Register base structs + structsLibrary.register(new EntityDefinition()); + structsLibrary.register(new ConsoleDefinition()); } @Override diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/ConsoleDefinition.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/ConsoleDefinition.java index a2511916..51a70c30 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/ConsoleDefinition.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/ConsoleDefinition.java @@ -15,14 +15,9 @@ /** * Definition for the 'console' object. */ -public class ConsoleDefinition extends AbstractStructDefinition { +public class ConsoleDefinition extends AbstractStructDefinition { - private static ConsoleDefinition FLY_INSTANCE = null; - public static @NotNull ConsoleDefinition get() { - if(FLY_INSTANCE == null) - FLY_INSTANCE = new ConsoleDefinition(); - return FLY_INSTANCE; - } + static final ConsoleDefinition INSTANCE = new ConsoleDefinition(); public ConsoleDefinition() { super(ConsoleStruct.NAME); @@ -35,7 +30,7 @@ public ConsoleDefinition() { } @Override - public @NotNull Struct instantiate(Void value) { + public @NotNull Struct instantiate(Object ignored) { return new ConsoleInstance(); } diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/ConsoleInstance.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/ConsoleInstance.java index b8ebef77..237ff450 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/ConsoleInstance.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/ConsoleInstance.java @@ -3,13 +3,13 @@ /** * Structure for the console. */ -public class ConsoleInstance extends AbstractStructInstance { +public class ConsoleInstance extends AbstractStructInstance { /** * Create a new console instance. */ public ConsoleInstance() { - super(ConsoleDefinition.get(), null); + super(ConsoleDefinition.INSTANCE, null); } } diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/EntityDefinition.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/EntityDefinition.java index bb55fd55..90bed182 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/EntityDefinition.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/structs/EntityDefinition.java @@ -24,13 +24,6 @@ */ public class EntityDefinition extends AbstractStructDefinition { - private static EntityDefinition FLY_INSTANCE = null; - public static @NotNull EntityDefinition get() { - if(FLY_INSTANCE == null) - FLY_INSTANCE = new EntityDefinition(); - return FLY_INSTANCE; - } - /** * Create a new definition. */ diff --git a/plugin/src/test/java/fr/jamailun/ultimatespellsystem/extension/ExtensionParsingTests.java b/plugin/src/test/java/fr/jamailun/ultimatespellsystem/extension/ExtensionParsingTests.java index c7338375..70438d3f 100644 --- a/plugin/src/test/java/fr/jamailun/ultimatespellsystem/extension/ExtensionParsingTests.java +++ b/plugin/src/test/java/fr/jamailun/ultimatespellsystem/extension/ExtensionParsingTests.java @@ -1,20 +1,12 @@ package fr.jamailun.ultimatespellsystem.extension; -import fr.jamailun.ultimatespellsystem.api.runner.RuntimeStatement; -import fr.jamailun.ultimatespellsystem.dsl2.errors.UssException; -import fr.jamailun.ultimatespellsystem.plugin.runner.builder.SpellStructure; -import fr.jamailun.ultimatespellsystem.runner.framework.AssertException; -import org.jetbrains.annotations.NotNull; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; -import java.io.File; -import java.util.List; - /** * Multiple tests for valid USS files. */ -public class ExtensionParsingTests extends ParseAndCompileTest { +class ExtensionParsingTests extends ParseAndCompileTest { @BeforeAll static void beforeAll() { @@ -36,32 +28,9 @@ void testEntityTypes() { testFolder("entities", false); } - @Test - void testLoops() { - testFolder("loops", true); - } - private void testFolder(@NotNull String folder, boolean run) { - for(File file : listTests(folder)) { - try { - SpellStructure structure = parseAndVerify(file); - List statements = structure.statements(); - if(run) - cast(statements); - addOk(); - } catch (UssException e) { - e.printStackTrace(); - addFails(file, toString(e)); - } catch (AssertException e) { - System.err.println("Assertion exception ! " + e.getMessage()); - addFails(file, toString(e)); - } catch (Exception e) { - System.err.println("Unexpected error."); - e.printStackTrace(); - addFails(file, toString(e)); - } - } - printResults(); + @Override + protected String baseDir() { + return "extension"; } - } diff --git a/plugin/src/test/java/fr/jamailun/ultimatespellsystem/extension/ParseAndCompileTest.java b/plugin/src/test/java/fr/jamailun/ultimatespellsystem/extension/ParseAndCompileTest.java index 3bdc8a48..f9f06148 100644 --- a/plugin/src/test/java/fr/jamailun/ultimatespellsystem/extension/ParseAndCompileTest.java +++ b/plugin/src/test/java/fr/jamailun/ultimatespellsystem/extension/ParseAndCompileTest.java @@ -1,5 +1,6 @@ package fr.jamailun.ultimatespellsystem.extension; +import fr.jamailun.ultimatespellsystem.api.runner.RuntimeStatement; import fr.jamailun.ultimatespellsystem.dsl2.UltimateSpellSystemDSL2; import fr.jamailun.ultimatespellsystem.dsl2.errors.UssException; import fr.jamailun.ultimatespellsystem.dsl2.nodes.StatementNode; @@ -9,6 +10,7 @@ import fr.jamailun.ultimatespellsystem.dsl2.tokenization.Tokenizer; import fr.jamailun.ultimatespellsystem.plugin.runner.builder.SpellBuilderVisitor; import fr.jamailun.ultimatespellsystem.plugin.runner.builder.SpellStructure; +import fr.jamailun.ultimatespellsystem.runner.framework.AssertException; import fr.jamailun.ultimatespellsystem.runner.framework.TestFramework; import org.jetbrains.annotations.NotNull; import org.junit.jupiter.api.Assertions; @@ -22,10 +24,12 @@ */ abstract class ParseAndCompileTest extends TestFramework { - protected final File PARSINGS_FILE = new File("src/test/resources/extension-parsing"); + protected final File PARSINGS_FILE = new File("src/test/resources/spells"); + + protected abstract String baseDir(); protected @NotNull List listTests(@NotNull String subFolder) { - File directory = new File(PARSINGS_FILE, subFolder); + File directory = new File(new File(PARSINGS_FILE, baseDir()), subFolder); Assertions.assertTrue(directory.exists() && directory.isDirectory(), "Directory '" + subFolder + "' does not exist."); File[] children = directory.listFiles(); @@ -52,6 +56,29 @@ protected void addFails(@NotNull File test, @NotNull String error) { failures.put(test, error); } + protected void testFolder(@NotNull String folder, boolean run) { + for(File file : listTests(folder)) { + try { + SpellStructure structure = parseAndVerify(file); + List statements = structure.statements(); + if(run) + cast(statements); + addOk(); + } catch (UssException e) { + e.printStackTrace(); + addFails(file, toString(e)); + } catch (AssertException e) { + System.err.println("Assertion exception ! " + e.getMessage()); + addFails(file, toString(e)); + } catch (Exception e) { + System.err.println("Unexpected error."); + e.printStackTrace(); + addFails(file, toString(e)); + } + } + printResults(); + } + protected SpellStructure parseAndVerify(@NotNull File file) throws UssException { System.out.println("\n\n ================[ " + file.getName() + "]================\n"); // Tokenize diff --git a/plugin/src/test/java/fr/jamailun/ultimatespellsystem/extension/VanillaParsingTests.java b/plugin/src/test/java/fr/jamailun/ultimatespellsystem/extension/VanillaParsingTests.java new file mode 100644 index 00000000..6a227016 --- /dev/null +++ b/plugin/src/test/java/fr/jamailun/ultimatespellsystem/extension/VanillaParsingTests.java @@ -0,0 +1,24 @@ +package fr.jamailun.ultimatespellsystem.extension; + +import org.junit.jupiter.api.Test; + +/** + * Multiple tests for valid USS files. + */ +class VanillaParsingTests extends ParseAndCompileTest { + + @Test + void testLoops() { + testFolder("loops", true); + } + + @Test + void testConsole() { + testFolder("console", true); + } + + @Override + protected String baseDir() { + return "vanilla"; + } +} diff --git a/plugin/src/test/resources/old/entities/summon-orb.uss b/plugin/src/test/resources/spells/extension/entities/summon-orb.uss similarity index 100% rename from plugin/src/test/resources/old/entities/summon-orb.uss rename to plugin/src/test/resources/spells/extension/entities/summon-orb.uss diff --git a/plugin/src/test/resources/old/various/damage.uss b/plugin/src/test/resources/spells/extension/various/damage.uss similarity index 100% rename from plugin/src/test/resources/old/various/damage.uss rename to plugin/src/test/resources/spells/extension/various/damage.uss diff --git a/plugin/src/test/resources/old/various/entity_set_unset.uss b/plugin/src/test/resources/spells/extension/various/entity_set_unset.uss similarity index 100% rename from plugin/src/test/resources/old/various/entity_set_unset.uss rename to plugin/src/test/resources/spells/extension/various/entity_set_unset.uss diff --git a/plugin/src/test/resources/old/various/operators.uss b/plugin/src/test/resources/spells/extension/various/operators.uss similarity index 100% rename from plugin/src/test/resources/old/various/operators.uss rename to plugin/src/test/resources/spells/extension/various/operators.uss diff --git a/plugin/src/test/resources/old/various/repeat.uss b/plugin/src/test/resources/spells/extension/various/repeat.uss similarity index 100% rename from plugin/src/test/resources/old/various/repeat.uss rename to plugin/src/test/resources/spells/extension/various/repeat.uss diff --git a/plugin/src/test/resources/old/various/strike.uss b/plugin/src/test/resources/spells/extension/various/strike.uss similarity index 100% rename from plugin/src/test/resources/old/various/strike.uss rename to plugin/src/test/resources/spells/extension/various/strike.uss diff --git a/plugin/src/test/resources/spells/vanilla/console/console.uss b/plugin/src/test/resources/spells/vanilla/console/console.uss new file mode 100644 index 00000000..2471d51f --- /dev/null +++ b/plugin/src/test/resources/spells/vanilla/console/console.uss @@ -0,0 +1 @@ +console.info("test"); \ No newline at end of file diff --git a/plugin/src/test/resources/extension-parsing/loops/basic_incr.uss b/plugin/src/test/resources/spells/vanilla/loops/basic_incr.uss similarity index 100% rename from plugin/src/test/resources/extension-parsing/loops/basic_incr.uss rename to plugin/src/test/resources/spells/vanilla/loops/basic_incr.uss diff --git a/plugin/src/test/resources/extension-parsing/loops/for_break.uss b/plugin/src/test/resources/spells/vanilla/loops/for_break.uss similarity index 100% rename from plugin/src/test/resources/extension-parsing/loops/for_break.uss rename to plugin/src/test/resources/spells/vanilla/loops/for_break.uss diff --git a/plugin/src/test/resources/extension-parsing/loops/while_breaks.uss b/plugin/src/test/resources/spells/vanilla/loops/while_breaks.uss similarity index 100% rename from plugin/src/test/resources/extension-parsing/loops/while_breaks.uss rename to plugin/src/test/resources/spells/vanilla/loops/while_breaks.uss From d6729e53f6fd19a429cf87f18c909cf797f7e666 Mon Sep 17 00:00:00 2001 From: "timothe.rosaz" Date: Sun, 9 Nov 2025 13:49:52 +0100 Subject: [PATCH 37/38] Added list operators back to DSLv2 --- .../dsl2/nodes/ExpressionNode.java | 10 +-- .../expressions/operators/BiOperator.java | 12 ++- .../expressions/operators/ListOperator.java | 79 +++++++++++++++++++ .../expressions/operators/MonoOperator.java | 5 +- .../expressions/operators/SizeOfOperator.java | 60 ++++++++++++++ .../dsl2/nodes/type/Type.java | 9 +++ .../dsl2/tokenization/TokenType.java | 6 ++ .../dsl2/tokenization/Tokenizer.java | 5 ++ .../dsl2/visitor/PrintingVisitor.java | 6 +- .../parsing/corrects/arrays/sizeof.uss | 2 + 10 files changed, 181 insertions(+), 13 deletions(-) create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/ListOperator.java create mode 100644 dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/SizeOfOperator.java create mode 100644 dsl2/src/test/resources/parsing/corrects/arrays/sizeof.uss diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/ExpressionNode.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/ExpressionNode.java index 23490d69..14496ec1 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/ExpressionNode.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/ExpressionNode.java @@ -4,10 +4,7 @@ import fr.jamailun.ultimatespellsystem.dsl2.errors.UssException; import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.*; import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.litteral.*; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.operators.BiOperator; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.operators.IncrementExpression; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.operators.NotOperator; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.operators.SubOperator; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.operators.*; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; import fr.jamailun.ultimatespellsystem.dsl2.tokenization.*; import fr.jamailun.ultimatespellsystem.dsl2.visitor.ExpressionVisitor; @@ -100,9 +97,10 @@ protected ExpressionNode(@NotNull TokenPosition position) { case NULL -> new NullLiteral(token.pos()); case CHAR_AT -> LocationLiteral.readNextLocation(tokens); - // Increment / decrement + // Increment / decrement / sizeof case INCREMENT -> IncrementExpression.parseIncrementOrDecrement(tokens, true); case DECREMENT -> IncrementExpression.parseIncrementOrDecrement(tokens, false); + case SIZE_OF -> SizeOfOperator.parseSizeOf(tokens); // Toutes les compositions de // "A.B", "A.B(...)", "A[B]" et "A". @@ -226,7 +224,7 @@ private static ExpressionNode tryConvertMathOperations(ExpressionNode expr, @Not private static @NotNull ExpressionNode tryConvertLogicalExpression(ExpressionNode expr, @NotNull TokenStream tokens, boolean firstLevel) { Token token = tokens.peek(); return switch(token.getType()) { - case OPE_OR, OPE_AND -> { + case OPE_OR, OPE_AND, LIST_ADD, LIST_REM, LIST_REM_INDEX -> { if(!firstLevel) yield expr; tokens.drop(); diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/BiOperator.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/BiOperator.java index ba2691a4..8b76a66d 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/BiOperator.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/BiOperator.java @@ -3,7 +3,6 @@ import fr.jamailun.ultimatespellsystem.dsl2.errors.SyntaxException; import fr.jamailun.ultimatespellsystem.dsl2.nodes.ExpressionNode; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; -import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.variables.TypesContext; import fr.jamailun.ultimatespellsystem.dsl2.tokenization.Token; import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenPosition; @@ -63,6 +62,7 @@ public void visit(@NotNull ExpressionVisitor visitor) { COMP_GE, COMP_GT, COMP_LE, COMP_LT, OPE_AND, OPE_OR -> new LogicalOperator(operand, left, right); + case LIST_ADD, LIST_REM, LIST_REM_INDEX, LIST_CONTAINS -> new ListOperator(operand, left, right); default -> throw new SyntaxException(operand, "Unknown Bi-operator."); }; } @@ -78,14 +78,12 @@ public void visit(@NotNull ExpressionVisitor visitor) { public enum BiOpeType { // Math - ADD, SUB, MUL, DIV, // Logical - EQUAL, NOT_EQUAL, GREATER_OR_EQ, @@ -94,7 +92,13 @@ public enum BiOpeType { LESSER, AND, - OR + OR, + + // List + LIST_ADD, + LIST_REM, + LIST_REM_INDEX, + LIST_CONTAINS } diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/ListOperator.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/ListOperator.java new file mode 100644 index 00000000..f0199b7e --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/ListOperator.java @@ -0,0 +1,79 @@ +package fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.operators; + +import fr.jamailun.ultimatespellsystem.dsl2.errors.TypeException; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.ExpressionNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.ReferenceExpression; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.variables.TypesContext; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.variables.VariableDefinition; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.variables.VariableReference; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.Token; +import org.jetbrains.annotations.NotNull; + +/** + * A list operator. Can be one of a {@link BiOpeType} for lists. + */ +public class ListOperator extends BiOperator { + + private final BiOpeType opeType; + + public ListOperator(@NotNull Token operand, @NotNull ExpressionNode left, @NotNull ExpressionNode right) { + super(operand.pos(), left, right); + opeType = switch (operand.getType()) { + case LIST_ADD -> BiOpeType.LIST_ADD; + case LIST_REM -> BiOpeType.LIST_REM; + case LIST_REM_INDEX -> BiOpeType.LIST_REM_INDEX; + case LIST_CONTAINS -> BiOpeType.LIST_CONTAINS; + default -> throw new RuntimeException("Unreachable."); + }; + } + + @Override + public @NotNull BiOpeType getType() { + return opeType; + } + + @Override + protected void validateTypes(@NotNull Type leftType, @NotNull Type rightType, @NotNull TypesContext context) { + // Left must be a list, right cannot be null. + if(rightType.isNull()) + throw new TypeException(firstTokenPosition(), "Cannot apply an operator with a NULL-typed right operand (" + right + ")"); + if(! leftType.isCollection()) + throw new TypeException(firstTokenPosition(), "A list operator (" + opeType + ") can ONLY be applied on a LIST for the left operand. Left is " + leftType); + + // We can, eventually, help to figure-out what variable + if(opeType != BiOpeType.LIST_REM_INDEX) { + if(left.getExpressionType().isNull()) { + helpCompleteVariable(rightType, context); + } else if( ! leftType.isLike(rightType)) { + throw new TypeException(firstTokenPosition(), "Cannot have heterogeneous lists. List is " + leftType + ", right operand is " + rightType); + } + } + + // if REM_INDEX, right must be numbers + if(opeType == BiOpeType.LIST_REM_INDEX && ! rightType.is(TypePrimitive.NUMBER)) + throw new TypeException(firstTokenPosition(), "A LIST_REM_INDEX operator can only accept a NUMBER for the right operant."); + + // Produced type is either the left side, either a BOOL for the contains operator. + if(opeType == BiOpeType.LIST_CONTAINS) { + producedType = TypePrimitive.BOOLEAN.asType(); + } else { + producedType = leftType; + } + } + + private void helpCompleteVariable(Type rightType, TypesContext context) { + if(left instanceof ReferenceExpression varExpr) { + VariableDefinition var = context.findVariable(varExpr.getVariableName()); + if(var != null) { + var.register(new VariableReference.Constant(rightType.pushArray(), firstTokenPosition())); + } + } + } + + @Override + public String toString() { + return left + " " + opeType + " " + right; + } +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/MonoOperator.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/MonoOperator.java index 03a7e1cb..21e87e0b 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/MonoOperator.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/MonoOperator.java @@ -40,7 +40,7 @@ public void visit(@NotNull ExpressionVisitor visitor) { public final void validateTypes(@NotNull TypesContext context) { child.validateTypes(context); - validateTypes(child.getExpressionType()); + validateTypes(child.getExpressionType()); } /** @@ -50,7 +50,8 @@ public final void validateTypes(@NotNull TypesContext context) { public abstract void validateTypes(@NotNull Type childType); public enum MonoOpeType { - NOT; + NOT, + SIZE_OF } } diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/SizeOfOperator.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/SizeOfOperator.java new file mode 100644 index 00000000..740d9286 --- /dev/null +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/expressions/operators/SizeOfOperator.java @@ -0,0 +1,60 @@ +package fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.operators; + + +import fr.jamailun.ultimatespellsystem.dsl2.errors.TypeException; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.ExpressionNode; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.Type; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.type.TypePrimitive; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.PreviousIndicator; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenPosition; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenStream; +import fr.jamailun.ultimatespellsystem.dsl2.tokenization.TokenType; +import lombok.Getter; +import org.jetbrains.annotations.NotNull; + +/** + * Size of a collection. + */ +@Getter +public class SizeOfOperator extends MonoOperator { + + protected SizeOfOperator(TokenPosition position, ExpressionNode child) { + super(position, child); + } + + @Override + public void validateTypes(@NotNull Type childType) { + // Just needs to be a collection ! + if( ! childType.isCollection()) { + throw new TypeException(this, "A SIZE_OF can only handle collections."); + } + } + + @Override + public @NotNull MonoOpeType getType() { + return MonoOpeType.SIZE_OF; + } + + @Override + public @NotNull Type getExpressionType() { + return TypePrimitive.NUMBER.asType(); + } + + @PreviousIndicator(expected = TokenType.SIZE_OF) + public static @NotNull SizeOfOperator parseSizeOf(@NotNull TokenStream tokens) { + TokenPosition position = tokens.position(); + boolean parenthesis = tokens.dropOptional(TokenType.BRACKET_OPEN); + + ExpressionNode child = ExpressionNode.readNextExpression(tokens); + + if(parenthesis) + tokens.dropOrThrow(TokenType.BRACKET_CLOSE, "Need a parenthesis to close the size-of operator."); + + return new SizeOfOperator(position, child); + } + + @Override + public String toString() { + return "size_of(" + child + ")"; + } +} diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/Type.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/Type.java index 3675ccd6..80d4aa2a 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/Type.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/nodes/type/Type.java @@ -132,4 +132,13 @@ public int hashCode() { TypePrimitive primitive = TypePrimitive.parsePrimitive(name); return primitive == null ? Type.of(name) : Type.of(primitive); } + + /** + * Test if a type is like this one, ignoring array level. + * @param other other object. + * @return true if types are similar. + */ + public boolean isLike(@NotNull Type other) { + return Objects.equals(other.objectClass, objectClass) || Objects.equals(other.primitive, primitive); + } } diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/tokenization/TokenType.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/tokenization/TokenType.java index 4f088f4e..85940207 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/tokenization/TokenType.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/tokenization/TokenType.java @@ -20,6 +20,7 @@ public enum TokenType { OPE_NOT, // ! INCREMENT, // ++ DECREMENT, // -- + SIZE_OF(true), // sizeof() // Others COLON, // : @@ -45,6 +46,11 @@ public enum TokenType { OPE_AND, // '&&' OPE_OR, // '||' + LIST_ADD, // :+ + LIST_REM, // :- + LIST_REM_INDEX, // :/ + LIST_CONTAINS, // :? + // == KEYWORDS CHAR_AT, // @ diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/tokenization/Tokenizer.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/tokenization/Tokenizer.java index f8319a2e..fa6dbe54 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/tokenization/Tokenizer.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/tokenization/Tokenizer.java @@ -48,6 +48,11 @@ public final class Tokenizer { OPERATORS_BI.put("++", TokenType.INCREMENT); OPERATORS_BI.put("--", TokenType.DECREMENT); + OPERATORS_BI.put(":+", TokenType.LIST_ADD); + OPERATORS_BI.put(":-", TokenType.LIST_REM); + OPERATORS_BI.put(":/", TokenType.LIST_REM_INDEX); + OPERATORS_BI.put(":?", TokenType.LIST_CONTAINS); + // words Arrays.stream(TokenType.values()) .filter(t -> t.letters) diff --git a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/PrintingVisitor.java b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/PrintingVisitor.java index fc9f020a..db003ac7 100644 --- a/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/PrintingVisitor.java +++ b/dsl2/src/main/java/fr/jamailun/ultimatespellsystem/dsl2/visitor/PrintingVisitor.java @@ -7,6 +7,7 @@ import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.operators.BiOperator; import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.operators.IncrementExpression; import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.operators.MonoOperator; +import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.operators.SizeOfOperator; import fr.jamailun.ultimatespellsystem.dsl2.nodes.statements.*; import fr.jamailun.ultimatespellsystem.dsl2.nodes.statements.blocks.ForLoopStatement; import fr.jamailun.ultimatespellsystem.dsl2.nodes.statements.blocks.IfElseStatement; @@ -179,7 +180,6 @@ public void handleIncrementDecrement(@NotNull IncrementExpression expression) { } } - @Override public void handleSimpleExpression(@NotNull SimpleExpressionStatement statement) { builder.append("{"); @@ -318,6 +318,10 @@ public void handleBiOperator(@NotNull BiOperator operator) { case LESSER -> "<"; case AND -> "and"; case OR -> "or"; + case LIST_ADD -> ":+"; + case LIST_REM -> ":-"; + case LIST_REM_INDEX -> ":/"; + case LIST_CONTAINS -> ":?"; }; builder.append(" ").append(ope).append(" "); operator.getRight().visit(this); diff --git a/dsl2/src/test/resources/parsing/corrects/arrays/sizeof.uss b/dsl2/src/test/resources/parsing/corrects/arrays/sizeof.uss new file mode 100644 index 00000000..2657ac40 --- /dev/null +++ b/dsl2/src/test/resources/parsing/corrects/arrays/sizeof.uss @@ -0,0 +1,2 @@ +var truc = ["a", "b"]; +int size = size_of(truc); From c39e52f9ab113d882811394f8db71e2cc643bc14 Mon Sep 17 00:00:00 2001 From: "timothe.rosaz" Date: Sun, 9 Nov 2025 14:05:54 +0100 Subject: [PATCH 38/38] Added list operators back to plugin runner --- .../runner/builder/ExpressionQueue.java | 16 ++++-- .../runner/nodes/operators/RunSizeofOpe.java | 30 +++++++++++ .../nodes/operators/list/ListOperator.java | 54 +++++++++++++++++++ .../nodes/operators/list/RunListAddOpe.java | 31 +++++++++++ .../operators/list/RunListContainsOpe.java | 33 ++++++++++++ .../operators/list/RunListRemIndexOpe.java | 30 +++++++++++ .../nodes/operators/list/RunListRemOpe.java | 31 +++++++++++ 7 files changed, 222 insertions(+), 3 deletions(-) create mode 100644 plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/RunSizeofOpe.java create mode 100644 plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/list/ListOperator.java create mode 100644 plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/list/RunListAddOpe.java create mode 100644 plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/list/RunListContainsOpe.java create mode 100644 plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/list/RunListRemIndexOpe.java create mode 100644 plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/list/RunListRemOpe.java diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/builder/ExpressionQueue.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/builder/ExpressionQueue.java index e7ef587a..9c7153fe 100644 --- a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/builder/ExpressionQueue.java +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/builder/ExpressionQueue.java @@ -17,6 +17,10 @@ import fr.jamailun.ultimatespellsystem.dsl2.nodes.expressions.operators.MonoOperator; import fr.jamailun.ultimatespellsystem.dsl2.visitor.ExpressionVisitor; import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.expressions.*; +import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.operators.list.RunListAddOpe; +import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.operators.list.RunListContainsOpe; +import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.operators.list.RunListRemIndexOpe; +import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.operators.list.RunListRemOpe; import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.operators.objects.ArrayGetNode; import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.operators.objects.GlobalFunctionCallNode; import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.operators.objects.StructFieldGetNode; @@ -119,15 +123,21 @@ public void handleBiOperator(@NotNull BiOperator operator) { case LESSER -> new RunCompOpe(left, right, false, false); case AND -> new RunAndOrOpe(left, right, true); case OR -> new RunAndOrOpe(left, right, false); + case LIST_ADD -> new RunListAddOpe(left, right); + case LIST_REM -> new RunListRemOpe(left, right); + case LIST_REM_INDEX -> new RunListRemIndexOpe(left, right); + case LIST_CONTAINS -> new RunListContainsOpe(left, right); }); } @Override public void handleMonoOperator(@NotNull MonoOperator operator) { RuntimeExpression child = evaluate(operator.getChild()); - if(operator.getType() == MonoOperator.MonoOpeType.NOT) { - add(new RunNotOpe(child)); - } + RuntimeMonoOperator expr = switch (operator.getType()) { + case NOT -> new RunNotOpe(child); + case SIZE_OF -> new RunSizeofOpe(child); + }; + add(expr); } @Override diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/RunSizeofOpe.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/RunSizeofOpe.java new file mode 100644 index 00000000..c97cfe42 --- /dev/null +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/RunSizeofOpe.java @@ -0,0 +1,30 @@ +package fr.jamailun.ultimatespellsystem.plugin.runner.nodes.operators; + +import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; +import fr.jamailun.ultimatespellsystem.api.runner.errors.UnreachableRuntimeException; +import org.jetbrains.annotations.NotNull; + +import java.util.Collection; + +/** + * Sizeof-operator + */ +public final class RunSizeofOpe extends RuntimeMonoOperator { + + public RunSizeofOpe(@NotNull RuntimeExpression child) { + super(child); + } + + @Override + protected @NotNull Object evaluate(@NotNull Object value) { + if(value instanceof Collection coll) { + return coll.size(); + } + throw new UnreachableRuntimeException("Unexpected type for SIZE_OF-operator : " + value + " | " + value.getClass()); + } + + @Override + public @NotNull String toString() { + return "size_of(" + child + ")"; + } +} diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/list/ListOperator.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/list/ListOperator.java new file mode 100644 index 00000000..0e908d8c --- /dev/null +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/list/ListOperator.java @@ -0,0 +1,54 @@ +package fr.jamailun.ultimatespellsystem.plugin.runner.nodes.operators.list; + +import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; +import fr.jamailun.ultimatespellsystem.api.runner.errors.UnreachableRuntimeException; +import fr.jamailun.ultimatespellsystem.plugin.runner.nodes.operators.RuntimeBiOperator; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * Specialized bi-operator for list. + */ +public abstract class ListOperator extends RuntimeBiOperator { + + public ListOperator(@NotNull RuntimeExpression left, @NotNull RuntimeExpression right) { + super(left, right); + } + + /** + * Evaluate with a list. + * @param collection list of objects. + * @param arg argument of the operator. + * @return something, according to the operator. + */ + protected abstract Object evaluateList(@NotNull Collection collection, Object arg); + + @Override + @SuppressWarnings("unchecked") + protected final Object evaluate(Object left, Object right) { + if(!(left instanceof Collection list)) + throw new UnreachableRuntimeException("Cannot have a left non-list: " + left); + + List listObj = (List) list; + return evaluateList(listObj, right); + } + + /** + * Transform a single element or a collection (or a {@code null} value into a collection). + * @param object object to handle. + * @return a non-null collection. + */ + protected @NotNull Collection elementAsCollection(@Nullable Object object) { + if(object instanceof Collection coll) { + return new HashSet<>(coll); + } + if(object == null) + return new HashSet<>(); + return Set.of(object); + } +} diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/list/RunListAddOpe.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/list/RunListAddOpe.java new file mode 100644 index 00000000..fa45b1dd --- /dev/null +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/list/RunListAddOpe.java @@ -0,0 +1,31 @@ +package fr.jamailun.ultimatespellsystem.plugin.runner.nodes.operators.list; + +import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; +import org.jetbrains.annotations.NotNull; + +import java.util.Collection; + +/** + * "Append" operation on a collection. + */ +public class RunListAddOpe extends ListOperator { + + public RunListAddOpe(@NotNull RuntimeExpression left, @NotNull RuntimeExpression right) { + super(left, right); + } + + @Override + protected Object evaluateList(@NotNull Collection collection, Object arg) { + // Can add either another collection or a single element. + Collection allOthers = elementAsCollection(arg); + + // Append values + collection.addAll(allOthers); + return collection; + } + + @Override + public String toString() { + return leftExpression +".add(" + rightExpression + ")"; + } +} diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/list/RunListContainsOpe.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/list/RunListContainsOpe.java new file mode 100644 index 00000000..230795aa --- /dev/null +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/list/RunListContainsOpe.java @@ -0,0 +1,33 @@ +package fr.jamailun.ultimatespellsystem.plugin.runner.nodes.operators.list; + +import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; +import org.jetbrains.annotations.NotNull; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +/** + * Test if a collection contains an element. + */ +public class RunListContainsOpe extends ListOperator { + + public RunListContainsOpe(@NotNull RuntimeExpression left, @NotNull RuntimeExpression right) { + super(left, right); + } + + @Override + protected Object evaluateList(@NotNull Collection collection, Object arg) { + Set hashedList = new HashSet<>(collection); + + if(arg instanceof Collection others) { + return hashedList.containsAll(new HashSet<>(others)); + } + return hashedList.contains(arg); + } + + @Override + public String toString() { + return leftExpression + ".contains(" + rightExpression + ")"; + } +} diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/list/RunListRemIndexOpe.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/list/RunListRemIndexOpe.java new file mode 100644 index 00000000..067f35c2 --- /dev/null +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/list/RunListRemIndexOpe.java @@ -0,0 +1,30 @@ +package fr.jamailun.ultimatespellsystem.plugin.runner.nodes.operators.list; + +import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; +import fr.jamailun.ultimatespellsystem.api.runner.errors.UnreachableRuntimeException; +import org.jetbrains.annotations.NotNull; + +import java.util.Collection; + +/** + * "Remove" operation on a collection, by index. + */ +public class RunListRemIndexOpe extends ListOperator { + + public RunListRemIndexOpe(@NotNull RuntimeExpression left, @NotNull RuntimeExpression right) { + super(left, right); + } + + @Override + protected Object evaluateList(@NotNull Collection collection, Object arg) { + if(!(arg instanceof Number index)) + throw new UnreachableRuntimeException("Cannot have a right non-number: " + arg); + collection.remove(index.intValue()); + return arg; + } + + @Override + public String toString() { + return leftExpression + ".remove_idx(" + rightExpression + ")"; + } +} diff --git a/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/list/RunListRemOpe.java b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/list/RunListRemOpe.java new file mode 100644 index 00000000..4ca7780a --- /dev/null +++ b/plugin/src/main/java/fr/jamailun/ultimatespellsystem/plugin/runner/nodes/operators/list/RunListRemOpe.java @@ -0,0 +1,31 @@ +package fr.jamailun.ultimatespellsystem.plugin.runner.nodes.operators.list; + +import fr.jamailun.ultimatespellsystem.api.runner.RuntimeExpression; +import org.jetbrains.annotations.NotNull; + +import java.util.Collection; + +/** + * "Remove" operation on a collection. + */ +public class RunListRemOpe extends ListOperator { + + public RunListRemOpe(@NotNull RuntimeExpression left, @NotNull RuntimeExpression right) { + super(left, right); + } + + @Override + protected Object evaluateList(@NotNull Collection collection, Object arg) { + // Can add either another collection or a single element. + Collection allOthers = elementAsCollection(arg); + + // Append values + collection.addAll(allOthers); + return collection; + } + + @Override + public String toString() { + return leftExpression +".remove(" + rightExpression + ")"; + } +}