@@ -19,6 +19,8 @@ Compiler::Compiler(Engine *engine) :
1919void Compiler::compile (std::shared_ptr<Block> topLevelBlock)
2020{
2121 m_bytecode.clear ();
22+ m_procedurePrototype = nullptr ;
23+
2224 // Add start instruction
2325 addInstruction (OP_START);
2426
@@ -95,22 +97,21 @@ void Compiler::addInstruction(Opcode opcode, std::initializer_list<unsigned int>
9597 m_bytecode.push_back (arg);
9698}
9799
98- /* ! Compiles the given input (resolved by ID) and adds it to the bytecode. */
99- void Compiler::addInput (int id )
100+ /* ! Compiles the given input and adds it to the bytecode. */
101+ void Compiler::addInput (Input *input )
100102{
101- auto in = input (id);
102- if (!in) {
103+ if (!input) {
103104 addInstruction (OP_NULL);
104105 return ;
105106 }
106- switch (in ->type ()) {
107+ switch (input ->type ()) {
107108 case Input::Type::Shadow:
108- addInstruction (OP_CONST, { constIndex (in ->primaryValue ()) });
109+ addInstruction (OP_CONST, { constIndex (input ->primaryValue ()) });
109110 break ;
110111
111112 case Input::Type::NoShadow: {
112113 auto previousBlock = m_block;
113- m_block = in ->valueBlock ();
114+ m_block = input ->valueBlock ();
114115 assert (m_block);
115116 if (m_block->compileFunction ())
116117 m_block->compile (this );
@@ -124,7 +125,7 @@ void Compiler::addInput(int id)
124125
125126 case Input::Type::ObscuredShadow: {
126127 auto previousBlock = m_block;
127- m_block = in ->valueBlock ();
128+ m_block = input ->valueBlock ();
128129 if (m_block) {
129130 if (m_block->compileFunction ())
130131 m_block->compile (this );
@@ -133,19 +134,31 @@ void Compiler::addInput(int id)
133134 addInstruction (OP_NULL);
134135 }
135136 } else
136- in ->primaryValue ()->compile (this );
137+ input ->primaryValue ()->compile (this );
137138 m_block = previousBlock;
138139 break ;
139140 }
140141 }
141142}
142143
144+ /* ! Compiles the given input (resolved by ID) and adds it to the bytecode. */
145+ void Compiler::addInput (int id)
146+ {
147+ addInput (input (id));
148+ }
149+
143150/* ! Adds a function call to the bytecode (the OP_EXEC instruction). */
144151void Compiler::addFunctionCall (BlockFunc f)
145152{
146153 addInstruction (OP_EXEC, { m_engine->functionIndex (f) });
147154}
148155
156+ /* ! Adds an argument to a procedure (custom block). */
157+ void Compiler::addProcedureArg (std::string procCode, std::string argName)
158+ {
159+ m_procedureArgs[procCode].push_back (argName);
160+ }
161+
149162/* ! Jumps to the given substack. The second substack is used for example for the if/else block. */
150163void Compiler::moveToSubstack (std::shared_ptr<Block> substack1, std::shared_ptr<Block> substack2, SubstackType type)
151164{
@@ -221,6 +234,21 @@ unsigned int Compiler::procedureIndex(std::string proc)
221234 return m_procedures.size () - 1 ;
222235}
223236
237+ /* ! Returns the index of the argument of the given procedure (custom block). */
238+ long Compiler::procedureArgIndex (std::string procCode, std::string argName)
239+ {
240+ if (m_procedureArgs.count (procCode) == 0 ) {
241+ std::cout << " warning: could not find custom block '" << procCode << " '" << std::endl;
242+ return -1 ;
243+ }
244+ const std::vector<std::string> args = m_procedureArgs[procCode];
245+ auto it = std::find (args.begin (), args.end (), argName);
246+ if (it != args.end ())
247+ return it - args.begin ();
248+ std::cout << " warning: could not find argument '" << argName << " ' in custom block '" << procCode << " '" << std::endl;
249+ return -1 ;
250+ }
251+
224252void Compiler::substackEnd ()
225253{
226254 auto parent = m_substackTree.back ();
@@ -244,6 +272,18 @@ void Compiler::substackEnd()
244272 substackEnd ();
245273}
246274
275+ /* ! Returns the prototype of the current custom block. */
276+ BlockPrototype *Compiler::procedurePrototype () const
277+ {
278+ return m_procedurePrototype;
279+ }
280+
281+ /* ! Sets the prototype of the current custom block. */
282+ void Compiler::setProcedurePrototype (BlockPrototype *prototype)
283+ {
284+ m_procedurePrototype = prototype;
285+ }
286+
247287/* ! Returns the list of custom block prototypes. */
248288const std::vector<std::string> &Compiler::procedures () const
249289{
0 commit comments