@@ -8,17 +8,62 @@ using namespace libscratchcpp;
88CustomBlocks::CustomBlocks ()
99{
1010 // Blocks
11- addHatBlock (" procedures_definition" );
11+ addCompileFunction (" procedures_definition" , &compileDefinition );
1212 addCompileFunction (" procedures_call" , &compileCall);
13+ addCompileFunction (" argument_reporter_boolean" , &compileArgument);
14+ addCompileFunction (" argument_reporter_string_number" , &compileArgument);
15+
16+ // Inputs
17+ addInput (" custom_block" , CUSTOM_BLOCK);
18+
19+ // Fields
20+ addField (" VALUE" , VALUE);
1321}
1422
1523std::string CustomBlocks::name () const
1624{
1725 return " Custom blocks" ;
1826}
1927
28+ void CustomBlocks::compileDefinition (Compiler *compiler)
29+ {
30+ auto prototype = compiler->input (CUSTOM_BLOCK)->valueBlock ()->mutationPrototype ();
31+ compiler->setProcedurePrototype (prototype);
32+ const std::vector<std::string> &args = prototype->argumentNames ();
33+ const std::string &code = prototype->procCode ();
34+ for (const std::string &arg : args)
35+ compiler->addProcedureArg (code, arg);
36+ }
37+
2038void CustomBlocks::compileCall (Compiler *compiler)
2139{
22- const std::string &code = compiler->block ()->mutationPrototype ()->procCode ();
40+ compiler->addInstruction (vm::OP_INIT_PROCEDURE);
41+ auto block = compiler->block ();
42+ auto prototype = block->mutationPrototype ();
43+ const std::vector<std::string> &args = prototype->argumentIds ();
44+ size_t i = 0 ;
45+ for (const std::string &id : args) {
46+ auto index = block->findInput (id);
47+ if (index == -1 )
48+ compiler->addInstruction (vm::OP_NULL);
49+ else
50+ compiler->addInput (block->inputAt (index).get ());
51+ compiler->addInstruction (vm::OP_ADD_ARG);
52+ i++;
53+ }
54+ const std::string &code = prototype->procCode ();
2355 compiler->addInstruction (vm::OP_CALL_PROCEDURE, { compiler->procedureIndex (code) });
2456}
57+
58+ void CustomBlocks::compileArgument (Compiler *compiler)
59+ {
60+ if (compiler->procedurePrototype ()) {
61+ const std::string &argName = compiler->field (VALUE)->value ().toString ();
62+ auto index = compiler->procedureArgIndex (compiler->procedurePrototype ()->procCode (), argName);
63+ if (index == -1 )
64+ compiler->addInstruction (vm::OP_NULL);
65+ else
66+ compiler->addInstruction (vm::OP_READ_ARG, { static_cast <unsigned int >(index) });
67+ } else
68+ compiler->addInstruction (vm::OP_NULL);
69+ }
0 commit comments