├── MuaInterpreter ├── .classpath ├── .project ├── .settings │ └── org.eclipse.jdt.core.prefs ├── bin │ └── mua │ │ ├── Data$Type.class │ │ ├── Data.class │ │ ├── DataGenerator$ExpressionProcessor$1.class │ │ ├── DataGenerator$ExpressionProcessor$2.class │ │ ├── DataGenerator$ExpressionProcessor.class │ │ ├── DataGenerator.class │ │ ├── DataOperationStack$ArgsNumRecord.class │ │ ├── DataOperationStack.class │ │ ├── FunctionHandler.class │ │ ├── Main.class │ │ ├── NameSpace$1.class │ │ ├── NameSpace.class │ │ ├── WordCtrler$LineCtrler.class │ │ ├── WordCtrler.class │ │ ├── error │ │ ├── MuaError.class │ │ ├── NameError.class │ │ ├── SyntaxError.class │ │ ├── TypeError.class │ │ └── ValueError.class │ │ └── operation │ │ ├── ButfirstOp.class │ │ ├── ButlastOp.class │ │ ├── ErallOp.class │ │ ├── EraseOp.class │ │ ├── ExportOp.class │ │ ├── FirstOp.class │ │ ├── IOperation.class │ │ ├── IfOp.class │ │ ├── IntOp.class │ │ ├── IsboolOp.class │ │ ├── IsemptyOp.class │ │ ├── IslistOp.class │ │ ├── IsnameOp.class │ │ ├── IsnumberOp.class │ │ ├── IswordOp.class │ │ ├── JoinOp.class │ │ ├── LastOp.class │ │ ├── ListOp.class │ │ ├── LoadOp.class │ │ ├── MakeOp.class │ │ ├── Operation.class │ │ ├── OperationHandler$1.class │ │ ├── OperationHandler.class │ │ ├── OutputOp.class │ │ ├── PoallOp.class │ │ ├── PrintOp.class │ │ ├── RandomOp.class │ │ ├── ReadOp.class │ │ ├── ReadlistOp.class │ │ ├── RepeatOp.class │ │ ├── SaveOp.class │ │ ├── SentenceOp.class │ │ ├── SqrtOp.class │ │ ├── ThingOp.class │ │ ├── WaitOp.class │ │ ├── WordOp.class │ │ └── operator │ │ ├── AddOp.class │ │ ├── AndOp.class │ │ ├── DivOp.class │ │ ├── EqOp.class │ │ ├── GtOp.class │ │ ├── LtOp.class │ │ ├── ModOp.class │ │ ├── MulOp.class │ │ ├── NotOp.class │ │ ├── Operator.class │ │ ├── OrOp.class │ │ └── SubOp.class └── src │ └── mua │ ├── Data.java │ ├── DataGenerator.java │ ├── DataOperationStack.java │ ├── FunctionHandler.java │ ├── Main.java │ ├── NameSpace.java │ ├── WordCtrler.java │ ├── error │ ├── MuaError.java │ ├── NameError.java │ ├── SyntaxError.java │ ├── TypeError.java │ └── ValueError.java │ └── operation │ ├── ButfirstOp.java │ ├── ButlastOp.java │ ├── ErallOp.java │ ├── EraseOp.java │ ├── ExportOp.java │ ├── FirstOp.java │ ├── IOperation.java │ ├── IfOp.java │ ├── IntOp.java │ ├── IsboolOp.java │ ├── IsemptyOp.java │ ├── IslistOp.java │ ├── IsnameOp.java │ ├── IsnumberOp.java │ ├── IswordOp.java │ ├── JoinOp.java │ ├── LastOp.java │ ├── ListOp.java │ ├── LoadOp.java │ ├── MakeOp.java │ ├── Operation.java │ ├── OperationHandler.java │ ├── OutputOp.java │ ├── PoallOp.java │ ├── PrintOp.java │ ├── RandomOp.java │ ├── ReadOp.java │ ├── ReadlistOp.java │ ├── RepeatOp.java │ ├── SaveOp.java │ ├── SentenceOp.java │ ├── SqrtOp.java │ ├── ThingOp.java │ ├── WaitOp.java │ ├── WordOp.java │ └── operator │ ├── AddOp.java │ ├── AndOp.java │ ├── DivOp.java │ ├── EqOp.java │ ├── GtOp.java │ ├── LtOp.java │ ├── ModOp.java │ ├── MulOp.java │ ├── NotOp.java │ ├── Operator.java │ ├── OrOp.java │ └── SubOp.java ├── README.md ├── README.pdf ├── mua.jar ├── readme_images ├── add_sub_mul_div_mod_demo.png ├── and_or_demo.png ├── bool_demo.png ├── butfirst_butlast_demo.png ├── colon_demo.png ├── demo_exp_bool.png ├── demo_exp_number1.png ├── demo_exp_number2.png ├── demo_export.png ├── demo_function_call.png ├── demo_function_definition.png ├── demo_output.png ├── demo_repeat.png ├── demo_stop.png ├── eq_demo.png ├── erase_demo.png ├── error_name1.png ├── error_name2.png ├── error_name3.png ├── error_syntax1.png ├── error_syntax2.png ├── error_syntax3.png ├── error_syntax4.png ├── error_syntax5.png ├── error_syntax6.png ├── error_type1.png ├── error_type2.png ├── error_value.png ├── fact_recursive.png ├── first_last_demo.png ├── gt_lt_demo.png ├── if_demo.png ├── infix_sentence_demo.png ├── int_demo.png ├── is_type_demo.png ├── isempty_demo.png ├── isname_demo.png ├── join_demo.png ├── list_demo.png ├── list_op_demo.png ├── load_not_exist_demo.png ├── make_demo.png ├── modification_colon.png ├── namespace_op_demo.png ├── namespace_op_demo2.png ├── not_demo.png ├── number_demo.png ├── operation_implement_empty_stack_print.png ├── operation_implement_exp_haskell_infix.png ├── operation_implement_exp_mua_infix.png ├── operation_implement_exp_sugar.png ├── operation_implement_exp_sugar_complex.png ├── operation_implement_function1.png ├── operation_implement_function2.png ├── operation_implement_repeat.png ├── ori_names_demo.png ├── print_demo.png ├── qsort_demo_1.png ├── qsort_demo_2.png ├── random_demo.png ├── read_demo.png ├── readlist_demo.png ├── sample_fact1.png ├── sample_fact2.png ├── sample_fact_equal.png ├── sample_inside_function_binding.png ├── sample_inside_function_call.png ├── sample_inside_function_call2.png ├── sample_inside_function_definition.png ├── sample_inside_function_definition2.png ├── sample_inside_function_equal.png ├── sentence_demo.png ├── sqrt_demo.png ├── thing_demo.png ├── util_content.png ├── util_instruction.png ├── wait_demo_1.png ├── wait_demo_2.png ├── word_demo.png └── word_op_demo.png └── util /MuaInterpreter/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /MuaInterpreter/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | MuaInterpreter 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /MuaInterpreter/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 4 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve 5 | org.eclipse.jdt.core.compiler.compliance=1.8 6 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate 7 | org.eclipse.jdt.core.compiler.debug.localVariable=generate 8 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate 9 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 10 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 11 | org.eclipse.jdt.core.compiler.source=1.8 12 | -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/Data$Type.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/Data$Type.class -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/Data.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/Data.class -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/DataGenerator$ExpressionProcessor$1.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/DataGenerator$ExpressionProcessor$1.class -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/DataGenerator$ExpressionProcessor$2.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/DataGenerator$ExpressionProcessor$2.class -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/DataGenerator$ExpressionProcessor.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/DataGenerator$ExpressionProcessor.class -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/DataGenerator.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/DataGenerator.class -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/DataOperationStack$ArgsNumRecord.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/DataOperationStack$ArgsNumRecord.class -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/DataOperationStack.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/DataOperationStack.class -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/FunctionHandler.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/FunctionHandler.class -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/Main.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/Main.class -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/NameSpace$1.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/NameSpace$1.class -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/NameSpace.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/NameSpace.class -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/WordCtrler$LineCtrler.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/WordCtrler$LineCtrler.class -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/WordCtrler.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/WordCtrler.class -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/error/MuaError.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/error/MuaError.class -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/error/NameError.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/error/NameError.class -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/error/SyntaxError.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/error/SyntaxError.class -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/error/TypeError.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/error/TypeError.class -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/error/ValueError.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/error/ValueError.class -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/operation/ButfirstOp.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/operation/ButfirstOp.class -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/operation/ButlastOp.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/operation/ButlastOp.class -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/operation/ErallOp.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/operation/ErallOp.class -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/operation/EraseOp.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/operation/EraseOp.class -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/operation/ExportOp.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/operation/ExportOp.class -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/operation/FirstOp.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/operation/FirstOp.class -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/operation/IOperation.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/operation/IOperation.class -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/operation/IfOp.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/operation/IfOp.class -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/operation/IntOp.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/operation/IntOp.class -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/operation/IsboolOp.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/operation/IsboolOp.class -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/operation/IsemptyOp.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/operation/IsemptyOp.class -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/operation/IslistOp.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/operation/IslistOp.class -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/operation/IsnameOp.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/operation/IsnameOp.class -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/operation/IsnumberOp.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/operation/IsnumberOp.class -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/operation/IswordOp.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/operation/IswordOp.class -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/operation/JoinOp.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/operation/JoinOp.class -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/operation/LastOp.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/operation/LastOp.class -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/operation/ListOp.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/operation/ListOp.class -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/operation/LoadOp.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/operation/LoadOp.class -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/operation/MakeOp.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/operation/MakeOp.class -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/operation/Operation.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/operation/Operation.class -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/operation/OperationHandler$1.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/operation/OperationHandler$1.class -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/operation/OperationHandler.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/operation/OperationHandler.class -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/operation/OutputOp.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/operation/OutputOp.class -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/operation/PoallOp.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/operation/PoallOp.class -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/operation/PrintOp.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/operation/PrintOp.class -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/operation/RandomOp.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/operation/RandomOp.class -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/operation/ReadOp.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/operation/ReadOp.class -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/operation/ReadlistOp.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/operation/ReadlistOp.class -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/operation/RepeatOp.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/operation/RepeatOp.class -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/operation/SaveOp.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/operation/SaveOp.class -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/operation/SentenceOp.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/operation/SentenceOp.class -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/operation/SqrtOp.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/operation/SqrtOp.class -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/operation/ThingOp.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/operation/ThingOp.class -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/operation/WaitOp.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/operation/WaitOp.class -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/operation/WordOp.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/operation/WordOp.class -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/operation/operator/AddOp.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/operation/operator/AddOp.class -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/operation/operator/AndOp.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/operation/operator/AndOp.class -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/operation/operator/DivOp.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/operation/operator/DivOp.class -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/operation/operator/EqOp.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/operation/operator/EqOp.class -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/operation/operator/GtOp.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/operation/operator/GtOp.class -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/operation/operator/LtOp.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/operation/operator/LtOp.class -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/operation/operator/ModOp.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/operation/operator/ModOp.class -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/operation/operator/MulOp.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/operation/operator/MulOp.class -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/operation/operator/NotOp.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/operation/operator/NotOp.class -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/operation/operator/Operator.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/operation/operator/Operator.class -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/operation/operator/OrOp.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/operation/operator/OrOp.class -------------------------------------------------------------------------------- /MuaInterpreter/bin/mua/operation/operator/SubOp.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/MuaInterpreter/bin/mua/operation/operator/SubOp.class -------------------------------------------------------------------------------- /MuaInterpreter/src/mua/Data.java: -------------------------------------------------------------------------------- 1 | package mua; 2 | 3 | import java.util.Vector; 4 | 5 | import mua.error.*; 6 | 7 | public class Data { 8 | 9 | public enum Type { 10 | UNDEFINED, NUMBER, WORD, LIST, BOOL, OP 11 | // UNDFINED: Used to mark an uninitialized data. 12 | // OP: Includes operation, function, parameter, stores in wordValue. 13 | } 14 | 15 | private Type type = Type.UNDEFINED; 16 | private double numberValue; 17 | private String wordValue; 18 | private Vector listValue; 19 | private boolean boolValue; 20 | 21 | public Data(String literal, Object o) throws MuaError 22 | { // Object o is used for distinguishing constructor from literal and string. 23 | if (literal == null || literal.isEmpty()) { 24 | return; 25 | } 26 | char firstChar = literal.charAt(0); 27 | if (firstChar == '-' || ('0' <= firstChar && firstChar <= '9')) { 28 | asNumber(literal); 29 | } else if (firstChar == '"') { 30 | asWord(literal); 31 | } else if (firstChar == ':' && literal.length() == 1) { 32 | throw new SyntaxError(":", "colon shall not appear by itself"); 33 | } else if (literal.equals("true") || literal.equals("false")) { 34 | asBool(literal); 35 | } else if (literal.equals("[")) { 36 | type = Type.LIST; 37 | listValue = new Vector(); 38 | } else { 39 | asOp(literal); 40 | } 41 | } 42 | 43 | public Data(Data data) { 44 | copy(data); 45 | } 46 | 47 | public Data(double numberValue) { 48 | type = Type.NUMBER; 49 | this.numberValue = numberValue; 50 | } 51 | 52 | public Data(boolean boolValue) { 53 | type = Type.BOOL; 54 | this.boolValue = boolValue; 55 | } 56 | 57 | public Data(String wordValue) { 58 | if (wordValue == null) { 59 | return; 60 | } 61 | type = Type.WORD; 62 | this.wordValue = wordValue; 63 | } 64 | 65 | public Data(Vector listValue) { 66 | if (listValue == null) { 67 | return; 68 | } 69 | type = Type.LIST; 70 | this.listValue = listValue; 71 | } 72 | 73 | public Type getType() { 74 | return type; 75 | } 76 | 77 | public String getTypeString() { 78 | return type.name().toLowerCase(); 79 | } 80 | 81 | public double getNumberValue() throws TypeError { 82 | if (type != Type.NUMBER) { 83 | throw new TypeError(this, "not a number"); 84 | } 85 | return numberValue; 86 | } 87 | 88 | public String getWordValue() throws TypeError { 89 | if (type != Type.WORD) { 90 | throw new TypeError(this, "not a word"); 91 | } 92 | return wordValue; 93 | } 94 | 95 | public String getOpValue() throws TypeError { 96 | if (type != Type.OP) { 97 | throw new TypeError(this, "not an operation"); 98 | } 99 | return wordValue; 100 | } 101 | 102 | public Vector getListValue() throws TypeError { 103 | if (type != Type.LIST) { 104 | throw new TypeError(this, "not a list"); 105 | } 106 | return listValue; 107 | } 108 | 109 | public boolean getBoolValue() throws TypeError { 110 | if (type != Type.BOOL) { 111 | throw new TypeError(this, "not a bool"); 112 | } 113 | return boolValue; 114 | } 115 | 116 | public void copy(Data data) { 117 | if (data == null) { 118 | return; 119 | } 120 | type = data.type; 121 | numberValue = data.numberValue; 122 | wordValue = data.wordValue; 123 | listValue = data.listValue; 124 | boolValue = data.boolValue; 125 | } 126 | 127 | public boolean addListItem(Data data) throws MuaError { 128 | if (type != Type.LIST || listValue == null) { 129 | throw new TypeError(this, "not a list"); 130 | } 131 | if (data == null) { 132 | return false; 133 | } 134 | return listValue.add(data); // TODO WHETHER NEW NEEDED CHANGE 135 | } 136 | 137 | public boolean addListItem(String literal) throws MuaError { 138 | if (type != Type.LIST || listValue == null) { 139 | throw new TypeError(this, "not a list"); 140 | } 141 | if (literal == null || literal.isEmpty()) { 142 | return false; 143 | } 144 | return listValue.add(new Data(literal, null)); 145 | } 146 | 147 | @Override 148 | public String toString() { 149 | switch (type) { 150 | case BOOL: 151 | return boolValue ? "true" : "false"; 152 | case NUMBER: 153 | return Double.toString(numberValue); 154 | case OP: 155 | return wordValue; 156 | case WORD: 157 | return "\"" + wordValue; 158 | case LIST: 159 | return listValueToString().toString(); 160 | default: 161 | return "undefined"; 162 | } 163 | } 164 | 165 | private StringBuffer listValueToString() { 166 | StringBuffer listStringBuffer = new StringBuffer("[ "); 167 | for (Data listItem: listValue) { 168 | listStringBuffer.append(listItem.toString()); 169 | listStringBuffer.append(' '); 170 | } 171 | listStringBuffer.append(']'); 172 | return listStringBuffer; 173 | } 174 | 175 | @Override 176 | public boolean equals(Object o) { 177 | if (this == o) { 178 | return true; 179 | } 180 | if (o == null || o.getClass() != getClass()) { 181 | return false; 182 | } 183 | Data dataObject = (Data)o; 184 | if (type != dataObject.type) { 185 | return false; 186 | } 187 | switch (type) { 188 | case BOOL: 189 | return boolValue == dataObject.boolValue; 190 | case NUMBER: 191 | return numberValue == dataObject.numberValue; 192 | case OP: 193 | case WORD: 194 | return wordValue.equals(dataObject.wordValue); 195 | case LIST: 196 | return listValue.equals(dataObject.listValue); 197 | default: 198 | return false; 199 | } 200 | } 201 | 202 | // Functions asTypes are used for initializing the data to the corresponding type. 203 | private double asNumber(String literal) throws SyntaxError { 204 | type = Type.NUMBER; 205 | try { 206 | numberValue = Double.parseDouble(literal); 207 | } catch (Exception e) { 208 | throw new SyntaxError(literal, "illegal number literal"); 209 | } 210 | return numberValue; 211 | } 212 | 213 | private String asWord(String literal) throws SyntaxError { 214 | type = Type.WORD; 215 | String tempWordValue = literal.substring(1); 216 | if (!isLegalWord(tempWordValue)) { 217 | throw new SyntaxError(literal, "illegal word literal"); 218 | } 219 | wordValue = tempWordValue; 220 | return wordValue; 221 | } 222 | 223 | private String asOp(String literal) throws SyntaxError { 224 | type = Type.OP; 225 | if (!isLegalOp(literal)) { 226 | throw new SyntaxError(literal, "illegal operation name"); 227 | } 228 | wordValue = literal; 229 | return wordValue; 230 | } 231 | 232 | private boolean asBool(String literal) { 233 | type = Type.BOOL; 234 | boolValue = literal.equals("true"); 235 | return boolValue; 236 | } 237 | 238 | private boolean isLegalWord(String word) { 239 | return !containsChars(word, ":\"[]()"); 240 | } // Word type data shall not contain ':', '"', '[', ']', '(' and ')'. 241 | 242 | private boolean isLegalOp(String word) { 243 | if (word == null || word.isEmpty()) { 244 | return false; 245 | } 246 | char fstCh = word.charAt(0); 247 | if (!(fstCh == '_' || ('a' <= fstCh && fstCh <= 'z') || ('A' <= fstCh && fstCh <= 'Z'))) { 248 | return false; 249 | } // A legal OP type data literal shall begin with '_' or letters. 250 | String legalChars = "abcdefghigklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_'"; 251 | for (int i = 1; i < word.length(); ++i) { 252 | if (legalChars.indexOf(word.charAt(i)) == -1) { 253 | return false; 254 | } 255 | } 256 | return true; 257 | } 258 | 259 | private boolean containsChars(String str, char[] chars) { 260 | if (str == null || str.length() == 0) { 261 | return false; 262 | } 263 | if (chars == null || chars.length == 0) { 264 | return true; 265 | } 266 | for (char c : chars) { 267 | if (str.indexOf(c) != -1) { 268 | return true; 269 | } 270 | } 271 | return false; 272 | } 273 | 274 | private boolean containsChars(String str, String charsStr) { 275 | if (charsStr == null) { 276 | return true; 277 | } 278 | return containsChars(str, charsStr.toCharArray()); 279 | } 280 | 281 | } 282 | -------------------------------------------------------------------------------- /MuaInterpreter/src/mua/DataGenerator.java: -------------------------------------------------------------------------------- 1 | package mua; 2 | 3 | import java.util.Collections; 4 | import java.util.HashMap; 5 | import java.util.LinkedList; 6 | import java.util.Queue; 7 | import java.util.Stack; 8 | import java.util.Vector; 9 | 10 | import mua.error.MuaError; 11 | import mua.error.SyntaxError; 12 | 13 | public class DataGenerator { // Works with a WordCtrler class, used for generating data from input. 14 | 15 | private static class ExpressionProcessor { // Expression process on string level. 16 | 17 | @SuppressWarnings("serial") 18 | private static final HashMap infixOpPriority = new HashMap() {{ 19 | put("*", 7); put("/", 7); put("%", 7); put("+", 6); put("-", 6); 20 | put("&&", 3); put("||", 2); 21 | put(">", 4); put("<", 4); put("==", 4); 22 | put("++", 5); 23 | }}; // Defines the priority of the infix operation, the larger values means higher priority. 24 | 25 | @SuppressWarnings("serial") 26 | private static final HashMap infixPrefixOpPair = new HashMap() {{ 27 | put("*", "mul"); 28 | put("/", "div"); 29 | put("%", "mod"); 30 | put("+", "add"); 31 | put("-", "sub"); 32 | put("&&", "and"); 33 | put("||", "or"); 34 | put(">", "gt"); 35 | put("<", "lt"); 36 | put("==", "eq"); 37 | put("++", "sentence"); 38 | }}; // Infix operation will be transformed to the corresponding prefix operation. 39 | 40 | public static int getInfixOpPriority(String infixOp) { 41 | return infixOpPriority.get(infixOp); 42 | } 43 | 44 | public static String getPrefixOpName(String infixOp) { 45 | return infixPrefixOpPair.get(infixOp); 46 | } 47 | 48 | public static boolean isInfixOp(String name) { 49 | return infixPrefixOpPair.containsKey(name); 50 | } 51 | 52 | private Vector processResult; // Result with prefix style in string. 53 | // Here word block means a number of words separated by infix separators. 54 | private Stack> wordBlockStack = new Stack>(); 55 | private Stack infixOpStack = new Stack(); 56 | private boolean nextNewWordBlock = true; // Whether the next word word belongs to a new word block. 57 | private ExpressionProcessor insideProcessor; // Use to handle the inside expression recursively. 58 | private int depth; // Begin from 1, which presents the number of brackets. 59 | 60 | ExpressionProcessor(int depth) { 61 | this.depth = depth; 62 | } 63 | 64 | Vector getProcessResult() { 65 | return processResult; 66 | } 67 | 68 | void push(String word, int wordDepth) throws SyntaxError { 69 | if (insideProcessor != null) { // Recursion implementation. 70 | insideProcessor.push(word, wordDepth); // Processes and generates word with prefix operations recursively. 71 | if (wordDepth == depth && word.equals(")")) { // End of the current inside expression process. 72 | if (nextNewWordBlock) { 73 | wordBlockStack.push(insideProcessor.getProcessResult()); 74 | } else { 75 | wordBlockStack.peek().addAll(insideProcessor.getProcessResult()); 76 | } // The result of the insideProcessor is a word block. 77 | insideProcessor = null; 78 | } 79 | return; 80 | } 81 | switch (word) { 82 | case "(": // "(" create a new inside expression. 83 | insideProcessor = new ExpressionProcessor(depth + 1); 84 | break; 85 | case ")": // ")" end a expression. 86 | generateResult(); // Generate result here and handle result in higher ExpressionProcessor. 87 | break; 88 | default: 89 | if (isInfixOp(word)) { 90 | nextNewWordBlock = true; // Meeting infix operator means next word belongs to a new word block. 91 | infixOpStack.push(word); // Push infix operator into infixOpStack. 92 | } else { 93 | if (nextNewWordBlock) { 94 | wordBlockStack.push(new Vector()); 95 | } 96 | wordBlockStack.peek().add(word); 97 | nextNewWordBlock = false; 98 | } 99 | break; 100 | } 101 | } 102 | 103 | private void generateResult() throws SyntaxError { 104 | if (wordBlockStack.size() != infixOpStack.size() + 1) { // Shall be n + 1 arguments for n infix operators. 105 | StringBuffer errorDataMessageBuffer = new StringBuffer(); // For building error message. 106 | if (!wordBlockStack.isEmpty()) { 107 | Vector lastElementOfWordBlockVector = wordBlockStack.peek(); 108 | if (!lastElementOfWordBlockVector.isEmpty()) { 109 | errorDataMessageBuffer.append("(Data Block:"); 110 | for (String blockWord : lastElementOfWordBlockVector) { 111 | errorDataMessageBuffer.append(' ').append(blockWord); 112 | } 113 | errorDataMessageBuffer.append(')'); 114 | } 115 | } 116 | if (!infixOpStack.isEmpty()) { 117 | errorDataMessageBuffer.append("(Infix Operator: ").append(infixOpStack.peek()).append(')'); 118 | } 119 | if (errorDataMessageBuffer.length() == 0) { 120 | throw new SyntaxError("()", "empty expression"); 121 | } else { 122 | throw new SyntaxError(errorDataMessageBuffer.toString(), "infix opeartor lacks argument"); 123 | } 124 | } 125 | Vector> tempResult = new Vector>(); 126 | Stack tempOpStack = new Stack(); 127 | // The following part implements infix to prefix: 128 | // First get reversed prefix order: 129 | tempResult.add(wordBlockStack.pop()); 130 | while (!infixOpStack.isEmpty()) { 131 | while (!tempOpStack.isEmpty() && getInfixOpPriority(tempOpStack.peek()) > getInfixOpPriority(infixOpStack.peek())) { 132 | tempResult.add(new Vector()); 133 | tempResult.lastElement().add(getPrefixOpName(tempOpStack.pop())); 134 | } // Pop from tempOpStack and push into tempResult while operator on the top of tempOpStack has higher priority. 135 | tempOpStack.push(infixOpStack.pop()); 136 | tempResult.add(wordBlockStack.pop()); 137 | } 138 | while (!tempOpStack.isEmpty()) { 139 | tempResult.add(new Vector()); 140 | tempResult.lastElement().add(getPrefixOpName(tempOpStack.pop())); 141 | } // Then push and pop all operator. 142 | Collections.reverse(tempResult); // Then reverse to get prefix order. 143 | processResult = new Vector(); 144 | for (Vector wordBlock : tempResult) { 145 | for (String word : wordBlock) { 146 | processResult.add(word); 147 | } 148 | } // Flatten the tempResult to processResult. 149 | } 150 | 151 | void clear() { 152 | wordBlockStack.clear(); 153 | infixOpStack.clear(); 154 | nextNewWordBlock = true; 155 | processResult = null; 156 | insideProcessor = null; 157 | } 158 | } 159 | 160 | private WordCtrler wordCtrler; 161 | private String curWord; // The current word being processed. 162 | private boolean metColon = false; // For handling colon operator. 163 | private ExpressionProcessor expressionProcessor = new ExpressionProcessor(1); // The number of brackets begins from 1. 164 | private int leftBracketsCount = 0; 165 | private Queue wordQueue = new LinkedList(); // The place where word caches. 166 | 167 | DataGenerator(WordCtrler wordCtrler) { 168 | this.wordCtrler = wordCtrler; 169 | } 170 | 171 | Data getNextData() throws MuaError { 172 | while (wordQueue.isEmpty()) { 173 | generateWordQueueOnce(); 174 | } // Use while because function generateWordQueueOnce may not push words into queue. 175 | String word = wordQueue.poll();; 176 | if (word.equals("]")) { 177 | return null; // As the end of List. 178 | } 179 | Data data = new Data(word, null); 180 | if (data.getType() == Data.Type.UNDEFINED) { 181 | return null; 182 | } 183 | if (word.equals("[")) { // Create a list recursively. 184 | Data listItem; 185 | while ((listItem = getNextData()) != null) { 186 | data.addListItem(listItem); 187 | } 188 | } 189 | return data; 190 | } 191 | 192 | private void generateWordQueueOnce() throws SyntaxError { 193 | String word = getNextWordWithColonPreprocess(); 194 | if (word.equals("(")) { 195 | if (++leftBracketsCount == 1) { 196 | return; // The first bracket will be handled in this function and shall not be pushed. 197 | } 198 | } else if (word.equals(")")) { 199 | if (--leftBracketsCount == 0) { // Expression end. 200 | expressionProcessor.generateResult(); 201 | if (expressionProcessor.getProcessResult() != null) { 202 | for (String wordInExpression : expressionProcessor.getProcessResult()) { 203 | wordQueue.add(wordInExpression); 204 | } 205 | } // Generate the result and push it into wordQueue. 206 | initExpressionProcessor(); 207 | return; 208 | } 209 | if (leftBracketsCount < 0) { 210 | throw new SyntaxError(") " + wordCtrler.getCurLeftLine(), "unmatched expression bracket"); 211 | } 212 | } 213 | if (leftBracketsCount > 0) { 214 | expressionProcessor.push(word, leftBracketsCount); 215 | } else { 216 | wordQueue.add(word); 217 | } 218 | } 219 | 220 | private String getNextWordWithColonPreprocess() { // make :word thing "word. 221 | if (metColon) { 222 | metColon = false; 223 | return "\"" + curWord.substring(1); // Then return word with colon replaced with double quote. 224 | } 225 | curWord = wordCtrler.getNextWord(); 226 | if (!curWord.isEmpty() && curWord.charAt(0) == ':' && curWord.length() > 1) { 227 | metColon = true; 228 | return "thing"; // First return "thing". 229 | } 230 | return curWord; // Normal condition without colon. 231 | } 232 | 233 | private void initExpressionProcessor() { 234 | expressionProcessor.clear(); 235 | leftBracketsCount = 0; 236 | } 237 | 238 | public void clear() { 239 | metColon = false; 240 | initExpressionProcessor(); 241 | wordQueue.clear(); 242 | } 243 | 244 | } -------------------------------------------------------------------------------- /MuaInterpreter/src/mua/DataOperationStack.java: -------------------------------------------------------------------------------- 1 | package mua; 2 | 3 | import java.util.Stack; 4 | import java.util.Vector; 5 | 6 | import mua.error.*; 7 | import mua.operation.OperationHandler; 8 | 9 | public class DataOperationStack { // The core of the interpreter. 10 | 11 | private class ArgsNumRecord { // Record the arguments number of operation and function and store handler. 12 | 13 | private int oriArgsNum; // The arguments number of the operation or the function. 14 | private int curLeftArgsNum; // When 1 argument push into operation stack, --curLeftArgsNum. 15 | private boolean isFunction; // Whether the record for a function. 16 | private OperationHandler operationHandler; 17 | private FunctionHandler functionHandler; 18 | 19 | ArgsNumRecord(OperationHandler operationHandler) { // Use to record operation. 20 | isFunction = false; 21 | this.operationHandler = operationHandler; 22 | oriArgsNum = curLeftArgsNum = this.operationHandler.getArgsNum(); 23 | } 24 | 25 | ArgsNumRecord(FunctionHandler functionHandler) { // Use to record function. 26 | isFunction = true; 27 | this.functionHandler = functionHandler; 28 | oriArgsNum = curLeftArgsNum = this.functionHandler.getArgsNum(); 29 | } 30 | 31 | int getOriArgsNum() { 32 | return oriArgsNum; 33 | } 34 | 35 | int decCurLeftArgsNum() { 36 | return --curLeftArgsNum; 37 | } 38 | 39 | boolean getIsFunction() { 40 | return isFunction; 41 | } 42 | 43 | OperationHandler getOperationHandler() { 44 | return operationHandler; 45 | } 46 | 47 | FunctionHandler getFunctionHandler() { 48 | return functionHandler; 49 | } 50 | 51 | } 52 | 53 | private Vector dataVector = new Vector(); // Where real operation stack stores. 54 | private Stack sucArgsNumStack = new Stack(); 55 | private NameSpace space; // A DataOperationStack is binding with a NameSpace. 56 | private boolean stopFlagForFunction = false; // Communicate with corresponding FunctionHandler. 57 | 58 | public DataOperationStack(NameSpace space) { 59 | if (space == null) { 60 | this.space = new NameSpace(); 61 | } else { 62 | this.space = space; 63 | } 64 | } 65 | 66 | public NameSpace getNameSpace() { 67 | return space; 68 | } 69 | 70 | public boolean getStopFlagForFunction() { 71 | return stopFlagForFunction; 72 | } 73 | 74 | private boolean getIsFunctionMode() { 75 | return space.getIsFunctionSpace(); 76 | } 77 | 78 | private String getFunctionName() { 79 | return space.getFunctionName(); 80 | } 81 | 82 | void push(Data data) throws MuaError { // Core. 83 | /* BELOW4DEBUG 84 | Print DataOperationStack Info:*/ 85 | // System.out.print(" " + getFunctionName() + " : "); 86 | // for (Data x : dataVector) { 87 | // System.out.print(x.toString() + " "); 88 | // } 89 | // System.out.println("+" + data); 90 | /* ABOVE4DEBUG*/ 91 | if (data == null) { 92 | return; 93 | } 94 | if (data.getType() == Data.Type.OP) { 95 | int argsNum = OperationHandler.getOpArgsNum(data.getOpValue()); 96 | if (argsNum == -1) { // -1 means not an operation. 97 | FunctionHandler functionHandler = new FunctionHandler(data.getOpValue(), space); 98 | if (functionHandler.getIsFunction()) { 99 | if (functionHandler.getArgsNum() == 0) { // A function accepting no argument shall be executed immediately. 100 | functionHandler.execute(); 101 | Data functionReturnValue = functionHandler.getReturnValue(); 102 | if (functionReturnValue != null) { 103 | push(functionReturnValue); 104 | } 105 | } else { 106 | dataVector.add(data); 107 | sucArgsNumStack.push(new ArgsNumRecord(functionHandler)); // Use sucArgsNumStack to record. 108 | } 109 | } else { // Neither an operation nor a function. 110 | throw new NameError(data, "undefined name (in " + getFunctionName() + ")"); 111 | } 112 | } else if (argsNum == 0) { // An operation accepting no argument shall be executed immediately. 113 | String opValue = data.getOpValue(); 114 | if (opValue.equals("stop") && getIsFunctionMode()) { 115 | stopFlagForFunction = true; // Signal function handler to stop. 116 | clear(); 117 | } else { 118 | OperationHandler operationHandler = new OperationHandler(opValue, space); 119 | operationHandler.execute(); 120 | if (operationHandler.hasReturnValue()) { 121 | data = operationHandler.getReturnValue(); 122 | push(data); 123 | } 124 | } 125 | } else { 126 | OperationHandler operationHandler = new OperationHandler(data.getOpValue(), space); 127 | dataVector.add(data); 128 | sucArgsNumStack.push(new ArgsNumRecord(operationHandler)); 129 | } 130 | } else if (sucArgsNumStack.isEmpty()) { // List shall be run when operation stack is empty. 131 | if (data.getType() == Data.Type.LIST) { 132 | for (Data listItem : data.getListValue()) { 133 | push(listItem); 134 | } 135 | } else if (!getIsFunctionMode()) { // The ways to handle other data types. 136 | System.out.print("// "); 137 | System.out.print(data); 138 | System.out.print(" :: "); 139 | System.out.println(data.getTypeString()); 140 | } 141 | } else { // Data whose type is not OP. 142 | dataVector.add(data); 143 | if (sucArgsNumStack.peek().decCurLeftArgsNum() == 0) { // Data number reaches arguments number. 144 | ArgsNumRecord argsNumRecord = sucArgsNumStack.pop(); 145 | int oriArgsNum = argsNumRecord.getOriArgsNum(); 146 | if (argsNumRecord.getIsFunction()) { // Execute function. 147 | FunctionHandler functionHandler = argsNumRecord.getFunctionHandler(); 148 | for (int i = oriArgsNum - 1; i >= 0; --i) { 149 | functionHandler.addArg(peekAt(i)); 150 | } 151 | functionHandler.execute(); 152 | removeFromTop(oriArgsNum + 1); // Remove function and its arguments from operation stack. 153 | Data returnValue = functionHandler.getReturnValue(); 154 | if (returnValue != null) { 155 | push(returnValue); 156 | } 157 | } else { // Execute operation. 158 | OperationHandler operationHandler = argsNumRecord.getOperationHandler(); 159 | for (int i = oriArgsNum - 1; i >= 0; --i) { 160 | operationHandler.addArg(peekAt(i)); 161 | } 162 | operationHandler.execute(); 163 | removeFromTop(oriArgsNum + 1); // Remove operation and its arguments from operation stack. 164 | if (operationHandler.hasAppendedData()) { // Operation can append data to operation stack. 165 | Data appendedData; 166 | while ((appendedData = operationHandler.getAppendedData()) != null) { 167 | if (appendedData.getType() == Data.Type.OP && appendedData.getOpValue().equals("stop")) { 168 | break; 169 | } 170 | push(appendedData); 171 | } 172 | } 173 | if (operationHandler.hasReturnValue()) { 174 | Data returnValue = operationHandler.getReturnValue(); 175 | push(returnValue); 176 | } 177 | } 178 | } 179 | } 180 | } 181 | 182 | int size() { 183 | return dataVector.size(); 184 | } 185 | 186 | Data peekAt(int n) { // Return the nth data from the top of operation stack. 187 | if (size() <= n) { 188 | return null; 189 | } 190 | return dataVector.get(size() - n - 1); 191 | } 192 | 193 | Data pop() { 194 | if (size() == 0) { 195 | return null; 196 | } 197 | return dataVector.remove(size() - 1); 198 | } 199 | 200 | void removeFromTop(int n) { // Remove n data from the top of operation stack. 201 | for (int i = 0; i < n; ++i) { 202 | pop(); 203 | } 204 | } 205 | 206 | void clear() { 207 | dataVector.clear(); 208 | sucArgsNumStack.clear(); 209 | } 210 | 211 | } 212 | -------------------------------------------------------------------------------- /MuaInterpreter/src/mua/FunctionHandler.java: -------------------------------------------------------------------------------- 1 | package mua; 2 | 3 | import java.util.Vector; 4 | 5 | import mua.error.MuaError; 6 | import mua.error.NameError; 7 | import mua.error.TypeError; 8 | 9 | public class FunctionHandler { 10 | 11 | private boolean isFunction = false; 12 | private String functionName; 13 | private int argsNum; 14 | private Vector parameters = new Vector(); 15 | private Data functionBody; 16 | private NameSpace functionSpace; 17 | private DataOperationStack dataOperationStack; 18 | private int curArgsNum = 0; 19 | 20 | public FunctionHandler(String functionName, NameSpace callerSpace) throws TypeError { 21 | Data data = callerSpace.getWholeSpaceBindingData(functionName); 22 | if (data == null || data.getType() != Data.Type.LIST) { 23 | return; 24 | } 25 | Vector dataContent = data.getListValue(); 26 | if (dataContent == null || dataContent.size() != 2) { 27 | return; 28 | } 29 | Data args = dataContent.get(0); 30 | if (args.getType() != Data.Type.LIST) { 31 | return; 32 | } 33 | for (Data arg : args.getListValue()) { 34 | if (arg.getType() != Data.Type.OP) { 35 | return; 36 | } 37 | parameters.add(arg.getOpValue()); // Initialize parameters. 38 | } 39 | if (dataContent.get(1).getType() != Data.Type.LIST) { 40 | return; 41 | } 42 | isFunction = true; // Passed function definition format check. 43 | this.functionName = functionName; 44 | argsNum = parameters.size(); 45 | functionBody = dataContent.get(1); // Initialize function body. 46 | functionSpace = new NameSpace(this.functionName, callerSpace); // Initialize function space. 47 | dataOperationStack = new DataOperationStack(functionSpace); // Initialize the operation stack for the function. 48 | } 49 | 50 | public boolean getIsFunction() { 51 | return isFunction; 52 | } 53 | 54 | public String getFunctionName() { 55 | return functionName; 56 | } 57 | 58 | public int getArgsNum() { 59 | return argsNum; 60 | } 61 | 62 | public Data getFunctionBody() { 63 | return functionBody; 64 | } 65 | 66 | public void addArg(Data arg) throws NameError { // Add parameter and argument value binding to function space. 67 | if (curArgsNum >= argsNum) { 68 | return; 69 | } 70 | functionSpace.addBinding(parameters.get(curArgsNum++), arg); 71 | } 72 | 73 | public void execute() throws MuaError { 74 | for (Data data : functionBody.getListValue()) { 75 | dataOperationStack.push(data); 76 | if (dataOperationStack.getStopFlagForFunction()) { // Check stop flag. 77 | break; 78 | } 79 | } 80 | } 81 | 82 | public boolean hasReturnValue() { 83 | return functionSpace.getReturnValue() != null; 84 | } 85 | 86 | public Data getReturnValue() { 87 | return functionSpace.getReturnValue(); 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /MuaInterpreter/src/mua/Main.java: -------------------------------------------------------------------------------- 1 | package mua; 2 | 3 | import mua.error.*; 4 | 5 | public class Main { 6 | 7 | static WordCtrler wordCtrler = new WordCtrler(); 8 | static DataGenerator dataGenerator = new DataGenerator(wordCtrler); 9 | static NameSpace mainSpace = new NameSpace(); 10 | static DataOperationStack dataStack = new DataOperationStack(mainSpace); 11 | 12 | public static void main(String[] args) { 13 | try { 14 | preload(); 15 | } catch (MuaError muaError) { 16 | System.err.println("Preloading code meets error:"); 17 | handleError(muaError); 18 | System.exit(-1); 19 | } 20 | System.out.println("Welcome to MUA Interpreter!"); 21 | System.out.println(" By: RenHaotian (3150104714@zju.edu.cn)"); 22 | Data data; 23 | while (true) { 24 | try { 25 | data = dataGenerator.getNextData(); 26 | if (data == null) { 27 | handleError(new SyntaxError("] " + wordCtrler.getCurLeftLine(), "unmatched bracket")); 28 | } else { 29 | dataStack.push(data); 30 | } 31 | } catch (MuaError muaError) { 32 | handleError(muaError); 33 | } catch (Exception e) { 34 | System.err.println("InterpreterRunTimeError:"); 35 | e.printStackTrace(); 36 | System.exit(-1); 37 | } 38 | } 39 | } 40 | 41 | static void preload() throws MuaError { 42 | final String preloadContent = new StringBuffer() 43 | .append("make \"pi [[][output 3.14159]] ") 44 | .append("make \"run [[l][repeat 1 :l]] ") 45 | .toString(); 46 | DataOperationStack tempDataStack = new DataOperationStack(mainSpace); 47 | WordCtrler tempWordCtrler = new WordCtrler(preloadContent); 48 | DataGenerator tempDataGenerator = new DataGenerator(tempWordCtrler); 49 | Data data; 50 | while (true) { 51 | data = tempDataGenerator.getNextData(); 52 | if (data == null) { 53 | break; 54 | } 55 | tempDataStack.push(data); 56 | } 57 | } 58 | 59 | static void handleError(MuaError error) { 60 | System.err.print("[Line "); 61 | System.err.print(wordCtrler.getLineNumber()); 62 | System.err.print("] "); 63 | error.printErrorInfomation(); 64 | wordCtrler.clear(); 65 | dataGenerator.clear(); 66 | dataStack.clear(); 67 | } 68 | 69 | public static NameSpace getMainSpace() { 70 | return mainSpace; 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /MuaInterpreter/src/mua/NameSpace.java: -------------------------------------------------------------------------------- 1 | package mua; 2 | 3 | import java.util.HashMap; 4 | import java.util.HashSet; 5 | import java.util.Set; 6 | 7 | import mua.error.NameError; 8 | 9 | public class NameSpace { 10 | 11 | @SuppressWarnings("serial") 12 | private static final HashSet reservedWord = new HashSet() {{ 13 | add("true"); add("false"); 14 | add("make"); add("thing"); add("erase"); add("isname"); add("print"); add("read"); add("readlist"); 15 | add("add"); add("sub"); add("mul"); add("div"); add("mod"); 16 | add("eq"); add("gt"); add("lt"); add("and"); add("or"); add("not"); 17 | add("repeat"); add("output"); add("export"); add("stop"); 18 | add("random"); add("sqrt"); add("int"); 19 | add("isnumber"); add("isword"); add("islist"); add("isbool"); add("isempty"); 20 | add("word"); add("sentence"); add("list"); add("join"); 21 | add("first"); add("last"); add("butfirst"); add("butlast"); 22 | add("wait"); 23 | add("erall"); add("poall"); 24 | add("save"); add("load"); 25 | add("if"); 26 | }}; 27 | 28 | private HashMap wordDataBindings = new HashMap(); 29 | private Data returnValue; 30 | private String functionName; // Not function space will be "[Main]". 31 | private boolean isFunctionSpace; // Whether the space is for a function. 32 | private NameSpace parentSpace; // The parent space of a function is where its caller from. 33 | 34 | public NameSpace() { 35 | functionName = "[Main]"; 36 | isFunctionSpace = false; 37 | parentSpace = null; 38 | } 39 | 40 | public NameSpace(String functionName, NameSpace parentSpace) { 41 | if (functionName != null && !functionName.isEmpty() && parentSpace != null) { 42 | this.functionName = functionName; 43 | isFunctionSpace = true; 44 | this.parentSpace = parentSpace; 45 | } else { 46 | this.functionName = "[Main]"; 47 | isFunctionSpace = false; 48 | this.parentSpace = null; 49 | } 50 | } 51 | 52 | public void setReturnValue(Data newReturnValue) { 53 | returnValue = newReturnValue; 54 | } 55 | 56 | public Data getReturnValue() { 57 | return returnValue; 58 | } 59 | 60 | public String getFunctionName() { 61 | return functionName; 62 | } 63 | 64 | public boolean getIsFunctionSpace() { 65 | return isFunctionSpace; 66 | } 67 | 68 | public Data addBinding(String word, Data data) throws NameError { 69 | if (word == null || word.isEmpty()) { 70 | return null; 71 | } 72 | if (reservedWord.contains(word)) { 73 | throw new NameError(word, "name is reserved (in " + functionName + ")"); 74 | } 75 | return wordDataBindings.put(word, data); 76 | } 77 | 78 | public Data eraseBinding(String word) { 79 | return localSpaceContainsBinding(word) ? wordDataBindings.remove(word) : null; 80 | } 81 | 82 | public void clearBindings() { 83 | wordDataBindings.clear(); 84 | } 85 | 86 | public Set getBindingsKeySet() { 87 | return wordDataBindings.keySet(); 88 | } 89 | 90 | // Local space means the wordDataBindings segment. 91 | // Whole space means the wordDataBindings segment and the recursive parentSpace. 92 | public Data getlocalSpaceBindingData(String word) { 93 | return localSpaceContainsBinding(word) ? wordDataBindings.get(word) : null; 94 | } 95 | 96 | public Data getWholeSpaceBindingData(String word) { 97 | if (word == null || word.isEmpty()) { 98 | return null; 99 | } 100 | if (wordDataBindings.containsKey(word)) { 101 | return wordDataBindings.get(word); 102 | } 103 | if (parentSpace == null) { 104 | return null; 105 | } 106 | return parentSpace.getWholeSpaceBindingData(word); 107 | } 108 | 109 | public boolean localSpaceContainsBinding(String word) { 110 | if (word == null || word.isEmpty()) { 111 | return false; 112 | } 113 | return wordDataBindings.containsKey(word); 114 | } 115 | 116 | public boolean wholeSpaceContainsBinding(String word) { 117 | if (word == null || word.isEmpty()) { 118 | return false; 119 | } 120 | if (wordDataBindings.containsKey(word)) { 121 | return true; 122 | } 123 | if (parentSpace == null) { 124 | return false; 125 | } 126 | return parentSpace.wholeSpaceContainsBinding(word); 127 | } 128 | 129 | } 130 | -------------------------------------------------------------------------------- /MuaInterpreter/src/mua/WordCtrler.java: -------------------------------------------------------------------------------- 1 | package mua; 2 | 3 | import java.io.InputStream; 4 | import java.util.Scanner; 5 | 6 | public class WordCtrler { // Here word means the characters segmented naturally. 7 | 8 | private class LineCtrler { 9 | 10 | private Scanner input; 11 | private boolean isFromStdInput; // Whether scanner is from standard input. 12 | private String lineContent = ""; // Current line got from input scanner. 13 | private int lineNumber = 0; // The line number of the current line. 14 | private String outPrompt = "> "; // The prompt begins at every line out of list and expression. 15 | private String inPrompt = "... "; // The prompt begins at every line in list and expression. 16 | 17 | // Use constructor to indicate input scanner. 18 | // If no scanner indicated, use standard input. 19 | LineCtrler() { 20 | input = new Scanner(System.in); 21 | isFromStdInput = true; 22 | } 23 | 24 | LineCtrler(InputStream inputStream) { 25 | if (input == null || inputStream == System.in) { 26 | input = new Scanner(System.in); 27 | isFromStdInput = true; 28 | } else { 29 | this.input = new Scanner(inputStream); 30 | isFromStdInput = false; 31 | } 32 | } 33 | 34 | public String getCurLine() { 35 | return lineContent; 36 | } 37 | 38 | public int getLineNumber() { 39 | return lineNumber; 40 | } 41 | 42 | public String getOutPrompt() { 43 | return outPrompt; 44 | } 45 | 46 | public String getInPrompt() { 47 | return inPrompt; 48 | } 49 | 50 | public String setOutPrompt(String newOutPrompt) { 51 | if (newOutPrompt != null) { 52 | outPrompt = newOutPrompt; 53 | } 54 | return outPrompt; 55 | } 56 | 57 | public String setInPrompt(String newInPrompt) { 58 | if (newInPrompt != null) { 59 | inPrompt = newInPrompt; 60 | } 61 | return inPrompt; 62 | } 63 | 64 | public String getNextLine() { 65 | do { 66 | if (isFromStdInput) { 67 | if (leftListBracketsNum == 0 && leftExpBracketsNum == 0) { 68 | System.out.print(outPrompt); 69 | } else { 70 | System.out.print(inPrompt); 71 | } 72 | } // Print prompt only when scanner is from standard input. 73 | lineContent = normalize(input.nextLine()); 74 | ++lineNumber; 75 | } while (lineContent.equals("")); // Ignore lines with meaningful content. 76 | return lineContent; 77 | } 78 | 79 | private String normalize(String str) { 80 | if (str == null) { 81 | return ""; 82 | } 83 | if (str.indexOf("//") >= 0) { // Remove the comments. 84 | str = str.substring(0, str.indexOf("//")); 85 | } 86 | str = str.trim(); // Remove white spaces at the begin and the end. 87 | return str; 88 | } 89 | 90 | } 91 | 92 | private LineCtrler lineCtrler; 93 | private String curLine; 94 | private String curLeftLine = ""; // The left content of the current line. 95 | private String curWord = ""; // The current word got from the current line. 96 | private int leftListBracketsNum = 0; 97 | private int leftExpBracketsNum = 0; 98 | 99 | // Usage 1: Get words from input stream (Need help from LineCtrler class). 100 | WordCtrler() { 101 | lineCtrler = new LineCtrler(); 102 | } 103 | 104 | WordCtrler(InputStream inputStream) { 105 | lineCtrler = new LineCtrler(inputStream); 106 | } 107 | 108 | // Usage 2: Get words from a one-line-string. 109 | public WordCtrler(String line) { 110 | curLeftLine = curLine = line; 111 | } 112 | 113 | public String getCurWord() { 114 | return curWord; 115 | } 116 | 117 | public String getCurLine() { 118 | if (lineCtrler != null) { 119 | curLine = lineCtrler.getCurLine(); 120 | } 121 | return curLine; 122 | } 123 | 124 | public String getCurLeftLine() { 125 | return curLeftLine; 126 | } 127 | 128 | public String getOutPrompt() { 129 | if (lineCtrler == null) { 130 | return null; 131 | } 132 | return lineCtrler.getOutPrompt(); 133 | } 134 | 135 | public String setOutPrompt(String newOutPrompt) { 136 | if (lineCtrler == null) { 137 | return null; 138 | } 139 | return lineCtrler.setOutPrompt(newOutPrompt); 140 | } 141 | 142 | public String getInPrompt() { 143 | if (lineCtrler == null) { 144 | return null; 145 | } 146 | return lineCtrler.getInPrompt(); 147 | } 148 | 149 | public String setInPrompt(String newInPrompt) { 150 | if (lineCtrler == null) { 151 | return null; 152 | } 153 | return lineCtrler.setInPrompt(newInPrompt); 154 | } 155 | 156 | public int getLineNumber() { 157 | if (lineCtrler == null) { 158 | return 0; 159 | } 160 | return lineCtrler.getLineNumber(); 161 | } 162 | 163 | public String getNextWord() { 164 | curLeftLine = curLeftLine.trim(); // Remove white spaces at the begin and the end. 165 | if (curLeftLine.equals("")) { 166 | if (lineCtrler == null) { // For usage 2. 167 | return ""; 168 | } 169 | curLeftLine = lineCtrler.getNextLine(); // Get a new meaningful line since the current line has been finished reading. 170 | } 171 | char firstChar = curLeftLine.charAt(0); 172 | if (firstChar == '[' || firstChar == ']' || firstChar == '(' || firstChar == ')') 173 | { // Lists' and expressions' begin and end shall be extracted alone. 174 | curLeftLine = curLeftLine.substring(1); 175 | curLeftLine = curLeftLine.trim(); 176 | switch (firstChar) { 177 | case '[': 178 | ++leftListBracketsNum; 179 | return "["; 180 | case ']': 181 | --leftListBracketsNum; 182 | return "]"; 183 | case '(': 184 | ++leftExpBracketsNum; 185 | return "("; 186 | case ')': 187 | --leftExpBracketsNum; 188 | return ")"; 189 | } 190 | } 191 | int nextSepIndex = getNextSepIndex(curLeftLine); // Find the index of the next separator. 192 | if (nextSepIndex == -1) { // No next separator indicates the whole curLeftLine is a single word. 193 | curWord = curLeftLine; 194 | curLeftLine = ""; 195 | return curWord; 196 | } 197 | curWord = curLeftLine.substring(0, nextSepIndex); 198 | curLeftLine = curLeftLine.substring(nextSepIndex); 199 | curLeftLine = curLeftLine.trim(); 200 | return curWord; 201 | } 202 | 203 | public void clear() { 204 | curLeftLine = ""; 205 | curWord = ""; 206 | leftListBracketsNum = leftExpBracketsNum = 0; 207 | } 208 | 209 | private int getNextSepIndex(String str) { 210 | String nextCharsStr = " \t[]()"; 211 | for (int i = 0; i < str.length(); ++i) { 212 | if (nextCharsStr.indexOf(str.charAt(i)) != -1) { 213 | return i; 214 | } 215 | } 216 | return -1; 217 | } 218 | 219 | } 220 | -------------------------------------------------------------------------------- /MuaInterpreter/src/mua/error/MuaError.java: -------------------------------------------------------------------------------- 1 | package mua.error; 2 | 3 | import mua.Data; 4 | 5 | @SuppressWarnings("serial") 6 | public class MuaError extends Exception { 7 | 8 | private Data errorData; 9 | private String errorDataString; 10 | private String errorTypeName; 11 | private StringBuffer detailedMessage; 12 | 13 | public MuaError(String errorTypeName, Data errorData, String message) { 14 | super(message); 15 | this.errorTypeName = errorTypeName; 16 | this.errorData = errorData; 17 | } 18 | 19 | public MuaError(String errorTypeName, String errorDataString, String message) { 20 | super(message); 21 | this.errorTypeName = errorTypeName; 22 | this.errorDataString = errorDataString; 23 | } 24 | 25 | public Data getErrorData() { 26 | return errorData; 27 | } 28 | 29 | public String getErrorTypeName() { 30 | return errorTypeName; 31 | } 32 | 33 | public void generateDetailedMessage() { 34 | detailedMessage = new StringBuffer(); 35 | detailedMessage.append(errorTypeName) 36 | .append(": ") 37 | .append(getMessage()) 38 | .append('\n'); 39 | if (errorData != null) { 40 | detailedMessage.append(" At ") 41 | .append(errorData.toString()) 42 | .append(" :: ") 43 | .append(errorData.getTypeString()) 44 | .append('\n'); 45 | } else if (errorDataString != null) { 46 | detailedMessage.append(" At ") 47 | .append(errorDataString) 48 | .append('\n'); 49 | } 50 | } 51 | 52 | public String getDetailedMessage() { 53 | return detailedMessage.toString(); 54 | } 55 | 56 | public void printErrorInfomation() { 57 | System.err.println(detailedMessage); 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /MuaInterpreter/src/mua/error/NameError.java: -------------------------------------------------------------------------------- 1 | package mua.error; 2 | 3 | import mua.Data; 4 | 5 | @SuppressWarnings("serial") 6 | public final class NameError extends MuaError { 7 | 8 | public NameError(Data errorData, String message) { 9 | super("NameError", errorData, message); 10 | generateDetailedMessage(); 11 | } 12 | 13 | public NameError(String errorDataString, String message) { 14 | super("NameError", errorDataString, message); 15 | generateDetailedMessage(); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /MuaInterpreter/src/mua/error/SyntaxError.java: -------------------------------------------------------------------------------- 1 | package mua.error; 2 | 3 | import mua.Data; 4 | 5 | @SuppressWarnings("serial") 6 | public final class SyntaxError extends MuaError { 7 | 8 | public SyntaxError(Data errorData, String message) { 9 | super("SyntaxError", errorData, message); 10 | generateDetailedMessage(); 11 | } 12 | 13 | public SyntaxError(String errorDataString, String message) { 14 | super("SyntaxError", errorDataString, message); 15 | generateDetailedMessage(); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /MuaInterpreter/src/mua/error/TypeError.java: -------------------------------------------------------------------------------- 1 | package mua.error; 2 | 3 | import mua.Data; 4 | 5 | @SuppressWarnings("serial") 6 | public final class TypeError extends MuaError { 7 | 8 | public TypeError(Data errorData, String message) { 9 | super("TypeError", errorData, message); 10 | generateDetailedMessage(); 11 | } 12 | 13 | public TypeError(String errorDataString, String message) { 14 | super("TypeError", errorDataString, message); 15 | generateDetailedMessage(); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /MuaInterpreter/src/mua/error/ValueError.java: -------------------------------------------------------------------------------- 1 | package mua.error; 2 | 3 | import mua.Data; 4 | 5 | @SuppressWarnings("serial") 6 | public class ValueError extends MuaError { 7 | 8 | public ValueError(Data errorData, String message) { 9 | super("ValueError", errorData, message); 10 | generateDetailedMessage(); 11 | } 12 | 13 | public ValueError(String errorDataString, String message) { 14 | super("ValueError", errorDataString, message); 15 | generateDetailedMessage(); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /MuaInterpreter/src/mua/operation/ButfirstOp.java: -------------------------------------------------------------------------------- 1 | package mua.operation; 2 | 3 | import java.util.Vector; 4 | 5 | import mua.Data; 6 | import mua.NameSpace; 7 | import mua.error.TypeError; 8 | import mua.error.ValueError; 9 | 10 | public final class ButfirstOp extends Operation { 11 | 12 | public ButfirstOp(Data var0) { 13 | arguments = new Data[] { var0 }; 14 | hasReturnValue = true; 15 | opName = "butfirst"; 16 | } 17 | 18 | @Override 19 | public void execute(NameSpace space) throws TypeError, ValueError { 20 | switch (arguments[0].getType()) { 21 | case LIST: 22 | Vector listValue = new Vector(arguments[0].getListValue()); 23 | if (listValue.size() == 0) { 24 | throw new ValueError(arguments[0], "empty list (in " + space.getFunctionName() + ")"); 25 | } 26 | listValue.remove(0); 27 | returnValue = new Data(listValue); 28 | break; 29 | case WORD: 30 | String wordValue = arguments[0].getWordValue(); 31 | if (wordValue.length() == 0) { 32 | throw new ValueError(arguments[0], "empty word (in " + space.getFunctionName() + ")"); 33 | } 34 | returnValue = new Data(wordValue.substring(1)); 35 | break; 36 | default: 37 | throw new TypeError(arguments[0], "not a word or a list (in " + space.getFunctionName() + ")"); 38 | } 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /MuaInterpreter/src/mua/operation/ButlastOp.java: -------------------------------------------------------------------------------- 1 | package mua.operation; 2 | 3 | import java.util.Vector; 4 | 5 | import mua.Data; 6 | import mua.NameSpace; 7 | import mua.error.TypeError; 8 | import mua.error.ValueError; 9 | 10 | public final class ButlastOp extends Operation { 11 | 12 | public ButlastOp(Data var0) { 13 | arguments = new Data[] { var0 }; 14 | hasReturnValue = true; 15 | opName = "butlast"; 16 | } 17 | 18 | @Override 19 | public void execute(NameSpace space) throws TypeError, ValueError { 20 | switch (arguments[0].getType()) { 21 | case LIST: 22 | Vector listValue = new Vector(arguments[0].getListValue()); 23 | int listValueSize = listValue.size(); 24 | if (listValueSize == 0) { 25 | throw new ValueError(arguments[0], "empty list (in " + space.getFunctionName() + ")"); 26 | } 27 | listValue.remove(listValueSize - 1); 28 | returnValue = new Data(listValue); 29 | break; 30 | case WORD: 31 | String wordValue = arguments[0].getWordValue(); 32 | int wordValueLength = wordValue.length(); 33 | if (wordValueLength == 0) { 34 | throw new ValueError(arguments[0], "empty word (in " + space.getFunctionName() + ")"); 35 | } 36 | returnValue = new Data(wordValue.substring(0, wordValueLength - 1)); 37 | break; 38 | default: 39 | throw new TypeError(arguments[0], "not a word or a list (in " + space.getFunctionName() + ")"); 40 | } 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /MuaInterpreter/src/mua/operation/ErallOp.java: -------------------------------------------------------------------------------- 1 | package mua.operation; 2 | 3 | import mua.Data; 4 | import mua.NameSpace; 5 | 6 | public final class ErallOp extends Operation { 7 | 8 | public ErallOp() { 9 | arguments = new Data[] {}; 10 | hasReturnValue = false; 11 | opName = "erall"; 12 | } 13 | 14 | @Override 15 | public void execute(NameSpace space) { 16 | space.clearBindings(); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /MuaInterpreter/src/mua/operation/EraseOp.java: -------------------------------------------------------------------------------- 1 | package mua.operation; 2 | 3 | import mua.Data; 4 | import mua.NameSpace; 5 | import mua.error.TypeError; 6 | import mua.error.ValueError; 7 | 8 | public final class EraseOp extends Operation { 9 | 10 | public EraseOp(Data var0) { 11 | arguments = new Data[] { var0 }; 12 | hasReturnValue = false; 13 | opName = "erase"; 14 | } 15 | 16 | @Override 17 | public void execute(NameSpace space) throws ValueError, TypeError { 18 | if (space.eraseBinding(arguments[0].getWordValue()) == null) { 19 | throw new ValueError(arguments[0], "not in namespace (in " + space.getFunctionName() + ")"); 20 | } 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /MuaInterpreter/src/mua/operation/ExportOp.java: -------------------------------------------------------------------------------- 1 | package mua.operation; 2 | 3 | import mua.Data; 4 | import mua.Main; 5 | import mua.NameSpace; 6 | import mua.error.NameError; 7 | import mua.error.TypeError; 8 | 9 | public final class ExportOp extends Operation { 10 | 11 | public ExportOp(Data var0) { 12 | arguments = new Data[] { var0 }; 13 | hasReturnValue = false; 14 | opName = "export"; 15 | } 16 | 17 | @Override 18 | public void execute(NameSpace space) throws NameError, TypeError { 19 | String word = arguments[0].getWordValue(); 20 | Data data = space.getWholeSpaceBindingData(word); 21 | if (data == null) { 22 | throw new NameError(arguments[0], "undefined name (in " + space.getFunctionName() + ")"); 23 | } 24 | Main.getMainSpace().addBinding(word, data); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /MuaInterpreter/src/mua/operation/FirstOp.java: -------------------------------------------------------------------------------- 1 | package mua.operation; 2 | 3 | import java.util.Vector; 4 | 5 | import mua.Data; 6 | import mua.NameSpace; 7 | import mua.error.TypeError; 8 | import mua.error.ValueError; 9 | 10 | public final class FirstOp extends Operation { 11 | 12 | public FirstOp(Data var0) { 13 | arguments = new Data[] { var0 }; 14 | hasReturnValue = true; 15 | opName = "first"; 16 | } 17 | 18 | @Override 19 | public void execute(NameSpace space) throws TypeError, ValueError { 20 | switch (arguments[0].getType()) { 21 | case LIST: 22 | Vector listValue = arguments[0].getListValue(); 23 | if (listValue.size() == 0) { 24 | throw new ValueError(arguments[0], "empty list (in " + space.getFunctionName() + ")"); 25 | } 26 | returnValue = new Data(listValue.firstElement()); 27 | break; 28 | case WORD: 29 | String wordValue = arguments[0].getWordValue(); 30 | if (wordValue.length() == 0) { 31 | throw new ValueError(arguments[0], "empty word (in " + space.getFunctionName() + ")"); 32 | } 33 | returnValue = new Data(arguments[0].getWordValue().substring(0, 1)); 34 | break; 35 | default: 36 | throw new TypeError(arguments[0], "not a word or a list (in " + space.getFunctionName() + ")"); 37 | } 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /MuaInterpreter/src/mua/operation/IOperation.java: -------------------------------------------------------------------------------- 1 | package mua.operation; 2 | 3 | import mua.Data; 4 | import mua.NameSpace; 5 | import mua.error.MuaError; 6 | 7 | public interface IOperation { 8 | public String getOpName(); 9 | public int getArgumentsNum(); 10 | public Data getArgumentAt(int argumentIndex); 11 | public void execute(NameSpace space) throws MuaError; 12 | public boolean getHasReturnValue(); 13 | public boolean getHasAppendedData(); 14 | public Data getReturnValue(); 15 | public Data getAppendedData(); 16 | } 17 | -------------------------------------------------------------------------------- /MuaInterpreter/src/mua/operation/IfOp.java: -------------------------------------------------------------------------------- 1 | package mua.operation; 2 | 3 | import java.util.Vector; 4 | 5 | import mua.Data; 6 | import mua.error.TypeError; 7 | 8 | public class IfOp extends Operation{ 9 | 10 | Vector runList; 11 | int curAppendedDataPos = 0; 12 | 13 | public IfOp(Data var0, Data var1, Data var2) throws TypeError { 14 | arguments = new Data[] { var0, var1, var2 }; 15 | hasReturnValue = false; 16 | opName = "if"; 17 | hasAppendData = true; 18 | boolean boolValue = arguments[0].getBoolValue(); 19 | Vector trueList = arguments[1].getListValue(); 20 | Vector falseList = arguments[2].getListValue(); 21 | runList = boolValue ? trueList : falseList; 22 | } 23 | 24 | @Override 25 | public Data getAppendedData() { 26 | if (runList.isEmpty() || curAppendedDataPos >= runList.size()) { 27 | return null; 28 | } 29 | return runList.get(curAppendedDataPos++); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /MuaInterpreter/src/mua/operation/IntOp.java: -------------------------------------------------------------------------------- 1 | package mua.operation; 2 | 3 | import mua.Data; 4 | import mua.NameSpace; 5 | import mua.error.TypeError; 6 | 7 | public final class IntOp extends Operation{ 8 | 9 | public IntOp(Data var0) { 10 | arguments = new Data[] { var0 }; 11 | hasReturnValue = true; 12 | opName = "int"; 13 | } 14 | 15 | @Override 16 | public void execute(NameSpace space) throws TypeError { 17 | returnValue = new Data(Math.floor(arguments[0].getNumberValue())); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /MuaInterpreter/src/mua/operation/IsboolOp.java: -------------------------------------------------------------------------------- 1 | package mua.operation; 2 | 3 | import mua.Data; 4 | import mua.NameSpace; 5 | import mua.error.TypeError; 6 | 7 | public final class IsboolOp extends Operation { 8 | 9 | public IsboolOp(Data var0) { 10 | arguments = new Data[] { var0 }; 11 | hasReturnValue = true; 12 | opName = "isbool"; 13 | } 14 | 15 | @Override 16 | public void execute(NameSpace space) throws TypeError { 17 | returnValue = new Data(arguments[0].getType() == Data.Type.BOOL); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /MuaInterpreter/src/mua/operation/IsemptyOp.java: -------------------------------------------------------------------------------- 1 | package mua.operation; 2 | 3 | import mua.Data; 4 | import mua.NameSpace; 5 | import mua.error.TypeError; 6 | 7 | public final class IsemptyOp extends Operation { 8 | 9 | public IsemptyOp(Data var0) { 10 | arguments = new Data[] { var0 }; 11 | hasReturnValue = true; 12 | opName = "isempty"; 13 | } 14 | 15 | @Override 16 | public void execute(NameSpace space) throws TypeError { 17 | if (arguments[0].getType() == Data.Type.WORD) { 18 | returnValue = new Data(arguments[0].getWordValue().equals("")); 19 | } else if (arguments[0].getType() == Data.Type.LIST) { 20 | returnValue = new Data(arguments[0].getListValue().size() == 0); 21 | } else { 22 | throw new TypeError(arguments[0], "not a word or a list (in " + space.getFunctionName() + ")"); 23 | } 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /MuaInterpreter/src/mua/operation/IslistOp.java: -------------------------------------------------------------------------------- 1 | package mua.operation; 2 | 3 | import mua.Data; 4 | import mua.NameSpace; 5 | import mua.error.TypeError; 6 | 7 | public final class IslistOp extends Operation { 8 | 9 | public IslistOp(Data var0) { 10 | arguments = new Data[] { var0 }; 11 | hasReturnValue = true; 12 | opName = "islist"; 13 | } 14 | 15 | @Override 16 | public void execute(NameSpace space) throws TypeError { 17 | returnValue = new Data(arguments[0].getType() == Data.Type.LIST); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /MuaInterpreter/src/mua/operation/IsnameOp.java: -------------------------------------------------------------------------------- 1 | package mua.operation; 2 | 3 | import mua.Data; 4 | import mua.NameSpace; 5 | import mua.error.TypeError; 6 | 7 | public final class IsnameOp extends Operation { 8 | 9 | public IsnameOp(Data var0) { 10 | arguments = new Data[] { var0 }; 11 | hasReturnValue = true; 12 | opName = "isname"; 13 | } 14 | 15 | @Override 16 | public void execute(NameSpace space) throws TypeError { 17 | String word = arguments[0].getWordValue(); 18 | returnValue = new Data(space.wholeSpaceContainsBinding(word)); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /MuaInterpreter/src/mua/operation/IsnumberOp.java: -------------------------------------------------------------------------------- 1 | package mua.operation; 2 | 3 | import mua.Data; 4 | import mua.NameSpace; 5 | import mua.error.TypeError; 6 | 7 | public final class IsnumberOp extends Operation{ 8 | 9 | public IsnumberOp(Data var0) { 10 | arguments = new Data[] { var0 }; 11 | hasReturnValue = true; 12 | opName = "isnumber"; 13 | } 14 | 15 | @Override 16 | public void execute(NameSpace space) throws TypeError { 17 | returnValue = new Data(arguments[0].getType() == Data.Type.NUMBER); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /MuaInterpreter/src/mua/operation/IswordOp.java: -------------------------------------------------------------------------------- 1 | package mua.operation; 2 | 3 | import mua.Data; 4 | import mua.NameSpace; 5 | import mua.error.TypeError; 6 | 7 | public final class IswordOp extends Operation { 8 | 9 | public IswordOp(Data var0) { 10 | arguments = new Data[] { var0 }; 11 | hasReturnValue = true; 12 | opName = "isnumber"; 13 | } 14 | 15 | @Override 16 | public void execute(NameSpace space) throws TypeError { 17 | returnValue = new Data(arguments[0].getType() == Data.Type.WORD); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /MuaInterpreter/src/mua/operation/JoinOp.java: -------------------------------------------------------------------------------- 1 | package mua.operation; 2 | 3 | import java.util.Vector; 4 | 5 | import mua.Data; 6 | import mua.NameSpace; 7 | import mua.error.MuaError; 8 | 9 | public final class JoinOp extends Operation { 10 | 11 | public JoinOp(Data var0, Data var1) { 12 | arguments = new Data[] { var0, var1 }; 13 | hasReturnValue = true; 14 | opName = "join"; 15 | } 16 | 17 | @Override 18 | public void execute(NameSpace space) throws MuaError { 19 | Vector oriListValue = new Vector(arguments[0].getListValue()); 20 | oriListValue.add(arguments[1]); 21 | returnValue = new Data(oriListValue); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /MuaInterpreter/src/mua/operation/LastOp.java: -------------------------------------------------------------------------------- 1 | package mua.operation; 2 | 3 | import java.util.Vector; 4 | 5 | import mua.Data; 6 | import mua.NameSpace; 7 | import mua.error.TypeError; 8 | import mua.error.ValueError; 9 | 10 | public final class LastOp extends Operation { 11 | 12 | public LastOp(Data var0) { 13 | arguments = new Data[] { var0 }; 14 | hasReturnValue = true; 15 | opName = "last"; 16 | } 17 | 18 | @Override 19 | public void execute(NameSpace space) throws TypeError, ValueError { 20 | switch (arguments[0].getType()) { 21 | case LIST: 22 | Vector listValue = arguments[0].getListValue(); 23 | if (listValue.size() == 0) { 24 | throw new ValueError(arguments[0], "empty list (in " + space.getFunctionName() + ")"); 25 | } 26 | returnValue = new Data(listValue.lastElement()); 27 | break; 28 | case WORD: 29 | String wordValue = arguments[0].getWordValue(); 30 | int wordValueLength = wordValue.length(); 31 | if (wordValueLength == 0) { 32 | throw new ValueError(arguments[0], "empty word (in " + space.getFunctionName() + ")"); 33 | } 34 | returnValue = new Data(wordValue.substring(wordValueLength - 1, wordValueLength)); 35 | break; 36 | default: 37 | throw new TypeError(arguments[0], "not a word or a list (in " + space.getFunctionName() + ")"); 38 | } 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /MuaInterpreter/src/mua/operation/ListOp.java: -------------------------------------------------------------------------------- 1 | package mua.operation; 2 | 3 | import java.util.Vector; 4 | 5 | import mua.Data; 6 | import mua.NameSpace; 7 | import mua.error.MuaError; 8 | 9 | public final class ListOp extends Operation { 10 | 11 | public ListOp(Data var0, Data var1) { 12 | arguments = new Data[] { var0, var1 }; 13 | hasReturnValue = true; 14 | opName = "list"; 15 | } 16 | 17 | @Override 18 | public void execute(NameSpace space) throws MuaError { 19 | Vector emptyListValue = new Vector(); 20 | returnValue = new Data(emptyListValue); 21 | returnValue.addListItem(arguments[0]); 22 | returnValue.addListItem(arguments[1]); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /MuaInterpreter/src/mua/operation/LoadOp.java: -------------------------------------------------------------------------------- 1 | package mua.operation; 2 | 3 | import java.io.FileReader; 4 | import java.io.IOException; 5 | import java.io.BufferedReader; 6 | import java.io.FileNotFoundException; 7 | 8 | import mua.Data; 9 | import mua.NameSpace; 10 | import mua.WordCtrler; 11 | import mua.error.MuaError; 12 | import mua.error.NameError; 13 | 14 | public final class LoadOp extends Operation { 15 | 16 | WordCtrler wordCtrler; 17 | 18 | public LoadOp(Data var0) { 19 | arguments = new Data[] { var0 }; 20 | hasReturnValue = false; 21 | opName = "save"; 22 | } 23 | 24 | @Override 25 | public void execute(NameSpace space) throws MuaError { 26 | try { 27 | FileReader fileReader = new FileReader(arguments[0].getWordValue()); 28 | BufferedReader bufferReader = new BufferedReader(fileReader); 29 | while (true) { 30 | String key = bufferReader.readLine(); 31 | if (key == null) { 32 | break; 33 | } 34 | key = key.trim(); 35 | if (key.isEmpty() || !isLegalOp(key)) { 36 | break; 37 | } 38 | String value = bufferReader.readLine(); 39 | if (value == null) { 40 | break; 41 | } 42 | value = value.trim(); 43 | if (value.isEmpty() || !isBracketsNumLegal(value)) { 44 | break; 45 | } 46 | wordCtrler = new WordCtrler(value); 47 | Data bindingData = generateData(); 48 | if (bindingData == null) { 49 | break; 50 | } 51 | space.addBinding(key, bindingData); 52 | } 53 | bufferReader.close(); 54 | fileReader.close(); 55 | } catch (FileNotFoundException e) { 56 | throw new NameError(arguments[0], "file not exist (in " + space.getFunctionName() + ")"); 57 | } catch (IOException e) { 58 | System.err.println("InterpreterRunTimeError:"); 59 | e.printStackTrace(); 60 | System.exit(-1); 61 | } 62 | } 63 | 64 | private boolean isLegalOp(String word) { 65 | if (word == null || word.isEmpty()) { 66 | return false; 67 | } 68 | char fstCh = word.charAt(0); 69 | if (!(fstCh == '_' || ('a' <= fstCh && fstCh <= 'z') || ('A' <= fstCh && fstCh <= 'Z'))) { 70 | return false; 71 | } 72 | String legalChars = "abcdefghigklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_'"; 73 | for (int i = 1; i < word.length(); ++i) { 74 | if (legalChars.indexOf(word.charAt(i)) == -1) { 75 | return false; 76 | } 77 | } 78 | return true; 79 | } 80 | 81 | private boolean isBracketsNumLegal(String str) { 82 | int unmatchedLeftBracketsNum = 0; 83 | for (int i = 0; i < str.length(); ++i) { 84 | switch (str.charAt(i)) { 85 | case '[': 86 | ++unmatchedLeftBracketsNum; 87 | break; 88 | case ']': 89 | --unmatchedLeftBracketsNum; 90 | break; 91 | default: 92 | break; 93 | } 94 | if (unmatchedLeftBracketsNum < 0) { 95 | return false; 96 | } 97 | } 98 | return unmatchedLeftBracketsNum == 0; 99 | } 100 | 101 | private Data generateData() throws MuaError { 102 | Data data; 103 | String word = wordCtrler.getNextWord(); 104 | if (word.equals("") || word.equals("]")) { 105 | return null; // As the end of List. 106 | } 107 | data = new Data(word, null); 108 | if (word.equals("[")) { 109 | Data listItem; 110 | while ((listItem = generateData()) != null) { 111 | data.addListItem(listItem); 112 | } 113 | } 114 | return data; 115 | } 116 | 117 | } 118 | -------------------------------------------------------------------------------- /MuaInterpreter/src/mua/operation/MakeOp.java: -------------------------------------------------------------------------------- 1 | package mua.operation; 2 | 3 | import mua.Data; 4 | import mua.NameSpace; 5 | import mua.error.NameError; 6 | import mua.error.TypeError; 7 | 8 | public final class MakeOp extends Operation { 9 | 10 | public MakeOp(Data var0, Data var1) { 11 | arguments = new Data[] { var0, var1 }; 12 | hasReturnValue = false; 13 | opName = "make"; 14 | } 15 | 16 | @Override 17 | public void execute(NameSpace space) throws TypeError, NameError { 18 | String wordValue = arguments[0].getWordValue(); 19 | if (!isLegalOp(wordValue)) { 20 | throw new NameError(arguments[0], "illegal binding name (in " + space.getFunctionName() + ")"); 21 | } 22 | space.addBinding(arguments[0].getWordValue(), arguments[1]); 23 | } 24 | 25 | private boolean isLegalOp(String word) { 26 | if (word == null || word.isEmpty()) { 27 | return false; 28 | } 29 | char fstCh = word.charAt(0); 30 | if (!(fstCh == '_' || ('a' <= fstCh && fstCh <= 'z') || ('A' <= fstCh && fstCh <= 'Z'))) { 31 | return false; 32 | } 33 | String legalChars = "abcdefghigklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_'"; 34 | for (int i = 1; i < word.length(); ++i) { 35 | if (legalChars.indexOf(word.charAt(i)) == -1) { 36 | return false; 37 | } 38 | } 39 | return true; 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /MuaInterpreter/src/mua/operation/Operation.java: -------------------------------------------------------------------------------- 1 | package mua.operation; 2 | 3 | import mua.Data; 4 | import mua.NameSpace; 5 | import mua.error.MuaError; 6 | 7 | public abstract class Operation implements IOperation { 8 | 9 | protected String opName; 10 | protected boolean hasReturnValue; 11 | protected Data[] arguments; 12 | protected Data returnValue; 13 | protected boolean hasAppendData = false; 14 | 15 | public String getOpName() { 16 | return opName; 17 | } 18 | 19 | public int getArgumentsNum() { 20 | return arguments == null ? -1 : arguments.length; // -1 as not initialized. 21 | } 22 | 23 | public Data getArgumentAt(int argumentIndex) { 24 | if (argumentIndex < getArgumentsNum()) { 25 | return arguments[argumentIndex]; 26 | } 27 | return null; 28 | } 29 | 30 | public void execute(NameSpace space) throws MuaError { 31 | } // Subclass overrides and implements this to set return value or handle I/O or operate name space. 32 | 33 | public boolean getHasReturnValue() { 34 | return hasReturnValue; 35 | } 36 | 37 | public Data getReturnValue() { 38 | return hasReturnValue ? returnValue : null; 39 | } 40 | 41 | public boolean getHasAppendedData() { 42 | return hasAppendData; 43 | } 44 | 45 | public Data getAppendedData() { 46 | return null; 47 | } // Subclass overrides and implements this to add data to the operation stack. 48 | 49 | } 50 | -------------------------------------------------------------------------------- /MuaInterpreter/src/mua/operation/OperationHandler.java: -------------------------------------------------------------------------------- 1 | package mua.operation; 2 | 3 | import java.util.HashMap; 4 | 5 | import mua.Data; 6 | import mua.NameSpace; 7 | import mua.error.*; 8 | import mua.operation.operator.*; 9 | 10 | public class OperationHandler { 11 | 12 | @SuppressWarnings("serial") 13 | private static final HashMap opArgsNumMap = new HashMap() {{ 14 | put("make", 2); put("thing", 1); put("erase", 1); put("isname", 1); 15 | put("print", 1); put("read", 0); put("readlist", 0); 16 | put("add", 2); put("sub", 2); put("mul", 2); put("div", 2); put("mod", 2); 17 | put("eq", 2); put("gt", 2); put("lt", 2); 18 | put("and", 2); put("or", 2); put("not", 1); 19 | put("repeat", 2); put("output", 1); put("export", 1); put("stop", 0); 20 | put("random", 1); put("sqrt", 1); put("int", 1); 21 | put("isnumber", 1); put("isword", 1); put("islist", 1); put("isbool", 1); put("isempty", 1); 22 | put("word", 2); put("sentence", 2); put("list", 2); put("join", 2); 23 | put("first", 1); put("last", 1); put("butfirst", 1); put("butlast", 1); 24 | put("wait", 1); 25 | put("erall", 0); put("poall", 0); 26 | put("save", 1); put("load", 1); 27 | put("if", 3); 28 | }}; 29 | 30 | public static int getOpArgsNum(String opName) { 31 | if (!opArgsNumMap.containsKey(opName)) { 32 | return -1; // -1 as not an operation. 33 | } 34 | return opArgsNumMap.get(opName); 35 | } 36 | 37 | public static boolean isOperation(String str) { 38 | return opArgsNumMap.containsKey(str); 39 | } 40 | 41 | private String opName; 42 | private int opArgsNum; 43 | private Operation op; 44 | private final int maxArgumentsNum = 3; // An operation has 3 arguments at most. 45 | private Data[] args = new Data[maxArgumentsNum]; 46 | private int curArgsNum = 0; 47 | private NameSpace space; 48 | 49 | public OperationHandler(String opName, NameSpace space) { 50 | this.opName = opName; 51 | opArgsNum = OperationHandler.getOpArgsNum(opName); 52 | this.space = space; 53 | } 54 | 55 | public int addArg(Data arg) { 56 | if (curArgsNum >= maxArgumentsNum || curArgsNum < 0) { // An operation has 3 arguments at most. 57 | curArgsNum = -1; 58 | return -1; // -1 as too much arguments. 59 | } 60 | args[curArgsNum++] = arg; 61 | return curArgsNum; 62 | } 63 | 64 | public boolean execute() throws MuaError { 65 | if (opArgsNum != curArgsNum || curArgsNum == -1) { 66 | return false; 67 | } 68 | switch (opName) { // Create corresponding operation object. 69 | case "make": op = new MakeOp(args[0], args[1]); break; 70 | case "thing": op = new ThingOp(args[0]); break; 71 | case "erase": op = new EraseOp(args[0]); break; 72 | case "isname": op = new IsnameOp(args[0]); break; 73 | case "print": op = new PrintOp(args[0]); break; 74 | case "read": op = new ReadOp(); break; 75 | case "readlist": op = new ReadlistOp(); break; 76 | case "add": op = new AddOp(args[0], args[1]); break; 77 | case "sub": op = new SubOp(args[0], args[1]); break; 78 | case "mul": op = new MulOp(args[0], args[1]); break; 79 | case "div": op = new DivOp(args[0], args[1]); break; 80 | case "mod": op = new ModOp(args[0], args[1]); break; 81 | case "eq": op = new EqOp(args[0], args[1]); break; 82 | case "gt": op = new GtOp(args[0], args[1]); break; 83 | case "lt": op = new LtOp(args[0], args[1]); break; 84 | case "and": op = new AndOp(args[0], args[1]); break; 85 | case "or": op = new OrOp(args[0], args[1]); break; 86 | case "not": op = new NotOp(args[0]); break; 87 | case "repeat": op = new RepeatOp(args[0], args[1]); break; 88 | case "output": op = new OutputOp(args[0]); break; 89 | case "export": op = new ExportOp(args[0]); break; 90 | case "random": op = new RandomOp(args[0]); break; 91 | case "sqrt": op = new SqrtOp(args[0]); break; 92 | case "int": op = new IntOp(args[0]); break; 93 | case "isnumber": op = new IsnumberOp(args[0]); break; 94 | case "isword": op = new IswordOp(args[0]); break; 95 | case "islist": op = new IslistOp(args[0]); break; 96 | case "isbool": op = new IsboolOp(args[0]); break; 97 | case "isempty": op = new IsemptyOp(args[0]); break; 98 | case "word": op = new WordOp(args[0], args[1]); break; 99 | case "sentence": op = new SentenceOp(args[0], args[1]); break; 100 | case "list": op = new ListOp(args[0], args[1]); break; 101 | case "join": op = new JoinOp(args[0], args[1]); break; 102 | case "first": op = new FirstOp(args[0]); break; 103 | case "last": op = new LastOp(args[0]); break; 104 | case "butfirst": op = new ButfirstOp(args[0]); break; 105 | case "butlast": op = new ButlastOp(args[0]); break; 106 | case "wait": op = new WaitOp(args[0]); break; 107 | case "erall": op = new ErallOp(); break; 108 | case "poall": op = new PoallOp(); break; 109 | case "save": op = new SaveOp(args[0]); break; 110 | case "load": op = new LoadOp(args[0]); break; 111 | case "if": op = new IfOp(args[0], args[1], args[2]); break; 112 | default: return false; 113 | } 114 | op.execute(space); 115 | return true; 116 | } 117 | 118 | public boolean hasReturnValue() { 119 | return op != null ? op.getHasReturnValue() : false; 120 | } 121 | 122 | public Data getReturnValue() { 123 | return hasReturnValue() ? op.getReturnValue() : null; 124 | } 125 | 126 | public boolean hasAppendedData() { 127 | return op != null ? op.getHasAppendedData() : false; 128 | } 129 | 130 | public Data getAppendedData() { 131 | return hasAppendedData() ? op.getAppendedData() : null; 132 | } 133 | 134 | public int getArgsNum() { 135 | return opArgsNum; 136 | } 137 | 138 | } 139 | -------------------------------------------------------------------------------- /MuaInterpreter/src/mua/operation/OutputOp.java: -------------------------------------------------------------------------------- 1 | package mua.operation; 2 | 3 | import mua.Data; 4 | import mua.NameSpace; 5 | 6 | public final class OutputOp extends Operation { 7 | 8 | public OutputOp(Data var0) { 9 | arguments = new Data[] { var0 }; 10 | hasReturnValue = false; 11 | opName = "output"; 12 | } 13 | 14 | @Override 15 | public void execute(NameSpace space) { 16 | space.setReturnValue(arguments[0]); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /MuaInterpreter/src/mua/operation/PoallOp.java: -------------------------------------------------------------------------------- 1 | package mua.operation; 2 | 3 | import mua.Data; 4 | import mua.NameSpace; 5 | 6 | public final class PoallOp extends Operation { 7 | 8 | public PoallOp() { 9 | arguments = new Data[] {}; 10 | hasReturnValue = false; 11 | opName = "poall"; 12 | } 13 | 14 | @Override 15 | public void execute(NameSpace space) { 16 | for (String key : space.getBindingsKeySet()) { 17 | System.out.println(key); 18 | // System.out.print(key); 19 | // System.out.print(" : "); 20 | // System.out.println(space.getlocalSpaceBindingData(key)); 21 | } 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /MuaInterpreter/src/mua/operation/PrintOp.java: -------------------------------------------------------------------------------- 1 | package mua.operation; 2 | 3 | import mua.Data; 4 | import mua.NameSpace; 5 | import mua.error.TypeError; 6 | 7 | public final class PrintOp extends Operation { 8 | 9 | public PrintOp(Data var0) { 10 | arguments = new Data[] { var0 }; 11 | hasReturnValue = false; 12 | opName = "print"; 13 | } 14 | 15 | @Override 16 | public void execute(NameSpace space) throws TypeError { 17 | if (arguments[0].getType() == Data.Type.WORD) { 18 | System.out.println(arguments[0].getWordValue()); 19 | } else { 20 | System.out.println(arguments[0]); 21 | } 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /MuaInterpreter/src/mua/operation/RandomOp.java: -------------------------------------------------------------------------------- 1 | package mua.operation; 2 | 3 | import mua.Data; 4 | import mua.NameSpace; 5 | import mua.error.TypeError; 6 | 7 | public final class RandomOp extends Operation { 8 | 9 | public RandomOp(Data var0) { 10 | arguments = new Data[] { var0 }; 11 | hasReturnValue = true; 12 | opName = "random"; 13 | } 14 | 15 | @Override 16 | public void execute(NameSpace space) throws TypeError { 17 | double argument = arguments[0].getNumberValue(); 18 | if (argument < 0) { 19 | returnValue = new Data(0); 20 | } else { 21 | returnValue = new Data(Math.floor(argument * Math.random())); 22 | } 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /MuaInterpreter/src/mua/operation/ReadOp.java: -------------------------------------------------------------------------------- 1 | package mua.operation; 2 | 3 | import java.util.Scanner; 4 | 5 | import mua.Data; 6 | import mua.NameSpace; 7 | import mua.error.MuaError; 8 | 9 | public final class ReadOp extends Operation { 10 | 11 | public ReadOp() { 12 | arguments = new Data[] {}; 13 | hasReturnValue = true; 14 | opName = "read"; 15 | } 16 | 17 | @Override 18 | public void execute(NameSpace space) throws MuaError { 19 | @SuppressWarnings("resource") 20 | Scanner scanner= new Scanner(System.in); 21 | String word = scanner.next(); 22 | returnValue = new Data(word, null); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /MuaInterpreter/src/mua/operation/ReadlistOp.java: -------------------------------------------------------------------------------- 1 | package mua.operation; 2 | 3 | import java.util.Scanner; 4 | 5 | import mua.Data; 6 | import mua.NameSpace; 7 | import mua.WordCtrler; 8 | import mua.error.*; 9 | 10 | public final class ReadlistOp extends Operation { 11 | 12 | WordCtrler wordCtrler; 13 | 14 | public ReadlistOp() { 15 | arguments = new Data[] {}; 16 | hasReturnValue = true; 17 | opName = "readlist"; 18 | } 19 | 20 | @Override 21 | public void execute(NameSpace space) throws MuaError { 22 | @SuppressWarnings("resource") 23 | Scanner scanner= new Scanner(System.in); 24 | String line = scanner.nextLine(); 25 | line = line.trim(); 26 | if (line.isEmpty()) { 27 | returnValue = new Data("[", null); 28 | return; 29 | } 30 | if (!isBracketsNumLegal(line)) { 31 | throw new SyntaxError(line, "brackets unmatch (in " + space.getFunctionName() + ")"); 32 | } 33 | wordCtrler = new WordCtrler(line); 34 | returnValue = new Data("[", null); 35 | Data listItem; 36 | while ((listItem = generateListItem()) != null) { 37 | returnValue.addListItem(listItem); 38 | } 39 | } 40 | 41 | private boolean isBracketsNumLegal(String str) { 42 | int unmatchedLeftBracketsNum = 0; 43 | for (int i = 0; i < str.length(); ++i) { 44 | switch (str.charAt(i)) { 45 | case '[': 46 | ++unmatchedLeftBracketsNum; 47 | break; 48 | case ']': 49 | --unmatchedLeftBracketsNum; 50 | break; 51 | default: 52 | break; 53 | } 54 | if (unmatchedLeftBracketsNum < 0) { 55 | return false; 56 | } 57 | } 58 | return unmatchedLeftBracketsNum == 0; 59 | } 60 | 61 | private Data generateListItem() throws MuaError { 62 | Data data; 63 | String word = wordCtrler.getNextWord(); 64 | if (word.equals("") || word.equals("]")) { 65 | return null; // As the end of List. 66 | } 67 | data = new Data(word, null); 68 | if (word.equals("[")) { 69 | Data listItem; 70 | while ((listItem = generateListItem()) != null) { 71 | data.addListItem(listItem); 72 | } 73 | } 74 | return data; 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /MuaInterpreter/src/mua/operation/RepeatOp.java: -------------------------------------------------------------------------------- 1 | package mua.operation; 2 | 3 | import java.util.Vector; 4 | 5 | import mua.Data; 6 | import mua.error.TypeError; 7 | 8 | public final class RepeatOp extends Operation { 9 | 10 | private int curTimes = 1; 11 | private int curAppendedDataPos = 0; 12 | private double times; 13 | private Vector dataList; 14 | 15 | public RepeatOp(Data var0, Data var1) throws TypeError { 16 | arguments = new Data[] { var0, var1 }; 17 | hasReturnValue = false; 18 | opName = "repeat"; 19 | hasAppendData = true; 20 | times = arguments[0].getNumberValue(); 21 | dataList = arguments[1].getListValue(); 22 | } 23 | 24 | @Override 25 | public Data getAppendedData() { 26 | if (dataList.isEmpty() || curTimes > times) { 27 | return null; 28 | } 29 | Data retValue = dataList.get(curAppendedDataPos); 30 | if (++curAppendedDataPos == dataList.size()) 31 | { 32 | ++curTimes; 33 | curAppendedDataPos = 0; 34 | } 35 | return retValue; 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /MuaInterpreter/src/mua/operation/SaveOp.java: -------------------------------------------------------------------------------- 1 | package mua.operation; 2 | 3 | import java.io.FileWriter; 4 | import java.io.IOException; 5 | 6 | import mua.Data; 7 | import mua.NameSpace; 8 | import mua.error.TypeError; 9 | 10 | public final class SaveOp extends Operation { 11 | 12 | public SaveOp(Data var0) { 13 | arguments = new Data[] { var0 }; 14 | hasReturnValue = false; 15 | opName = "save"; 16 | } 17 | 18 | @Override 19 | public void execute(NameSpace space) throws TypeError { 20 | try { 21 | FileWriter fileWriter = new FileWriter(arguments[0].getWordValue()); 22 | for (String key : space.getBindingsKeySet()) { 23 | fileWriter.write(key); 24 | fileWriter.write('\n'); 25 | fileWriter.write(space.getlocalSpaceBindingData(key).toString()); 26 | fileWriter.write('\n'); 27 | } 28 | fileWriter.flush(); 29 | fileWriter.close(); 30 | } catch (IOException e) { 31 | System.err.println("InterpreterRunTimeError:"); 32 | e.printStackTrace(); 33 | System.exit(-1); 34 | } 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /MuaInterpreter/src/mua/operation/SentenceOp.java: -------------------------------------------------------------------------------- 1 | package mua.operation; 2 | 3 | import java.util.Vector; 4 | 5 | import mua.Data; 6 | import mua.NameSpace; 7 | import mua.error.TypeError; 8 | 9 | public final class SentenceOp extends Operation { 10 | 11 | public SentenceOp(Data var0, Data var1) { 12 | arguments = new Data[] { var0, var1 }; 13 | hasReturnValue = true; 14 | opName = "sentence"; 15 | } 16 | 17 | @Override 18 | public void execute(NameSpace space) throws TypeError { 19 | Vector newListValue = new Vector(arguments[0].getListValue()); 20 | newListValue.addAll(arguments[1].getListValue()); 21 | returnValue = new Data(newListValue); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /MuaInterpreter/src/mua/operation/SqrtOp.java: -------------------------------------------------------------------------------- 1 | package mua.operation; 2 | 3 | import mua.Data; 4 | import mua.NameSpace; 5 | import mua.error.TypeError; 6 | import mua.error.ValueError; 7 | 8 | public final class SqrtOp extends Operation{ 9 | 10 | public SqrtOp(Data var0) { 11 | arguments = new Data[] { var0 }; 12 | hasReturnValue = true; 13 | opName = "sqrt"; 14 | } 15 | 16 | @Override 17 | public void execute(NameSpace space) throws TypeError, ValueError { 18 | double argument = arguments[0].getNumberValue(); 19 | if (argument < 0) { 20 | throw new ValueError(arguments[0], "sqrt argment < 0 (in " + space.getFunctionName() + ")"); 21 | } 22 | returnValue = new Data(Math.sqrt(argument)); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /MuaInterpreter/src/mua/operation/ThingOp.java: -------------------------------------------------------------------------------- 1 | package mua.operation; 2 | 3 | import mua.Data; 4 | import mua.NameSpace; 5 | import mua.error.NameError; 6 | import mua.error.TypeError; 7 | 8 | public final class ThingOp extends Operation { 9 | 10 | public ThingOp(Data var0) { 11 | arguments = new Data[] { var0 }; 12 | hasReturnValue = true; 13 | opName = "thing"; 14 | } 15 | 16 | @Override 17 | public void execute(NameSpace space) throws TypeError, NameError { 18 | if ((returnValue = space.getWholeSpaceBindingData(arguments[0].getWordValue())) == null) { 19 | throw new NameError(arguments[0], "undefined name (in " + space.getFunctionName() + ")"); 20 | } 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /MuaInterpreter/src/mua/operation/WaitOp.java: -------------------------------------------------------------------------------- 1 | package mua.operation; 2 | 3 | import mua.Data; 4 | import mua.NameSpace; 5 | import mua.error.TypeError; 6 | import mua.error.ValueError; 7 | 8 | public final class WaitOp extends Operation { 9 | 10 | public WaitOp(Data var0) { 11 | arguments = new Data[] { var0 }; 12 | hasReturnValue = true; 13 | opName = "wait"; 14 | } 15 | 16 | @Override 17 | public void execute(NameSpace space) throws TypeError, ValueError { 18 | try { 19 | long sleepTime = (long) arguments[0].getNumberValue(); 20 | if (sleepTime > 0) { 21 | Thread.sleep(sleepTime); 22 | } 23 | } catch (InterruptedException e) { 24 | System.err.println("InterpreterRunTimeError:"); 25 | e.printStackTrace(); 26 | System.exit(-1); 27 | } 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /MuaInterpreter/src/mua/operation/WordOp.java: -------------------------------------------------------------------------------- 1 | package mua.operation; 2 | 3 | import mua.Data; 4 | import mua.NameSpace; 5 | import mua.error.MuaError; 6 | import mua.error.TypeError; 7 | 8 | public final class WordOp extends Operation { 9 | 10 | public WordOp(Data var0, Data var1) { 11 | arguments = new Data[] { var0, var1 }; 12 | hasReturnValue = true; 13 | opName = "word"; 14 | } 15 | 16 | @Override 17 | public void execute(NameSpace space) throws MuaError { 18 | String fstWordValue = arguments[0].getWordValue(); 19 | String sndWordValue; 20 | switch (arguments[1].getType()) { 21 | case BOOL: 22 | sndWordValue = arguments[1].getBoolValue() ? "true" : "false"; 23 | break; 24 | case NUMBER: 25 | sndWordValue = Double.toString(arguments[1].getNumberValue()); 26 | break; 27 | case WORD: 28 | sndWordValue = arguments[1].getWordValue(); 29 | break; 30 | default: 31 | throw new TypeError(arguments[1], "not a word or a number or a bool (in " + space.getFunctionName() + ")"); 32 | } 33 | returnValue = new Data(fstWordValue + sndWordValue); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /MuaInterpreter/src/mua/operation/operator/AddOp.java: -------------------------------------------------------------------------------- 1 | package mua.operation.operator; 2 | 3 | import mua.Data; 4 | import mua.NameSpace; 5 | import mua.error.TypeError; 6 | 7 | public final class AddOp extends Operator { 8 | 9 | public AddOp(Data arg0, Data arg1) { 10 | super("add", arg0, arg1); 11 | } 12 | 13 | @Override 14 | public void execute(NameSpace space) throws TypeError { 15 | returnValue = new Data(arguments[0].getNumberValue() + arguments[1].getNumberValue()); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /MuaInterpreter/src/mua/operation/operator/AndOp.java: -------------------------------------------------------------------------------- 1 | package mua.operation.operator; 2 | 3 | import mua.Data; 4 | import mua.NameSpace; 5 | import mua.error.TypeError; 6 | 7 | public final class AndOp extends Operator { 8 | 9 | public AndOp(Data arg0, Data arg1) { 10 | super("and", arg0, arg1); 11 | } 12 | 13 | @Override 14 | public void execute(NameSpace space) throws TypeError { 15 | returnValue = new Data(arguments[0].getBoolValue() && arguments[1].getBoolValue()); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /MuaInterpreter/src/mua/operation/operator/DivOp.java: -------------------------------------------------------------------------------- 1 | package mua.operation.operator; 2 | 3 | import mua.Data; 4 | import mua.NameSpace; 5 | import mua.error.TypeError; 6 | import mua.error.ValueError; 7 | 8 | public final class DivOp extends Operator { 9 | 10 | public DivOp(Data arg0, Data arg1) { 11 | super("div", arg0, arg1); 12 | } 13 | 14 | @Override 15 | public void execute(NameSpace space) throws ValueError, TypeError { 16 | double divisor = arguments[1].getNumberValue(); 17 | if (divisor == 0) { 18 | throw new ValueError(arguments[1], "division by zero (in " + space.getFunctionName() + ")"); 19 | } 20 | returnValue = new Data(arguments[0].getNumberValue() / divisor); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /MuaInterpreter/src/mua/operation/operator/EqOp.java: -------------------------------------------------------------------------------- 1 | package mua.operation.operator; 2 | 3 | import mua.Data; 4 | import mua.NameSpace; 5 | import mua.error.TypeError; 6 | 7 | public final class EqOp extends Operator { 8 | 9 | public EqOp(Data arg0, Data arg1) { 10 | super("eq", arg0, arg1); 11 | } 12 | 13 | @Override 14 | public void execute(NameSpace space) throws TypeError { 15 | returnValue = new Data(arguments[0].equals(arguments[1])); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /MuaInterpreter/src/mua/operation/operator/GtOp.java: -------------------------------------------------------------------------------- 1 | package mua.operation.operator; 2 | 3 | import mua.Data; 4 | import mua.NameSpace; 5 | import mua.error.TypeError; 6 | 7 | public final class GtOp extends Operator { 8 | 9 | public GtOp(Data arg0, Data arg1) { 10 | super("gt", arg0, arg1); 11 | } 12 | 13 | @Override 14 | public void execute(NameSpace space) throws TypeError { 15 | if (arguments[0].getType() != arguments[1].getType()) { 16 | StringBuffer errorDataStringBuffer = new StringBuffer("gt"); 17 | errorDataStringBuffer.append(' ') 18 | .append(arguments[0]) 19 | .append(' ') 20 | .append(arguments[1]) 21 | .append(" - ") 22 | .append(arguments[0].getTypeString()) 23 | .append(" and ") 24 | .append(arguments[1].getTypeString()); 25 | throw new TypeError(errorDataStringBuffer.toString(), "type not match (in " + space.getFunctionName() + ")"); 26 | } 27 | switch (arguments[0].getType()) { 28 | case BOOL: 29 | returnValue = new Data(arguments[0].getBoolValue() && !arguments[1].getBoolValue()); 30 | break; 31 | case NUMBER: 32 | returnValue = new Data(arguments[0].getNumberValue() > arguments[1].getNumberValue()); 33 | break; 34 | case WORD: 35 | returnValue = new Data(arguments[0].getWordValue().compareTo(arguments[1].getWordValue()) > 0); 36 | break; 37 | default: 38 | throw new TypeError(arguments[0], "unordered type (in " + space.getFunctionName() + ")"); 39 | } 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /MuaInterpreter/src/mua/operation/operator/LtOp.java: -------------------------------------------------------------------------------- 1 | package mua.operation.operator; 2 | 3 | import mua.Data; 4 | import mua.NameSpace; 5 | import mua.error.TypeError; 6 | 7 | public final class LtOp extends Operator { 8 | 9 | public LtOp(Data arg0, Data arg1) { 10 | super("lt", arg0, arg1); 11 | } 12 | 13 | @Override 14 | public void execute(NameSpace space) throws TypeError { 15 | if (arguments[0].getType() != arguments[1].getType()) { 16 | StringBuffer errorDataStringBuffer = new StringBuffer("gt"); 17 | errorDataStringBuffer.append(' ') 18 | .append(arguments[0]) 19 | .append(' ') 20 | .append(arguments[1]) 21 | .append(" - ") 22 | .append(arguments[0].getTypeString()) 23 | .append(" and ") 24 | .append(arguments[1].getTypeString()); 25 | throw new TypeError(errorDataStringBuffer.toString(), "type not match (in " + space.getFunctionName() + ")"); 26 | } 27 | switch (arguments[0].getType()) { 28 | case BOOL: 29 | returnValue = new Data(!arguments[0].getBoolValue() && arguments[1].getBoolValue()); 30 | break; 31 | case NUMBER: 32 | returnValue = new Data(arguments[0].getNumberValue() < arguments[1].getNumberValue()); 33 | break; 34 | case WORD: 35 | returnValue = new Data(arguments[0].getWordValue().compareTo(arguments[1].getWordValue()) < 0); 36 | break; 37 | default: 38 | throw new TypeError(arguments[0], "unordered type (in " + space.getFunctionName() + ")"); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /MuaInterpreter/src/mua/operation/operator/ModOp.java: -------------------------------------------------------------------------------- 1 | package mua.operation.operator; 2 | 3 | import mua.Data; 4 | import mua.NameSpace; 5 | import mua.error.TypeError; 6 | import mua.error.ValueError; 7 | 8 | public final class ModOp extends Operator { 9 | 10 | public ModOp(Data arg0, Data arg1) { 11 | super("mod", arg0, arg1); 12 | } 13 | 14 | @Override 15 | public void execute(NameSpace space) throws ValueError, TypeError { 16 | double divisor = arguments[1].getNumberValue(); 17 | if (divisor == 0) { 18 | throw new ValueError(arguments[1], "modulo by zero (in " + space.getFunctionName() + ")"); 19 | } 20 | returnValue = new Data(arguments[0].getNumberValue() % divisor); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /MuaInterpreter/src/mua/operation/operator/MulOp.java: -------------------------------------------------------------------------------- 1 | package mua.operation.operator; 2 | 3 | import mua.Data; 4 | import mua.NameSpace; 5 | import mua.error.TypeError; 6 | 7 | public final class MulOp extends Operator { 8 | 9 | public MulOp(Data arg0, Data arg1) { 10 | super("mul", arg0, arg1); 11 | } 12 | 13 | @Override 14 | public void execute(NameSpace space) throws TypeError { 15 | returnValue = new Data(arguments[0].getNumberValue() * arguments[1].getNumberValue()); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /MuaInterpreter/src/mua/operation/operator/NotOp.java: -------------------------------------------------------------------------------- 1 | package mua.operation.operator; 2 | 3 | import mua.Data; 4 | import mua.NameSpace; 5 | import mua.error.TypeError; 6 | 7 | public final class NotOp extends Operator { 8 | 9 | public NotOp(Data arg0) { 10 | super("not", arg0, null); 11 | } 12 | 13 | @Override 14 | public void execute(NameSpace space) throws TypeError { 15 | returnValue = new Data(!arguments[0].getBoolValue()); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /MuaInterpreter/src/mua/operation/operator/Operator.java: -------------------------------------------------------------------------------- 1 | package mua.operation.operator; 2 | 3 | import mua.Data; 4 | import mua.operation.Operation; 5 | 6 | public abstract class Operator extends Operation { 7 | 8 | Operator(String opName, Data arg0, Data arg1) { 9 | arguments = new Data[arg1 == null ? 1 : 2]; 10 | arguments[0] = arg0; 11 | if (arg1 != null) { 12 | arguments[1] = arg1; 13 | } 14 | hasReturnValue = true; 15 | super.opName = opName; 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /MuaInterpreter/src/mua/operation/operator/OrOp.java: -------------------------------------------------------------------------------- 1 | package mua.operation.operator; 2 | 3 | import mua.Data; 4 | import mua.NameSpace; 5 | import mua.error.TypeError; 6 | 7 | public final class OrOp extends Operator { 8 | 9 | public OrOp(Data arg0, Data arg1) { 10 | super("or", arg0, arg1); 11 | } 12 | 13 | @Override 14 | public void execute(NameSpace space) throws TypeError { 15 | returnValue = new Data(arguments[0].getBoolValue() || arguments[1].getBoolValue()); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /MuaInterpreter/src/mua/operation/operator/SubOp.java: -------------------------------------------------------------------------------- 1 | package mua.operation.operator; 2 | 3 | import mua.Data; 4 | import mua.NameSpace; 5 | import mua.error.TypeError; 6 | 7 | public final class SubOp extends Operator { 8 | 9 | public SubOp(Data arg0, Data arg1) { 10 | super("sub", arg0, arg1); 11 | } 12 | 13 | @Override 14 | public void execute(NameSpace space) throws TypeError { 15 | returnValue = new Data(arguments[0].getNumberValue() - arguments[1].getNumberValue()); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MUA解释器 2 | 3 | `任皓天 3150104714@zju.edu.cn Haotian_Ren@outlook.com` 4 | 5 | ### Contents 6 | 7 | [解释器实现内容](#mua解释器的实现内容) 8 | 9 | [操作实现方法](#操作实现方法) 10 | 11 | [Error处理](error处理) 12 | 13 | [MUA代码样例](#mua代码样例) 14 | 15 | [源代码结构](#源代码结构) 16 | 17 | ## MUA(Make Up Programming Language) 18 | 19 | ### 基本数据类型 20 | 21 | 数字`number`,字`word`,表`list`,布尔`bool` 22 | 23 | - 数字的字面量以`[0~9]`或`'-'`开头,不区分整数,浮点数 24 | - 字的字面量以双引号`"`开头,不含空格,采用Unicode编码。在`"`后的任何内容,直到空格(包括空格、tab和回车)为止的字符都是这个字的一部分,包括其中可能有的`"`和`[]`等符号 25 | - 表的字面量以方括号`[]`包含,其中的元素以空格分隔;元素可是任意类型;元素类型可不一致 26 | 27 | ### 基本操作 28 | 29 | 基本形式:操作名 参数 30 | 31 | 操作名是一个不含空格的词,与参数间以空格分隔。参数可以有多个,多个参数间以空格分隔。每个操作所需的参数数量是确定的,所以不需要括号或语句结束符号。有的操作有返回值,有的没有。 32 | 33 | 一个程序就是操作的序列。 34 | 35 | 基本操作有: 36 | 37 | - `//`:注释 38 | - `make `: 将value绑定到word上。基本操作的字不能用做这里的word。绑定后的word称作名字,位于命名空间。 39 | - `thing `:返回word所绑定的值 40 | - `:`:与thing相同 41 | - `erase `:清除word所绑定的值 42 | - `isname `:返回word是否是一个名字,true/false 43 | - `print `:输出value 44 | - `read`:返回一个从标准输入读取的数字或字 45 | - `readlinst`:返回一个从标准输入读取的一行,构成一个表,行中每个以空格分隔的部分是list的一个元素 46 | - 运算符operator 47 | - `add`, `sub`, `mul`, `div`, `mod`:` ` 48 | - `eq`, `gt`, `lt`:` ` 49 | - `and`, `or`:` ` 50 | - `not`:`not ` 51 | - `repeat `:运行list中的代码number次 52 | 53 | ### 函数定义和调用 54 | 55 | #### 定义 56 | 57 | ``` 58 | make [ ] 59 | word为函数名 60 | list1为参数表 61 | list2为操作表 62 | ``` 63 | 64 | #### 调用 65 | 66 | ``` 67 | 68 | 为make中定义的函数名,不需要双引号" 69 | 是参数表,中的值和函数定义时的中名字进行一一对应绑定 70 | ``` 71 | 72 | #### 函数相关的操作 73 | 74 | - `output `:设定value为返回给调用者的值,但是不停止执行 75 | - `stop`:停止执行 76 | - `export`:将本地make的值输出到全局 77 | 78 | ### 表达式计算 79 | 80 | 允许使用以下运算符对数字进行计算: 81 | 82 | ``` 83 | +-*/%() 84 | ``` 85 | 86 | 为了方便识别,解释器的实现可以要求表达式的外面有括号包围。 87 | 88 | **** 89 | 90 | - `random `:返回[0,number)的一个随机数 91 | - `sqrt `:返回number的平方根 92 | - `isnumber `:返回value是否是数字 93 | - `isword `:返回value是否是字 94 | - `islist `:返回value是否是表 95 | - `isbool `:返回value是否是布尔量 96 | - `isempty `: 返回word或list是否是空 97 | - `int `: floor the int 98 | - `word `:将两个word合并为一个word,第二个值可以是word、number或bool 99 | - `if `:如果bool为真,则执行list1,否则执行list2。list均可以为空表 100 | - `sentence `:将list1和list2合并成一个表,两个表的元素并列,list1的在list2的前面 101 | - `list `:将两个值合并为一个表,如果值为表,则不打开这个表 102 | - `join `:将value作为list的最后一个元素加入到list中(如果value是表,则整个value成为表的最后一个元素) 103 | - `first `:返回word的第一个字符,或list的第一个元素 104 | - `last `:返回word的最后一个字符,list的最后一个元素 105 | - `butfirst `:返回除第一个元素外剩下的表,或除第一个字符外剩下的字 106 | - `butlast `:返回除最后一个元素外剩下的表,或除最后一个字符外剩下的字 107 | - `stop`:停止当前代码的执行。当前代码可能是run、repeat、if或函数中的代码 108 | - `wait `:等待number个ms 109 | - `save `:保存当前命名空间在word文件中 110 | - `load `:从word文件中装载内容,加入当前命名空间 111 | - `erall`:清除当前命名空间的全部内容 112 | - `poall`:列出当前命名空间的全部名字 113 | 114 | ### 既有名字 115 | 116 | 系统提供了一些常用的量,或可以由其他操作实现但是常用的操作,作为固有的名字。这些名字是可以被删除(erase)的。 117 | 118 | - `pi`:3.14159 119 | - `run `:运行list中的代码 120 | 121 | ## MUA解释器的实现内容 122 | 123 | ### 第一部分实现内容集合 124 | 125 | #### 基本数据类型 126 | 127 | - 数字`number`:字面量使用数字的通用表示方法 128 | 129 | ![](./readme_images/number_demo.png) 130 | 131 | - 单词`word`:字面量以西文双引号`"`开头,以空白字符结尾,西文双引号到空白字符之间的字符串为单词的真实值 132 | 133 | ![](./readme_images/word_demo.png) 134 | 135 | - 布尔`bool`:字面量为`true`和`false` 136 | 137 | ![](./readme_images/bool_demo.png) 138 | 139 | - 列表`list`:字面量`[`开头,以`]`结尾,列表中的元素可以为任意类型,以空白符作为间隔符 140 | 141 | ![](./readme_images/list_demo.png) 142 | 143 | 由于列表在被直接释放到解释器时会被执行,所以采用print的方式进行输出演示。 144 | 145 | #### 基本操作 146 | 147 | - `make `: 将value绑定到word上。基本操作的单词不能用做这里的word。绑定后的word称作名字,位于命名空间。 148 | 149 | ![](./readme_images/make_demo.png) 150 | 151 | - `thing `:返回word所绑定的值 152 | 153 | ![](./readme_images/thing_demo.png) 154 | 155 | - `:`:与`thing `相同 156 | 157 | ![](./readme_images/colon_demo.png) 158 | 159 | 事实上在具体实现中,`:`操作为`thing`操作得语法糖,可以通过以下过程进行体现: 160 | 161 | ![modification_colon](./readme_images/modification_colon.png) 162 | 163 | - `erase `:清除word所绑定的值 164 | 165 | ![](./readme_images/erase_demo.png) 166 | 167 | - `isname `:返回word是否是一个名字,true/false 168 | 169 | ![](./readme_images/isname_demo.png) 170 | 171 | - `print `:输出value 172 | 173 | ![](./readme_images/print_demo.png) 174 | 175 | - `read`:返回一个从标准输入读取的数字或单词 176 | 177 | ![](./readme_images/read_demo.png) 178 | 179 | - `readlist`:返回一个从标准输入读取的一行,构成一个列表,行中每个以空格分隔的部分是list的一个元素 180 | 181 | ![](./readme_images/readlist_demo.png) 182 | 183 | - 运算符operator 184 | - `add`, `sub`, `mul`, `div`, `mod`:` ` 185 | 186 | ![](./readme_images/add_sub_mul_div_mod_demo.png) 187 | 188 | - `eq`:` ` 189 | 190 | ![](./readme_images/eq_demo.png) 191 | 192 | - `gt`, `lt`:` ` 193 | 194 | ![](./readme_images/gt_lt_demo.png) 195 | 196 | - `and`, `or`:` ` 197 | 198 | ![](./readme_images/and_or_demo.png) 199 | 200 | - `not`:`not ` 201 | 202 | ![](./readme_images/not_demo.png) 203 | 204 | ### 第二部分实现内容集合 205 | 206 | #### 函数定义和调用 207 | 208 | - 函数定义 209 | 210 | ``` 211 | make [ ] 212 | word为函数名 213 | list1为参数列表 214 | list2为操作列表 215 | ``` 216 | 217 | 演示: 218 | 219 | ![demo_function_definition](./readme_images/demo_function_definition.png) 220 | 221 | 如上图所示便完成了一个函数`another_print`的创建,通过`print`操作我们可以看出函数实际上使用`word`与一个具有函数格式的`list`绑定进行存储。 222 | 223 | - 调用 224 | 225 | ``` 226 | 227 | 为make中定义的函数名,不需要双引号" 228 | 是参数列表,中的值和函数定义时的中名字进行一一对应绑定 229 | ``` 230 | 231 | 演示: 232 | 233 | ![demo_function_call](./readme_images/demo_function_call.png) 234 | 235 | - 函数相关的操作 236 | - `output `:设定value为返回给调用者的值,但是不停止执行 237 | 238 | 演示: 239 | 240 | ![demo_output](./readme_images/demo_output.png) 241 | 242 | - `export `:将word及word所绑定的值从当前所执行函数的命名空间导出到全局命名空间 243 | 244 | 演示: 245 | 246 | ![demo_export](./readme_images/demo_export.png) 247 | 248 | - `stop`:停止函数执行 249 | 250 | 演示: 251 | 252 | ![demo_stop](./readme_images/demo_stop.png) 253 | 254 | #### 表达式计算 255 | 256 | 表达式以西文左圆括号开始,以西文右圆括号结束,使用中缀运算符用于进行number类型以及bool类型的计算,要求中缀运算符的左右使用空白符进行间隔。 257 | 258 | - number类型可以应用两种类型的中缀运算符: 259 | - 返回值为number类型的运算符:`+` `-` `*` `/` `%` 260 | 261 | 演示: 262 | 263 | ![demo_exp_number1](./readme_images/demo_exp_number1.png) 264 | 265 | - 返回值为bool类型的运算符:`>` `<` `==` 266 | 267 | 演示: 268 | 269 | ![demo_exp_number2](./readme_images/demo_exp_number2.png) 270 | 271 | - bool类型可以应用的中缀运算符返回值均为bool类型,包括:`&&` `||` 272 | 273 | 演示: 274 | 275 | ![demo_exp_bool](./readme_images/demo_exp_bool.png) 276 | 277 | #### `repeat`操作 278 | 279 | `repeat `:运行list中的代码[number]次 280 | 281 | 演示: 282 | 283 | ![demo_repeat](./readme_images/demo_repeat.png) 284 | 285 | ### 第三部分实现内容集合 286 | 287 | #### `if`操作 288 | 289 | `if `:如果bool为真,则执行list1,否则执行list2。 290 | 291 | ![](./readme_images/if_demo.png) 292 | 293 | #### `number`相关操作 294 | 295 | - `random `:返回[0,number)的一个随机数 296 | 297 | ![](./readme_images/random_demo.png) 298 | 299 | - `sqrt `:返回number的平方根 300 | 301 | ![](./readme_images/sqrt_demo.png) 302 | 303 | - `int `: floor the int 304 | 305 | ![](./readme_images/int_demo.png) 306 | 307 | #### `word`及`list`相关操作 308 | 309 | - `word `:将两个word合并为一个word,第二个值可以是word、number或bool 310 | 311 | ![](./readme_images/word_op_demo.png) 312 | 313 | - `list `:将两个值合并为一个表,如果值为表,则不打开这个表 314 | 315 | ![](./readme_images/list_op_demo.png) 316 | 317 | - `sentence `:将list1和list2合并成一个表,两个表的元素并列,list1的在list2的前面 318 | 319 | ![](./readme_images/sentence_demo.png) 320 | 321 | 为`sentence`操作实现了中缀运算形式,类比Haskell使用`++`运算符: 322 | 323 | ![](./readme_images/infix_sentence_demo.png) 324 | 325 | - `join `:将value作为list的最后一个元素加入到list中(如果value是表,则整个value成为表的最后一个元素) 326 | 327 | ![](./readme_images/join_demo.png) 328 | 329 | - `first `:返回word的第一个字符,或list的第一个元素 330 | 331 | - `last `:返回word的最后一个字符,list的最后一个元素 332 | 333 | ![](./readme_images/first_last_demo.png) 334 | 335 | - `butfirst `:返回除第一个元素外剩下的表,或除第一个字符外剩下的字 336 | 337 | - `butlast `:返回除最后一个元素外剩下的表,或除最后一个字符外剩下的字 338 | 339 | ![](./readme_images/butfirst_butlast_demo.png) 340 | 341 | - `isempty `: 返回word或list是否是空 342 | 343 | ![](./readme_images/isempty_demo.png) 344 | 345 | #### 命名空间相关操作 346 | 347 | - `save `:保存当前命名空间在word文件中 348 | - `load `:从word文件中装载内容,加入当前命名空间 349 | - `erall`:清除当前命名空间的全部内容 350 | - `poall`:列出当前命名空间的全部名字 351 | 352 | ![](./readme_images/namespace_op_demo.png) 353 | 354 | 以以上为例,首先使用`poall`可以看出当前命名空间存在`pi`和`run`两个名字绑定,我们使用`save`将其保存到文件`space`中然后使用`erall`清空当前命名空间,再次`poall`便无输出,随后使用`load`从`space`文件中重新加载命名空间,`poall`便可以重新看到加载回的`pi`和`run`。 355 | 356 | ![](./readme_images/namespace_op_demo2.png) 357 | 358 | 通过以上操作可以看出`load`操作的**加载**而非覆盖方式,即其不会影响到原有的命名空间。 359 | 360 | 若尝试从一个不存在的文件中读取则会报错,如下: 361 | 362 | ![](./readme_images/load_not_exist_demo.png) 363 | 364 | #### 类型判断操作 365 | 366 | - `isnumber `:返回value是否是数字 367 | - `isword `:返回value是否是字 368 | - `islist `:返回value是否是表 369 | - `isbool `:返回value是否是布尔量 370 | 371 | ![](./readme_images/is_type_demo.png) 372 | 373 | #### `wait`操作 374 | 375 | `wait `:等待number个ms 376 | 377 | 如下图所示,即每1s输出一次“-1s”,代表时间流逝了1s: 378 | 379 | ![](./readme_images/wait_demo_1.png) 380 | 381 | 运行到一半时,如上图,5s后运行结束如下图: 382 | 383 | ![](./readme_images/wait_demo_2.png) 384 | 385 | #### 既有名字 386 | 387 | 系统提供了一些常用的量,或可以由其他操作实现但是常用的操作,作为固有的名字。这些名字是可以被删除(erase)的。 388 | 389 | - `pi`:3.14159 390 | - `run `:运行list中的代码 391 | 392 | ![](./readme_images/ori_names_demo.png) 393 | 394 | ## 操作实现方法 395 | 396 | ### 基本数据类型 397 | 398 | 在`mua`包中的`Data.java`文件中定义了MUA中的基本数据类型: 399 | 400 | ```java 401 | class Data { 402 | public enum Type { 403 | UNDEFINED, NUMBER, WORD, LIST, BOOL, OP 404 | } 405 | private Type type = Type.UNDEFINED; 406 | private double numberValue; 407 | private String wordValue; 408 | private Vector listValue; 409 | private boolean boolValue; 410 | // 类方法... 411 | } 412 | ``` 413 | 414 | 在对MUA解释器的实现时基于MUA的类型系统进行了如下设计: 415 | 416 | - 一切皆为视为数据`Data`,在MUA语言中任意语法正确的一部分均为一个或多个数据所组成的集合。 417 | 418 | - 强类型系统,数据可以分为以下六种类型: 419 | 420 | 未定义`UNDEFINED`、数字`NUMBER`、单词`WORD`、列表`LIST`、布尔`BOOL`、操作`OP`。其中,未定义表示类数据不会在MUA解释器层面出现,它在JVM中用于表示未进行初始化的数据;数字、单词、列表、布尔是四种拥有字面量表示方法的基本数据类型;操作类型用来表示MUA所提供的基本操作,但设计其所表示的范围较为广泛,它用来表示MUA中无需前导符进行修饰的单词,所实现的函数也采用这一类型。 421 | 422 | 此外,在`Data.java`文件中通过对Data类的定义实现了数据的各种构造方法,并Override了Object类的`toString`方法以及`equals`方法。 423 | 424 | ### 解释器核心 425 | 426 | MUA解释器的核心部分定义于`mua`包的`DataOperationStack.java`文件中,称其为“符号操作栈”。 427 | 428 | 由于MUA语言所拥有的以下三个特性: 429 | 430 | - 在对MUA解释器的设计中,一切均为数据 431 | - MUA程序的本质就是一系列操作的集合 432 | - MUA程序除表达式外不采用括号进行优先级的控制 433 | 434 | 因此MUA解释器的本质就是对来自通过对MUA代码处理获得的接连数据进行操作,没有特殊的优先级处理使得栈成为进行操作的理想数据结构。 435 | 436 | 现假设我们已经执行`make "a 233`语句,则`print eq thing "a sub 234 1`语句在数据操作栈上进行操作的过程如下所示: 437 | 438 | 1. 获得`op`类型数据`print`,压入数据操作栈: 439 | 440 | ||`print`|... 441 | 442 | 2. 获得`op`类型数据`eq`,压入数据操作栈: 443 | 444 | ||`print`|`eq`|... 445 | 446 | 3. 获得`op`类型数据`thing`,压入数据操作栈: 447 | 448 | ||`print`|`eq`|`thing`|... 449 | 450 | 4. 获得`word`类型数据`"a`,与`op`类型数据`thing`进行一次操作,从命名空间获得`number`类型数据`233`,压入数据操作栈: 451 | 452 | ||`print`|`eq`|`233`|... 453 | 454 | 5. 获得`op`类型数据`sub`,压入数据操作栈: 455 | 456 | ||`print`|`eq`|`233`|`sub`|... 457 | 458 | 6. 获得`number`类型数据`234`,压入数据操作栈: 459 | 460 | ||`print`|`eq`|`233`|`sub`|`234`|... 461 | 462 | 7. 获得`number`类型数据`1`,与`op`类型数据`sub`连同`number`类型数据`234`进行一次操作,获得返回值`number`类型数据`233`,其后数据操作栈中变化如下所示: 463 | 464 | ||`print`|`eq`|`233`|`233`|... 465 | 466 | ||`print`|`true`|... 467 | 468 | 8. 随后,解释器在标准输出中输出"true",数据操作栈回归空状态。 469 | 470 | **注:** 471 | 472 | 1. 实际操作时仅一个数据操作栈是无法以上过程的,还另外需要一个栈用来保存数据操作栈中`op`类型数据的信息以及状态。 473 | 474 | 2. 显然,因为只有`op`类型数据可以减少数据操作栈中的元素,多余数据的输入会导致栈的膨胀以及内存的无意义占用,采用空栈时类型检测的方法处理得以解决这一问题,即当栈为空时,检测入栈数据类型,当类型不为`op`或`list`时则进行相应操作后不入数据操作栈,实际上进行处理时,若这一过程发生在函数内,则将其直接丢弃,若发生在函数外,则采用类似其它解释器交互界面处理方法将其内容按照一定格式进行输出,如下: 475 | 476 | ![operation_implement_empty_stack_print](./readme_images/operation_implement_empty_stack_print.png) 477 | 478 | 此外,解释器对于一些特殊的操作提供了增添数据的接口,借助这一接口,`repeat`、`if`等操作可以在其执行时为数据操作栈中压入新的数据。 479 | 480 | ### 命名空间 481 | 482 | 命名空间及其相关操作定义于`mua`包的`NameSpace.java`文件中。 483 | 484 | 命名空间设计基于如下原则: 485 | 486 | - 对于函数功能,而每一个函数在执行时都拥有自己的独立命名空间,因此无法不能使用静态的命名空间,命名空间需要进行动态的分配,并且需要在运行时与相应的符号操作栈进行动态的绑定。 487 | 488 | 489 | - 由于我们可以在函数中执行如下操作:调用函数、定义新函数,因此根据函数闭包的特性,内部函数需要可以使用外部函数的命名空间内容,并且任何函数均应可以做到对于全局命名空间的使用,故采用了类似JavaScript原型链的方式进行实现,除全局命名空间以外,每一个命名空间拥有一个父命名空间,当查询绑定时若在当前命名空间中未查询到,则在父命名空间中进行递归查询。 490 | - 由于每一个函数都可以使用`output`操作制定一个返回值,而由于一个函数使用一个相互绑定的数据操作栈与命名空间,保证数据操作栈仅进行数据操作,因此将返回值存储于自身所拥有的命名空间中,故返回值还需要相应的需要拥有一个返回值属性用于`output`操作。 491 | 492 | 综上所述,设计命名空间的结构如下: 493 | 494 | ```java 495 | public class NameSpace { 496 | private HashMap wordDataBindings = new HashMap(); 497 | private Data returnValue; 498 | private String functionName; // Not function space will be "[Main]". 499 | private boolean isFunctionSpace; // Whether the space is for a function. 500 | private NameSpace parentSpace; // The parent space of a function is where its caller from. 501 | // Class methods... 502 | } 503 | ``` 504 | 505 | 命名空间拥有`save`和`load`两个和文件相关的操作,文件的具体格式如下: 506 | 507 | 我们以`util`文件(已附:[util](util))为例:(该文件会在**实现快排算法**部分说明) 508 | 509 | 文件内容如下: 510 | 511 | ![](./readme_images/util_content.png) 512 | 513 | 用于进行`save`和`load`两个操作的文件为以行进行组织的字符文件,其中奇数行为用于进行绑定的名字,奇数行后相连的偶数行为名字所绑定的数据。可以看出,在`util`文件中存在4个绑定,分别为`qsort`、`fact`、`pi`、`run`,其中第2、4、6、8行的内容即是它们分别所绑定的内容。(`qsort`、`fact`会在MUA代码样例部分进行说明,`pi`、`run`即是可以`erase`的既有名字。) 514 | 515 | ### 函数操作 516 | 517 | 函数操作定义在`mua`包的`FunctionHandler.java`文件中。 518 | 519 | 对于函数操作,我们需要进行的核心操作包括以下: 520 | 521 | - 函数检测 522 | 523 | 确定一个数据的格式是否满足函数的格式,即数据的类型应为`list`,且`list`内部的数据应为两个`list`类型的数据,其中第一个数据应为参数列表形式的`list`。 524 | 525 | - 函数参数的值绑定 526 | 527 | 即将函数参数列表中的parameters在函数所拥有的命名空间中与实际的arguments进行绑定。 528 | 529 | - 函数执行 530 | 531 | 即使用函数的数据操作栈以及命名空间对函数体的内容进行执行。 532 | 533 | 由此,`FunctionHandler`类中的属性以及其中所必须的几个方法如下: 534 | 535 | ```java 536 | public class FunctionHandler { 537 | private boolean isFunction; 538 | private String functionName; 539 | private int argsNum; 540 | private Vector parameters = new Vector(); 541 | private Data functionBody; 542 | private NameSpace functionSpace; 543 | private DataOperationStack dataOperationStack; 544 | private int curArgsNum = 0; 545 | public FunctionHandler(String functionName, NameSpace callerSpace) throws TypeError; // Shall initialize all class properties. 546 | public boolean getIsFunction(); 547 | public void addArg(Data arg) throws NameError; // Add parameter and argument value binding to function space. 548 | public void execute() throws MuaError; 549 | public boolean hasReturnValue(); 550 | public Data getReturnValue(); 551 | // Other class methods... 552 | } 553 | ``` 554 | 555 | 对于函数定义与操作的字面量定义: 556 | 557 | ``` 558 | make [ ] 559 | word为函数名 560 | list1为参数列表 561 | list2为操作列表 562 | 563 | 为make中定义的函数名,不需要双引号" 564 | 是参数列表,中的值和函数定义时的中名字进行一一对应绑定 565 | ``` 566 | 567 | 我们以以下函数为例: 568 | 569 | ![example_function](./readme_images/operation_implement_function1.png) 570 | 571 | 则该函数拥有的参数表中有一个形参,为`a`,函数体为`make "square_a mul :a :a output :square_a`,现在我们执行如下内容: 572 | 573 | ![operation_implement_function2](./readme_images/operation_implement_function2.png) 574 | 575 | 其执行流程如下: 576 | 577 | 1. 主数据操作栈获得`print`,检测到为操作,将其压入主数据操作栈中; 578 | 579 | 2. 主数据操作栈获得`demo_square`,进行函数检测,确定`demo_square`为一个函数; 580 | 581 | 3. 主数据操作栈获得`10`,将数据`10`传递给函数`demo_square`; 582 | 583 | 4. 函数`demo_square`将parameter`a`与argument`10`在自己的命名空间中进行绑定; 584 | 585 | 此时函数的命名空间中拥有1个绑定,未设定返回值: 586 | 587 | ``` 588 | functionName: demo_square 589 | a -> 10 :: number 590 | (returnValue: null) 591 | ``` 592 | 593 | 5. 函数`demo_square`将函数体的内容压入自己的数据操作栈中: 594 | 595 | 1. `make "square_a mul :a :a`部分完全压入后,函数将`square_a`与`mul`操作所获得的平方值`number`类型数据`100`在自己的命名空间中进行绑定; 596 | 597 | (其中,当遇到`:a`时,函数的数据操作栈从命名空间中取出与`a`所绑定的`number`类型数据`10`) 598 | 599 | 此时函数的命名空间中拥有2个绑定,未设定返回值: 600 | 601 | ``` 602 | functionName: demo_square 603 | a -> 10 :: number 604 | square_a -> 100 :: number 605 | (returnValue: null) 606 | ``` 607 | 608 | `output :square_a`部分完全压入后,函数将自己命名空间中与`square_a`所绑定的值`number`类型数据`100`作为自己的返回值,写在自己的命名空间中供自己的的调用者使用; 609 | 610 | 此时函数的命名空间中拥有2个绑定,设定了返回值`100`: 611 | 612 | ``` 613 | functionName: demo_square 614 | a -> 10 :: number 615 | square_a -> 100 :: number 616 | (returnValue: 100 :: number) 617 | ``` 618 | 619 | 6. 主数据操作栈从`demo_square`的命名空间中检测其是否存在返回值,检测到返回值后将其返回值取出压入主数据操作栈; 620 | 621 | 7. `print`操作获取到`100`,将其输出,我们即在标准输出看到100: 622 | 623 | ![operation_implement_function2](./readme_images/operation_implement_function2.png) 624 | 625 | ### 表达式处理 626 | 627 | 表达式处理定义在`mua`包的`DataGenerator.java`文件中`DataGenerator`类的静态内部类`ExpressionProcessor`。 628 | 629 | 在表达式计算中,存在以下4个概念: 630 | 631 | - 中缀操作符 632 | 633 | 中缀操作符为MUA语言中的特殊操作符,仅存在于表达式中,拥有两个参数,分别位于中缀操作符的两侧。 634 | 635 | - 对应关系 636 | 637 | 每一个中缀操作符拥有一个相对应的前缀操作符,该前缀操作符接受两个参数,第一个参数为其对应中缀操作符左侧的参数,第二个运算符为中缀操作符右侧的参数。前缀操作符与中缀操作符的对应方式较类似于Haskell,但MUA的中缀操作符无法自定义,且受限于表达式中,并在中缀操作符左右要求空白符等分隔符: 638 | 639 | - Haskell: 640 | 641 | ![operation_implement_exp_haskell](./readme_images/operation_implement_exp_haskell_infix.png) 642 | 643 | - MUA: 644 | 645 | ![operation_implement_exp_mua_infix](./readme_images/operation_implement_exp_mua_infix.png) 646 | 647 | 此外为中缀表达式的自定义实现方式预留了接口。 648 | 649 | | 前缀操作符 | 对应的中缀操作符 | 650 | | :------: | :------: | 651 | | mul | * | 652 | | div | / | 653 | | mod | % | 654 | | add | + | 655 | | sub | - | 656 | | and | && | 657 | | or | \|\| | 658 | | gt | > | 659 | | lt | < | 660 | | eq | == | 661 | | sentence | ++ | 662 | 663 | - 优先级 664 | 665 | 由于MUA语言的特性,前缀操作符在具体使用时不存在优先级,但是中缀表达式在具体使用时需要进行优先级的考虑,采用使用一个`int`类型数值表示其优先级,数值越大则优先级越高,部分优先级数值借鉴于Haskell,相关值设定如下: 666 | 667 | | 中缀运算符 | 优先级 | 668 | | :---: | :--: | 669 | | * | 7 | 670 | | / | 7 | 671 | | % | 7 | 672 | | + | 6 | 673 | | - | 6 | 674 | | && | 3 | 675 | | \|\| | 2 | 676 | | > | 4 | 677 | | < | 4 | 678 | | == | 4 | 679 | | ++ | 5 | 680 | 681 | - 表达式边界 682 | 683 | 表达式使用西文左括号`(`以及西文右括号`)`界定表达式的边界,由此对于在数字运算的表达式中使用括号进行优先级控制实际上是在生成了表达式内嵌表达式。 684 | 685 | 如对于表达式`((1 + 1) * 5)`实际上是在外层表达式中拥有一个内嵌表达式`(1 + 1)`。 686 | 687 | 688 | 事实上表达式的本质与冒号操作符相同,属于MUA语言的语法糖,可以采用以下过程体现: 689 | 690 | ![operation_implement_exp_sugar](./readme_images/operation_implement_exp_sugar.png) 691 | 692 | 另一个较为复杂的例子: 693 | 694 | ![operation_implement_exp_sugar_complex](./readme_images/operation_implement_exp_sugar_complex.png) 695 | 696 | 因此基于实现,MUA解释器实际上对表达式所做的工作为将使用中缀操作符的表达式转换为一连串使用前缀操作符的数据流,由于数据操作栈的使用方法依赖于数据流失输入的特性,所以表达式处理工作在数据生成过程中进行,为此需要将`DataGenerator`提取出来作为一个单独的类并为其添加内部类`ExpressionProcessor`,在data的generate过程中于`WordCtrler`类`getNextWord`方法与`DataGenerator`类`getNextData`方法中间增加一层`ExpressionProcessor`类的表达式处理机制。 697 | 698 | `ExpressionProcessor`类在字符串层面进行操作,不涉及更高的`Data`抽象层次。由于可以进行表达式的内嵌,所以对于表达式的处理需要进行递归式的处理,具体中缀转前缀的处理方式采用栈进行实现,由于`getNextWord`方法流式读入的特点,`ExpressionProcessor`类需要进行流式的压栈处理,由上,`ExpressionProcessor`类中的属性以及其中所必须的几个方法如下: 699 | 700 | ```java 701 | private static class ExpressionProcessor { // Expression process on string level. 702 | private Vector processResult; // Result with prefix style in string. 703 | // Here word block means a number of words separated by infix separators. 704 | private Stack> wordBlockStack = new Stack>(); 705 | private Stack infixOpStack = new Stack(); 706 | private boolean nextNewWordBlock = true; // Whether the next word word belongs to a new word block. 707 | private ExpressionProcessor insideProcessor; // Use to handle the inside expression recursively. 708 | private int depth; // Begin from 1, which presents the number of brackets. 709 | ExpressionProcessor(int depth); 710 | Vector getProcessResult(); 711 | void push(String word, int wordDepth) throws SyntaxError; 712 | private void generateResult() throws SyntaxError; 713 | // Other class methods... 714 | } 715 | ``` 716 | 717 | `ExpressionProcessor`类中最重要的2个方法为`push`方法以及`generateResult`方法: 718 | 719 | - `push`方法 720 | 721 | 其中,`push`方法需要使用递归的方式进行实现,要做到以下2点: 722 | 723 | - 递归地将内嵌表达式中的word压入`insideProcessor`; 724 | - 当遇到`)`时在合适深度的`ExpressionProcessor`对象调用`generateResult`方法并获取所得数据压入另一个合适深度的对象。 725 | 726 | 对于递归相关的部分使用如下代码进行实现: 727 | 728 | ```java 729 | if (insideProcessor != null) { // Recursion implementation. 730 | insideProcessor.push(word, wordDepth); // Processes and generates word with prefix operations recursively. 731 | if (wordDepth == depth && word.equals(")")) { // End of the current inside expression process. 732 | if (nextNewWordBlock) { 733 | wordBlockStack.push(insideProcessor.getProcessResult()); 734 | } else { 735 | wordBlockStack.peek().addAll(insideProcessor.getProcessResult()); 736 | } // The result of the insideProcessor is a word block. 737 | insideProcessor = null; 738 | } 739 | return; 740 | } 741 | ``` 742 | 743 | 非递归的部分进行简单的入栈操作以及`generateResult`方法的调用即可: 744 | 745 | ```java 746 | switch (word) { 747 | case "(": // "(" create a new inside expression. 748 | insideProcessor = new ExpressionProcessor(depth + 1); 749 | break; 750 | case ")": // ")" end a expression. 751 | generateResult(); // Generate result here and handle result in higher ExpressionProcessor. 752 | break; 753 | default: 754 | if (isInfixOp(word)) { 755 | nextNewWordBlock = true; // Meeting infix operator means next word belongs to a new word block. 756 | infixOpStack.push(word); // Push infix operator into infixOpStack. 757 | } else { 758 | if (nextNewWordBlock) { 759 | wordBlockStack.push(new Vector()); 760 | } 761 | wordBlockStack.peek().add(word); 762 | nextNewWordBlock = false; 763 | } 764 | break; 765 | } 766 | ``` 767 | 768 | - `generateResult`方法 769 | 770 | `generateResult`方法实现了中缀转前缀的方法: 771 | 772 | ```java 773 | Vector> tempResult = new Vector>(); 774 | Stack tempOpStack = new Stack(); 775 | // The following part implements infix to prefix: 776 | // First get reversed prefix order: 777 | tempResult.add(wordBlockStack.pop()); 778 | while (!infixOpStack.isEmpty()) { 779 | while (!tempOpStack.isEmpty() && getInfixOpPriority(tempOpStack.peek()) > getInfixOpPriority(infixOpStack.peek())) { 780 | tempResult.add(new Vector()); 781 | tempResult.lastElement().add(getPrefixOpName(tempOpStack.pop())); 782 | } // Pop from tempOpStack and push into tempResult while operator on the top of tempOpStack has higher priority. 783 | tempOpStack.push(infixOpStack.pop()); 784 | tempResult.add(wordBlockStack.pop()); 785 | } 786 | while (!tempOpStack.isEmpty()) { 787 | tempResult.add(new Vector()); 788 | tempResult.lastElement().add(getPrefixOpName(tempOpStack.pop())); 789 | } // Then push and pop all operator. 790 | Collections.reverse(tempResult); // Then reverse to get prefix order. 791 | processResult = new Vector(); 792 | for (Vector wordBlock : tempResult) { 793 | for (String word : wordBlock) { 794 | processResult.add(word); 795 | } 796 | } // Flatten the tempResult to processResult. 797 | ``` 798 | 799 | 其中要注意的一点是`Stack>`类型与`Stack`类型之间的转化以及对于`tempResult`到`processResult`之间进行类型转换时的flatten操作。 800 | 801 | ### `repeat`操作&`if`操作 802 | 803 | - `repeat`操作 804 | 805 | `repeat`操作定义在`mua.opeartion`包的`RepeatOp.java`文件中,并将`RepeatOp`类实现为`Operation`类的子类。 806 | 807 | `repeat `:运行list中的代码[number]次 808 | 809 | `repeat`操作在具体实现时并不使用一个新的数据操作栈,它直接将list中的代码释放number次到当前数据操作栈中,使用数据操作栈所提供的数据增添功能向其中立即压入数据,因此,当解释器遇到`repeat 3 [print "hello!]`时实际上向当前数据操作栈中压入了以下数据流: 810 | 811 | `(print) "hello (print) "hello (print) "hello` 812 | 813 | 借助这一特性可以实现一些有趣的代码写法: 814 | 815 | ![operation_implement_repeat](./readme_images/operation_implement_repeat.png) 816 | 817 | **注:**但由于MUA解释器基于数据操作栈进行实现的本质,这种写法不被推荐,list中的代码不应该在栈中留下冗余数据,否则可能导致栈溢出的发生。 818 | 819 | - `if`操作 820 | 821 | `if`操作定义在`mua.opeartion`包的`IfOp.java`文件中,并将`IfOp`类实现为`Operation`类的子类。 822 | 823 | `IfOp`类在进行构造时执行如下过程: 824 | 825 | ```java 826 | public IfOp(Data var0, Data var1, Data var2) throws TypeError { 827 | arguments = new Data[] { var0, var1, var2 }; 828 | hasReturnValue = false; 829 | opName = "if"; 830 | hasAppendData = true; 831 | boolean boolValue = arguments[0].getBoolValue(); 832 | Vector trueList = arguments[1].getListValue(); 833 | Vector falseList = arguments[2].getListValue(); 834 | runList = boolValue ? trueList : falseList; 835 | } 836 | ``` 837 | 838 | 即实际上根据所传的第一个参数确定将哪个列表是所需执行的列表。 839 | 840 | 在实际运行时将所选出的需执行列表中的数据压入数据操作栈。 841 | 842 | ## Error处理 843 | 844 | MUA解释器的error处理定义于`mua.error`包中,包含以下5个文件: 845 | 846 | ``` 847 | MuaError.java 848 | NameError.java 849 | SyntaxError.java 850 | TypeError.java 851 | ValueError.java 852 | ``` 853 | 854 | 其中`MuaError.java`定义了`MuaError`类,是另外4个文件中所定义类的父类 855 | 856 | - MuaError.java 857 | 858 | 在`MuaError.java`文件中定义了所有MuaError类,它是所有可预料MUA代码错误的父类,在MUA解释器中以Error形式存在,在JVM层面通过异常进行处理。 859 | 860 | MuaError类内部结构如下: 861 | 862 | ```java 863 | public class MuaError extends Exception { 864 | private Data errorData; 865 | private String errorDataString; 866 | private String errorTypeName; 867 | private StringBuffer detailedMessage; 868 | // 类方法... 869 | } 870 | ``` 871 | 872 | 在`Main.java`文件中,异常处理方法如下: 873 | 874 | ```java 875 | static void handleError(MuaError error) { 876 | System.err.print("[Line "); 877 | System.err.print(wordCtrler.getLineNumber()); 878 | System.err.print("] "); 879 | error.printErrorInfomation(); 880 | // 该句调用MuaError类的方法进行信息输出 881 | wordCtrler.clear(); 882 | dataStack.clear(); 883 | } 884 | ``` 885 | 886 | - 其余4个文件 887 | 888 | 其余4个文件定义了MUA代码中出现的4种error形式:NameError、SyntaxError、TypeError、ValueError,这4种error在解释器源代码中以MuaError子类形式存在,4个子类仅实现构造方法,不重载父类方法。 889 | 890 | - NameError 891 | 892 | - 操作或函数名不存在 893 | 894 | ![error_name1](./readme_images/error_name1.png) 895 | 896 | - 尝试thing、erase、export一个不存在的绑定 897 | 898 | ![error_name2](./readme_images/error_name2.png) 899 | 900 | - 使用保留字作为绑定名 901 | 902 | ![error_name3](./readme_images/error_name3.png) 903 | 904 | - SyntaxError 905 | 906 | - `:`操作符单独出现 907 | 908 | ![error_syntax1](./readme_images/error_syntax1.png) 909 | 910 | - 违法字面量 911 | 912 | ![error_syntax2](./readme_images/error_syntax2.png) 913 | 914 | - 空表达式 915 | 916 | ![error_syntax3](./readme_images/error_syntax3.png) 917 | 918 | - 表达式括号不匹配 919 | 920 | ![error_syntax4](./readme_images/error_syntax4.png) 921 | 922 | - 列表括号不匹配 923 | 924 | ![error_syntax5](./readme_images/error_syntax5.png) 925 | 926 | - 中缀运算符缺少参数 927 | 928 | ![error_syntax6](./readme_images/error_syntax6.png) 929 | 930 | - TypeError 931 | 932 | - 期待类型与实际类型不匹配 933 | 934 | ![error_type1](./readme_images/error_type1.png) 935 | 936 | - 使用操作不支持的类型 937 | 938 | ![error_type2](./readme_images/error_type2.png) 939 | 940 | - ValueError 941 | 942 | - 用0做除数 943 | 944 | ![error_value](./readme_images/error_value.png) 945 | 946 | ## MUA代码样例 947 | 948 | ### 定义内部函数 949 | 950 | ```mua 951 | make "fun [ 952 | [m n] 953 | [ 954 | make "sub2 [[n m][output sub :n :m]] 955 | make "add2 [[a1 a2][output add :a1 :a2]] 956 | make "square [[x][output mul :x :x]] 957 | make "m2 [[][output square :m]] 958 | output add add m2 959 | square :n 960 | mul sub2 :m :n 961 | add2 :m :n 962 | ] 963 | ] 964 | ``` 965 | 966 | 在以上代码中,函数`fun`参数列表为`m n`,它拥有四个内部函数: 967 | 968 | - `sub2`函数重新定义了减操作,其参数列表为`n m`,与外部函数的参数列表形参名称相同但顺序相反,目的在于体现外部函数的参数不会对内部函数的参数造成影响。 969 | - `add2`函数重新定义了加操作,`square`函数定义了平方操作,目的在于表示正常的内部函数使用。 970 | - `m2`函数为无参函数,其内部调用了在外部函数的命名空间中所定义的`square`函数,并直接使用了外部函数的参数,目的在于体现内部函数对外部函数命名空间的正常只读使用。 971 | 972 | 实际上`fun`函数的简化后数学表示为:`fun(m,n)=2m^2` 973 | 974 | 以下使用解释器进行演示: 975 | 976 | 首先进行函数定义: 977 | 978 | ![sample_inside_function_definition](./readme_images/sample_inside_function_definition.png) 979 | 980 | 进行函数定义后我们可以对于相关绑定进行查看: 981 | 982 | ![sample_inside_function_binding](./readme_images/sample_inside_function_binding.png) 983 | 984 | 进行函数调用: 985 | 986 | ![sample_inside_function_call](./readme_images/sample_inside_function_call.png) 987 | 988 | 通过以上结果可以看出,内部函数处理没有问题。 989 | 990 | 同时我们可以使用表达式的语法糖进行函数定义: 991 | 992 | ```mua 993 | make "fun' [ 994 | [m n] 995 | [ 996 | make "sub2 [[n m][output (:n - :m)]] 997 | make "add2 [[a1 a2][output (:a1 + :a2)]] 998 | make "square [[x][output (:x * :x)]] 999 | make "m2 [[][output square :m]] 1000 | output (m2 + square :n + sub2 :m :n * add2 :m :n) 1001 | ] 1002 | ] 1003 | ``` 1004 | 1005 | 较前缀操作符的定义方式更为易懂。 1006 | 1007 | ![sample_inside_function_definition2](./readme_images/sample_inside_function_definition2.png) 1008 | 1009 | 不过由于列表的存储方式和表达式语法糖的本质,我们可以使用等于操作符进行对比: 1010 | 1011 | ![sample_inside_function_equal](./readme_images/sample_inside_function_equal.png) 1012 | 1013 | 由于内部函数的定义顺序以及形参列表等均相同,故两函数所存储的列表相等,自然,新函数也可以正确地进行处理得到结果: 1014 | 1015 | ![sample_inside_function_call2](./readme_images/sample_inside_function_call2.png) 1016 | 1017 | ### `repeat`方式定义阶乘函数 1018 | 1019 | 可以依赖`repeat`操作进行阶乘函数实现,可以对其正确性进行验证: 1020 | 1021 | ```mua 1022 | make "fact [ 1023 | [ n ] 1024 | [ make "i 1 1025 | make "ret 1 1026 | repeat :n [ make "ret mul :ret :i 1027 | make "i add :i 1 ] 1028 | output :ret ] 1029 | ] 1030 | ``` 1031 | 1032 | 运行如下: 1033 | 1034 | ![sample_fact1](./readme_images/sample_fact1.png) 1035 | 1036 | 同样可以使用表达式进行定义: 1037 | 1038 | ```mua 1039 | make "fact' [ 1040 | [n] 1041 | [make "i 1 1042 | make "ret 1 1043 | repeat :n [make "ret (:ret * :i) 1044 | make "i (:i + 1)] 1045 | output :ret] 1046 | ] 1047 | ``` 1048 | 1049 | ![sample_fact2](./readme_images/sample_fact2.png) 1050 | 1051 | 自然,仍然有: 1052 | 1053 | ![sample_fact_equal](./readme_images/sample_fact_equal.png) 1054 | 1055 | ### 递归定义阶乘函数 1056 | 1057 | 递归定义阶乘函数则较为简单: 1058 | 1059 | ```mua 1060 | make "fact [ 1061 | [n] 1062 | [ 1063 | if (:n == 0) [ 1064 | output 1 1065 | ] [ 1066 | output (:n * fact (:n - 1)) 1067 | ] 1068 | ] 1069 | ] 1070 | ``` 1071 | 1072 | 运行的具体过程如下: 1073 | 1074 | ![](./readme_images/fact_recursive.png) 1075 | 1076 | ### **实现快排算法** 1077 | 1078 | 为方便进行分析,以Haskell语言进行以下思考: 1079 | 1080 | 以列表式快排入手: 1081 | 1082 | ```haskell 1083 | qsort :: (Ord a) => [a] -> [a] 1084 | qsort [] = [] 1085 | qsort (x:xs) = qsort [a | a <- xs, a <= x] ++ [x] ++ qsort [a | a <- xs, a > x] 1086 | ``` 1087 | 1088 | 首先进行第一步修改,因为MUA语言无列表推导,我们将列表推导使用函数进行表示,如下: 1089 | 1090 | ```haskell 1091 | qsort' :: (Ord a) => [a] -> [a] 1092 | qsort' [] = [] 1093 | qsort' (x:xs) = qsort' left ++ [x] ++ qsort' right 1094 | where left = get (\ a -> a <= x) xs 1095 | right = get (\ a -> a > x) xs 1096 | get _ [] = [] 1097 | get cond (x:xs) = (if cond x then [x] else []) ++ get cond xs 1098 | ``` 1099 | 1100 | 其次进行第二步修改,因为MUA语言只能支持一定程度上的λ函数,如下: 1101 | 1102 | ```haskell 1103 | qsort'' :: (Ord a) => [a] -> [a] 1104 | qsort'' [] = [] 1105 | qsort'' (x:xs) = qsort'' (getLeft x xs) ++ [x] ++ qsort'' (getRight x xs) 1106 | where getLeft _ [] = [] 1107 | getLeft a (x:xs) = (if x <= a then [x] else []) ++ getLeft a xs 1108 | getRight _ [] = [] 1109 | getRight a (x:xs) = (if x > a then [x] else []) ++ getRight a xs 1110 | ``` 1111 | 1112 | 抵达如上模样,我们便可以直接将其转化为MUA代码,转化形成的MUA代码如下: 1113 | 1114 | ```mua 1115 | make "qsort [ 1116 | [l] 1117 | [ 1118 | if (:l == []) [ 1119 | output [] 1120 | ] [ 1121 | make "x first :l 1122 | make "xs butfirst :l 1123 | make "singleElementList [ 1124 | [x] [output butlast list :x 0] 1125 | ] 1126 | make "getLeft [ 1127 | [a xxs] 1128 | [ 1129 | if (:xxs == []) [ 1130 | output [] 1131 | ] [ 1132 | make "x first :xxs 1133 | make "xs butfirst :xxs 1134 | output (if not (:x > :a) [ 1135 | singleElementList :x 1136 | ] [ [] ] ++ getLeft :a :xs) 1137 | ] 1138 | ] 1139 | ] 1140 | make "getRight [ 1141 | [a xxs] 1142 | [ 1143 | if (:xxs == []) [ 1144 | output [] 1145 | stop 1146 | ] [ 1147 | make "x first :xxs 1148 | make "xs butfirst :xxs 1149 | output (if (:x > :a) [ 1150 | singleElementList :x 1151 | ] [ [] ] ++ getRight :a :xs) 1152 | ] 1153 | ] 1154 | ] 1155 | output (qsort getLeft :x :xs ++ singleElementList :x ++ qsort getRight :x :xs) 1156 | ] 1157 | ] 1158 | ] 1159 | ``` 1160 | 1161 | 可以使用MUA解释器进行验证: 1162 | 1163 | ![](./readme_images/qsort_demo_1.png) 1164 | 1165 | 由于在MUA语言中,对于`word`类型数据同样可以进行大小比较,所以也可以对`word`类型列表进行排序: 1166 | 1167 | ![](./readme_images/qsort_demo_2.png) 1168 | 1169 | **另:** 1170 | 1171 | *`qsort`函数代码以及递归版`fact`函数代码已经使用`save`操作进行导出,导出文件名为`util`,该文件已附([util](util)),可以使用`load`操作导入。* 1172 | 1173 | ![](./readme_images/util_instruction.png) 1174 | 1175 | ## 源代码结构 1176 | 1177 | 源代码由4个包和其中的59个文件构成,其组织结构如下: 1178 | 1179 | ``` 1180 | ─mua 1181 | ├─Data.java 1182 | ├─WordCtrler.java 1183 | ├─DataGenerator.java 1184 | ├─NameSpace.java 1185 | ├─DataOperationStack.java 1186 | ├─FunctionHandler.java 1187 | ├─Main.java 1188 | ├─error 1189 | │ ├─MuaError.java 1190 | │ ├─NameError.java 1191 | │ ├─SyntaxError.java 1192 | │ ├─TypeError.java 1193 | │ └─ValueError.java 1194 | └─operation 1195 | ├─OperationHandler.java 1196 | ├─IOperation.java 1197 | ├─Operation.java 1198 | ├─MakeOp.java 1199 | ├─IsnameOp.java 1200 | ├─ThingOp.java 1201 | ├─EraseOp.java 1202 | ├─PrintOp.java 1203 | ├─ReadOp.java 1204 | ├─ReadlistOp.java 1205 | ├─OutputOp.java 1206 | ├─ExportOp.java 1207 | ├─IfOp.java 1208 | ├─RepeatOp.java 1209 | ├─FirstOp.java 1210 | ├─LastOp.java 1211 | ├─ButfirstOp.java 1212 | ├─ButlastOp.java 1213 | ├─IsemptyOp.java 1214 | ├─JoinOp.java 1215 | ├─WordOp.java 1216 | ├─SentenceOp.java 1217 | ├─ListOp.java 1218 | ├─LoadOp.java 1219 | ├─SaveOp.java 1220 | ├─PoallOp.java 1221 | ├─ErallOp.java 1222 | ├─IntOp.java 1223 | ├─IsnumberOp.java 1224 | ├─IswordOp.java 1225 | ├─IsboolOp.java 1226 | ├─IslistOp.java 1227 | ├─SqrtOp.java 1228 | ├─RandomOp.java 1229 | ├─WaitOp.java 1230 | └─operator 1231 | ├─AddOp.java 1232 | ├─AndOp.java 1233 | ├─DivOp.java 1234 | ├─EqOp.java 1235 | ├─GtOp.java 1236 | ├─LtOp.java 1237 | ├─ModOp.java 1238 | ├─MulOp.java 1239 | ├─NotOp.java 1240 | ├─Operator.java 1241 | ├─OrOp.java 1242 | └─SubOp.java 1243 | ``` 1244 | -------------------------------------------------------------------------------- /README.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/README.pdf -------------------------------------------------------------------------------- /mua.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/mua.jar -------------------------------------------------------------------------------- /readme_images/add_sub_mul_div_mod_demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/add_sub_mul_div_mod_demo.png -------------------------------------------------------------------------------- /readme_images/and_or_demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/and_or_demo.png -------------------------------------------------------------------------------- /readme_images/bool_demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/bool_demo.png -------------------------------------------------------------------------------- /readme_images/butfirst_butlast_demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/butfirst_butlast_demo.png -------------------------------------------------------------------------------- /readme_images/colon_demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/colon_demo.png -------------------------------------------------------------------------------- /readme_images/demo_exp_bool.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/demo_exp_bool.png -------------------------------------------------------------------------------- /readme_images/demo_exp_number1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/demo_exp_number1.png -------------------------------------------------------------------------------- /readme_images/demo_exp_number2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/demo_exp_number2.png -------------------------------------------------------------------------------- /readme_images/demo_export.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/demo_export.png -------------------------------------------------------------------------------- /readme_images/demo_function_call.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/demo_function_call.png -------------------------------------------------------------------------------- /readme_images/demo_function_definition.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/demo_function_definition.png -------------------------------------------------------------------------------- /readme_images/demo_output.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/demo_output.png -------------------------------------------------------------------------------- /readme_images/demo_repeat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/demo_repeat.png -------------------------------------------------------------------------------- /readme_images/demo_stop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/demo_stop.png -------------------------------------------------------------------------------- /readme_images/eq_demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/eq_demo.png -------------------------------------------------------------------------------- /readme_images/erase_demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/erase_demo.png -------------------------------------------------------------------------------- /readme_images/error_name1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/error_name1.png -------------------------------------------------------------------------------- /readme_images/error_name2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/error_name2.png -------------------------------------------------------------------------------- /readme_images/error_name3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/error_name3.png -------------------------------------------------------------------------------- /readme_images/error_syntax1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/error_syntax1.png -------------------------------------------------------------------------------- /readme_images/error_syntax2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/error_syntax2.png -------------------------------------------------------------------------------- /readme_images/error_syntax3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/error_syntax3.png -------------------------------------------------------------------------------- /readme_images/error_syntax4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/error_syntax4.png -------------------------------------------------------------------------------- /readme_images/error_syntax5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/error_syntax5.png -------------------------------------------------------------------------------- /readme_images/error_syntax6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/error_syntax6.png -------------------------------------------------------------------------------- /readme_images/error_type1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/error_type1.png -------------------------------------------------------------------------------- /readme_images/error_type2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/error_type2.png -------------------------------------------------------------------------------- /readme_images/error_value.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/error_value.png -------------------------------------------------------------------------------- /readme_images/fact_recursive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/fact_recursive.png -------------------------------------------------------------------------------- /readme_images/first_last_demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/first_last_demo.png -------------------------------------------------------------------------------- /readme_images/gt_lt_demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/gt_lt_demo.png -------------------------------------------------------------------------------- /readme_images/if_demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/if_demo.png -------------------------------------------------------------------------------- /readme_images/infix_sentence_demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/infix_sentence_demo.png -------------------------------------------------------------------------------- /readme_images/int_demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/int_demo.png -------------------------------------------------------------------------------- /readme_images/is_type_demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/is_type_demo.png -------------------------------------------------------------------------------- /readme_images/isempty_demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/isempty_demo.png -------------------------------------------------------------------------------- /readme_images/isname_demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/isname_demo.png -------------------------------------------------------------------------------- /readme_images/join_demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/join_demo.png -------------------------------------------------------------------------------- /readme_images/list_demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/list_demo.png -------------------------------------------------------------------------------- /readme_images/list_op_demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/list_op_demo.png -------------------------------------------------------------------------------- /readme_images/load_not_exist_demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/load_not_exist_demo.png -------------------------------------------------------------------------------- /readme_images/make_demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/make_demo.png -------------------------------------------------------------------------------- /readme_images/modification_colon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/modification_colon.png -------------------------------------------------------------------------------- /readme_images/namespace_op_demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/namespace_op_demo.png -------------------------------------------------------------------------------- /readme_images/namespace_op_demo2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/namespace_op_demo2.png -------------------------------------------------------------------------------- /readme_images/not_demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/not_demo.png -------------------------------------------------------------------------------- /readme_images/number_demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/number_demo.png -------------------------------------------------------------------------------- /readme_images/operation_implement_empty_stack_print.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/operation_implement_empty_stack_print.png -------------------------------------------------------------------------------- /readme_images/operation_implement_exp_haskell_infix.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/operation_implement_exp_haskell_infix.png -------------------------------------------------------------------------------- /readme_images/operation_implement_exp_mua_infix.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/operation_implement_exp_mua_infix.png -------------------------------------------------------------------------------- /readme_images/operation_implement_exp_sugar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/operation_implement_exp_sugar.png -------------------------------------------------------------------------------- /readme_images/operation_implement_exp_sugar_complex.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/operation_implement_exp_sugar_complex.png -------------------------------------------------------------------------------- /readme_images/operation_implement_function1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/operation_implement_function1.png -------------------------------------------------------------------------------- /readme_images/operation_implement_function2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/operation_implement_function2.png -------------------------------------------------------------------------------- /readme_images/operation_implement_repeat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/operation_implement_repeat.png -------------------------------------------------------------------------------- /readme_images/ori_names_demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/ori_names_demo.png -------------------------------------------------------------------------------- /readme_images/print_demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/print_demo.png -------------------------------------------------------------------------------- /readme_images/qsort_demo_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/qsort_demo_1.png -------------------------------------------------------------------------------- /readme_images/qsort_demo_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/qsort_demo_2.png -------------------------------------------------------------------------------- /readme_images/random_demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/random_demo.png -------------------------------------------------------------------------------- /readme_images/read_demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/read_demo.png -------------------------------------------------------------------------------- /readme_images/readlist_demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/readlist_demo.png -------------------------------------------------------------------------------- /readme_images/sample_fact1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/sample_fact1.png -------------------------------------------------------------------------------- /readme_images/sample_fact2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/sample_fact2.png -------------------------------------------------------------------------------- /readme_images/sample_fact_equal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/sample_fact_equal.png -------------------------------------------------------------------------------- /readme_images/sample_inside_function_binding.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/sample_inside_function_binding.png -------------------------------------------------------------------------------- /readme_images/sample_inside_function_call.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/sample_inside_function_call.png -------------------------------------------------------------------------------- /readme_images/sample_inside_function_call2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/sample_inside_function_call2.png -------------------------------------------------------------------------------- /readme_images/sample_inside_function_definition.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/sample_inside_function_definition.png -------------------------------------------------------------------------------- /readme_images/sample_inside_function_definition2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/sample_inside_function_definition2.png -------------------------------------------------------------------------------- /readme_images/sample_inside_function_equal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/sample_inside_function_equal.png -------------------------------------------------------------------------------- /readme_images/sentence_demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/sentence_demo.png -------------------------------------------------------------------------------- /readme_images/sqrt_demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/sqrt_demo.png -------------------------------------------------------------------------------- /readme_images/thing_demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/thing_demo.png -------------------------------------------------------------------------------- /readme_images/util_content.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/util_content.png -------------------------------------------------------------------------------- /readme_images/util_instruction.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/util_instruction.png -------------------------------------------------------------------------------- /readme_images/wait_demo_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/wait_demo_1.png -------------------------------------------------------------------------------- /readme_images/wait_demo_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/wait_demo_2.png -------------------------------------------------------------------------------- /readme_images/word_demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/word_demo.png -------------------------------------------------------------------------------- /readme_images/word_op_demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EveryTian/MUA-Interpreter/73eea02c3c3f6b51eba4a242753275992228b9a9/readme_images/word_op_demo.png -------------------------------------------------------------------------------- /util: -------------------------------------------------------------------------------- 1 | qsort 2 | [ [ l ] [ if eq thing "l [ ] [ output [ ] ] [ make "x first thing "l make "xs butfirst thing "l make "singleElementList [ [ x ] [ output butlast list thing "x 0.0 ] ] make "getLeft [ [ a xxs ] [ if eq thing "xxs [ ] [ output [ ] ] [ make "x first thing "xxs make "xs butfirst thing "xxs output sentence if not gt thing "x thing "a [ singleElementList thing "x ] [ [ ] ] getLeft thing "a thing "xs ] ] ] make "getRight [ [ a xxs ] [ if eq thing "xxs [ ] [ output [ ] stop ] [ make "x first thing "xxs make "xs butfirst thing "xxs output sentence if gt thing "x thing "a [ singleElementList thing "x ] [ [ ] ] getRight thing "a thing "xs ] ] ] output sentence sentence qsort getLeft thing "x thing "xs singleElementList thing "x qsort getRight thing "x thing "xs ] ] ] 3 | fact 4 | [ [ n ] [ if eq thing "n 0.0 [ output 1.0 ] [ output mul thing "n fact sub thing "n 1.0 ] ] ] 5 | pi 6 | [ [ ] [ output 3.14159 ] ] 7 | run 8 | [ [ l ] [ repeat 1.0 thing "l ] ] 9 | --------------------------------------------------------------------------------