• R/O
  • SSH
  • HTTPS

eircompile: Commit


Commit MetaInfo

Revision73 (tree)
Time2022-01-07 03:30:50
Authorquiret

Log Message

- fixed refPtr logic of lexing structures (lexing env and std-compiler)
- added commonlangs project which is used to store common language definitions such as COS (Lua will be added at a later date)

Change Summary

Incremental Difference

--- commonlangs/include/commonlangs/cos.h (nonexistent)
+++ commonlangs/include/commonlangs/cos.h (revision 73)
@@ -0,0 +1,893 @@
1+#pragma once
2+
3+// Compiler-Objects-Syntax definition.
4+
5+#include <sdk/Vector.h>
6+#include <sdk/String.h>
7+#include <sdk/MultiString.h>
8+
9+namespace COS
10+{
11+
12+template <typename structType>
13+using cosCommonVector = eir::Vector <structType, CRTHeapAllocator>;
14+
15+template <eir::CharacterType charType>
16+using cosCommonString = eir::String <charType, CRTHeapAllocator>;
17+
18+typedef eir::MultiString <CRTHeapAllocator> cosCommonMultiString;
19+
20+struct COSNode
21+{
22+ virtual ~COSNode( void )
23+ {}
24+
25+ inline void Delete( void ) noexcept
26+ {
27+ delete this;
28+ }
29+
30+ // Thanks to selector-based nodes we can detach the actual node building from the node logic itself.
31+ // This were a burden because it would require character-based methods that we would not want to lock to character encodings.
32+};
33+
34+struct Program final : public COSNode
35+{
36+ inline Program( cosCommonVector <COSNode*> statements = {} ) noexcept : statements( std::move( statements ) )
37+ {
38+ return;
39+ }
40+ inline Program( const Program& ) = default;
41+ inline Program( Program&& ) = default;
42+
43+ cosCommonVector <COSNode*> statements;
44+};
45+
46+struct Operation : public COSNode
47+{
48+};
49+
50+struct UnaryOperation : public COSNode
51+{
52+ inline UnaryOperation( COSNode *op = nullptr ) noexcept : op( op )
53+ {
54+ return;
55+ }
56+ inline UnaryOperation( const UnaryOperation& ) = default;
57+ inline UnaryOperation( UnaryOperation&& ) = default;
58+
59+ COSNode *op;
60+};
61+
62+struct LogicalNegationOperation final : public UnaryOperation
63+{
64+ using UnaryOperation::UnaryOperation;
65+};
66+struct BitwiseNegationOperation final : public UnaryOperation
67+{
68+ using UnaryOperation::UnaryOperation;
69+};
70+struct NumericNegationOperation final : public UnaryOperation
71+{
72+ using UnaryOperation::UnaryOperation;
73+};
74+struct PreIncrementOperation final : public UnaryOperation
75+{
76+ using UnaryOperation::UnaryOperation;
77+};
78+struct PreDecrementOperation final : public UnaryOperation
79+{
80+ using UnaryOperation::UnaryOperation;
81+};
82+struct PostIncrementOperation final : public UnaryOperation
83+{
84+ using UnaryOperation::UnaryOperation;
85+};
86+struct PostDecrementOperation final : public UnaryOperation
87+{
88+ using UnaryOperation::UnaryOperation;
89+};
90+struct ResolveSpecifierOperation final : public UnaryOperation
91+{
92+ using UnaryOperation::UnaryOperation;
93+};
94+struct PointerResolveOperation final : public UnaryOperation
95+{
96+ using UnaryOperation::UnaryOperation;
97+};
98+struct AddressOfOperation final : public UnaryOperation
99+{
100+ using UnaryOperation::UnaryOperation;
101+};
102+
103+struct BinaryOperation : public Operation
104+{
105+ inline BinaryOperation( COSNode *left = nullptr, COSNode *right = nullptr ) noexcept : left( left ), right( right )
106+ {
107+ return;
108+ }
109+ inline BinaryOperation( const BinaryOperation& ) = default;
110+ inline BinaryOperation( BinaryOperation&& ) = default;
111+
112+ COSNode *left;
113+ COSNode *right;
114+};
115+
116+struct AddOperation final : public BinaryOperation
117+{
118+ using BinaryOperation::BinaryOperation;
119+};
120+struct SubOperation final : public BinaryOperation
121+{
122+ using BinaryOperation::BinaryOperation;
123+};
124+struct MulOperation final : public BinaryOperation
125+{
126+ using BinaryOperation::BinaryOperation;
127+};
128+struct DivOperation final : public BinaryOperation
129+{
130+ using BinaryOperation::BinaryOperation;
131+};
132+struct ModulusOperation final : public BinaryOperation
133+{
134+ using BinaryOperation::BinaryOperation;
135+};
136+struct BitwiseAndOperation final : public BinaryOperation
137+{
138+ using BinaryOperation::BinaryOperation;
139+};
140+struct BitwiseOrOperation final : public BinaryOperation
141+{
142+ using BinaryOperation::BinaryOperation;
143+};
144+struct BitwiseXorOperation final : public BinaryOperation
145+{
146+ using BinaryOperation::BinaryOperation;
147+};
148+struct BitshiftLeftOperation final : public BinaryOperation
149+{
150+ using BinaryOperation::BinaryOperation;
151+};
152+struct BitshiftRightOperation final : public BinaryOperation
153+{
154+ using BinaryOperation::BinaryOperation;
155+};
156+struct CompareEqualityOperation final : public BinaryOperation
157+{
158+ using BinaryOperation::BinaryOperation;
159+};
160+struct CompareInequalityOperation final : public BinaryOperation
161+{
162+ using BinaryOperation::BinaryOperation;
163+};
164+struct CompareLessThanOperation final : public BinaryOperation
165+{
166+ using BinaryOperation::BinaryOperation;
167+};
168+struct CompareGreaterThanOperation final : public BinaryOperation
169+{
170+ using BinaryOperation::BinaryOperation;
171+};
172+struct CompareLessThanEqualOperation final : public BinaryOperation
173+{
174+ using BinaryOperation::BinaryOperation;
175+};
176+struct CompareGreaterThanEqualOperation final : public BinaryOperation
177+{
178+ using BinaryOperation::BinaryOperation;
179+};
180+struct LogicalAndOperation final : public BinaryOperation
181+{
182+ using BinaryOperation::BinaryOperation;
183+};
184+struct LogicalOrOperation final : public BinaryOperation
185+{
186+ using BinaryOperation::BinaryOperation;
187+};
188+struct AssignmentOperation final : public BinaryOperation
189+{
190+ using BinaryOperation::BinaryOperation;
191+};
192+struct EdgeBracketsOperation final : public BinaryOperation
193+{
194+ // a[b]
195+ using BinaryOperation::BinaryOperation;
196+};
197+struct DotOperation final : public BinaryOperation
198+{
199+ // a.b
200+ using BinaryOperation::BinaryOperation;
201+};
202+struct ArrowOperation final : public BinaryOperation
203+{
204+ using BinaryOperation::BinaryOperation;
205+};
206+
207+struct AssignAddOperation final : public BinaryOperation
208+{
209+ using BinaryOperation::BinaryOperation;
210+};
211+struct AssignSubOperation final : public BinaryOperation
212+{
213+ using BinaryOperation::BinaryOperation;
214+};
215+struct AssignMulOperation final : public BinaryOperation
216+{
217+ using BinaryOperation::BinaryOperation;
218+};
219+struct AssignDivOperation final : public BinaryOperation
220+{
221+ using BinaryOperation::BinaryOperation;
222+};
223+struct AssignModulusOperation final : public BinaryOperation
224+{
225+ using BinaryOperation::BinaryOperation;
226+};
227+struct AssignBitwiseXorOperation final : public BinaryOperation
228+{
229+ using BinaryOperation::BinaryOperation;
230+};
231+struct AssignBitwiseAndOperation final : public BinaryOperation
232+{
233+ using BinaryOperation::BinaryOperation;
234+};
235+struct AssignBitwiseOrOperation final : public BinaryOperation
236+{
237+ using BinaryOperation::BinaryOperation;
238+};
239+struct AssignDotOperation final : public BinaryOperation
240+{
241+ using BinaryOperation::BinaryOperation;
242+};
243+struct AssignArrowOperation final : public BinaryOperation
244+{
245+ using BinaryOperation::BinaryOperation;
246+};
247+struct AssignBitshiftLeftOperation final : public BinaryOperation
248+{
249+ using BinaryOperation::BinaryOperation;
250+};
251+struct AssignBitshiftRightOperation final : public BinaryOperation
252+{
253+ using BinaryOperation::BinaryOperation;
254+};
255+
256+struct FunctionCallOperation final : public Operation
257+{
258+ inline FunctionCallOperation( COSNode *what = nullptr, cosCommonVector <COSNode*> params = {} ) noexcept : what( what ), params( std::move( params ) )
259+ {
260+ return;
261+ }
262+ inline FunctionCallOperation( const FunctionCallOperation& ) = default;
263+ inline FunctionCallOperation( FunctionCallOperation&& right ) noexcept : params( std::move( right.params ) )
264+ {
265+ this->what = right.what;
266+
267+ right.what = nullptr;
268+ }
269+
270+ COSNode *what;
271+ cosCommonVector <COSNode*> params;
272+};
273+struct ArrayInitOperation final : public Operation
274+{
275+ inline ArrayInitOperation( COSNode *what = nullptr, cosCommonVector <COSNode*> items = {} ) noexcept : what( what ), items( std::move( items ) )
276+ {
277+ return;
278+ }
279+ inline ArrayInitOperation( const ArrayInitOperation& ) = default;
280+ inline ArrayInitOperation( ArrayInitOperation&& right ) noexcept : items( std::move( right.items ) )
281+ {
282+ this->what = right.what;
283+
284+ right.what = nullptr;
285+ }
286+
287+ COSNode *what;
288+ cosCommonVector <COSNode*> items;
289+};
290+
291+struct NewOperation final : public Operation
292+{
293+ inline NewOperation( COSNode *type = nullptr, cosCommonVector <COSNode*> params = {} ) noexcept : type( type ), params( std::move( params ) )
294+ {
295+ return;
296+ }
297+ inline NewOperation( const NewOperation& ) = default;
298+ inline NewOperation( NewOperation&& right ) noexcept : params( std::move( right.params ) )
299+ {
300+ this->type = right.type;
301+
302+ right.type = nullptr;
303+ }
304+
305+ COSNode *type;
306+ cosCommonVector <COSNode*> params;
307+};
308+struct ReplaceOperation final : public Operation
309+{
310+ inline ReplaceOperation( COSNode *what = nullptr, COSNode *with = nullptr ) noexcept : what( what ), with( with )
311+ {
312+ return;
313+ }
314+ inline ReplaceOperation( const ReplaceOperation& ) = default;
315+ inline ReplaceOperation( ReplaceOperation&& ) = default;
316+
317+ COSNode *what;
318+ COSNode *with;
319+};
320+struct DeleteOperation final : public UnaryOperation
321+{
322+ using UnaryOperation::UnaryOperation;
323+};
324+
325+struct CastOperation final : public Operation
326+{
327+ inline CastOperation( COSNode *totype = nullptr, COSNode *castobj = nullptr ) noexcept : totype( totype ), castobj( castobj )
328+ {
329+ return;
330+ }
331+ inline CastOperation( const CastOperation& ) = default;
332+ inline CastOperation( CastOperation&& right ) noexcept
333+ {
334+ this->totype = right.totype;
335+ this->castobj = right.castobj;
336+
337+ right.totype = nullptr;
338+ right.castobj = nullptr;
339+ }
340+
341+ COSNode *totype;
342+ COSNode *castobj;
343+};
344+
345+struct TemplateInstantiationOperation final : public Operation
346+{
347+ inline TemplateInstantiationOperation( COSNode *templ = nullptr, cosCommonVector <COSNode*> tparams = {} ) noexcept : templ( templ ), tparams( std::move( tparams ) )
348+ {
349+ return;
350+ }
351+ inline TemplateInstantiationOperation( const TemplateInstantiationOperation& ) = default;
352+ inline TemplateInstantiationOperation( TemplateInstantiationOperation&& right ) noexcept : tparams( std::move( right.tparams ) )
353+ {
354+ this->templ = right.templ;
355+
356+ right.templ = nullptr;
357+ }
358+
359+ COSNode *templ;
360+ cosCommonVector <COSNode*> tparams;
361+};
362+
363+struct IfStatement final : public COSNode
364+{
365+ inline IfStatement( COSNode *condition = nullptr, COSNode *true_branch = nullptr, COSNode *false_branch = nullptr ) noexcept : condition( condition ), true_branch( true_branch ), false_branch( false_branch )
366+ {
367+ return;
368+ }
369+ inline IfStatement( const IfStatement& ) = default;
370+ inline IfStatement( IfStatement&& right ) noexcept
371+ {
372+ this->condition = right.condition;
373+ this->true_branch = right.true_branch;
374+ this->false_branch = right.false_branch;
375+
376+ right.condition = nullptr;
377+ right.true_branch = nullptr;
378+ right.false_branch = nullptr;
379+ }
380+
381+ COSNode *condition;
382+ COSNode *true_branch;
383+ COSNode *false_branch;
384+};
385+struct WhileLoopStatement final : public COSNode
386+{
387+ inline WhileLoopStatement( COSNode *condition = nullptr, COSNode *exec = nullptr ) noexcept : condition( condition ), exec( exec )
388+ {
389+ return;
390+ }
391+ inline WhileLoopStatement( const WhileLoopStatement& ) = default;
392+ inline WhileLoopStatement( WhileLoopStatement&& right ) noexcept
393+ {
394+ this->condition = right.condition;
395+ this->exec = right.exec;
396+
397+ right.condition = nullptr;
398+ right.exec = nullptr;
399+ }
400+
401+ COSNode *condition;
402+ COSNode *exec;
403+};
404+struct ForLoopStatement final : public COSNode
405+{
406+ inline ForLoopStatement( COSNode *init = nullptr, COSNode *condition = nullptr, COSNode *iteration = nullptr, COSNode *exec = nullptr ) noexcept : init( init ), condition( condition ), iteration( iteration ), exec( exec )
407+ {
408+ return;
409+ }
410+ inline ForLoopStatement( const ForLoopStatement& ) = default;
411+ inline ForLoopStatement( ForLoopStatement&& right ) noexcept
412+ {
413+ this->init = right.init;
414+ this->condition = right.condition;
415+ this->iteration = right.iteration;
416+ this->exec = right.exec;
417+
418+ right.init = nullptr;
419+ right.condition = nullptr;
420+ right.iteration = nullptr;
421+ right.exec = nullptr;
422+ }
423+
424+ COSNode *init;
425+ COSNode *condition;
426+ COSNode *iteration;
427+ COSNode *exec;
428+};
429+struct ContinueStatement final : public COSNode
430+{
431+};
432+struct BreakStatement final : public COSNode
433+{
434+};
435+
436+struct ReturnStatement final : public COSNode
437+{
438+ inline ReturnStatement( COSNode *op = nullptr ) noexcept : op( op )
439+ {
440+ return;
441+ }
442+ inline ReturnStatement( const ReturnStatement& ) = default;
443+ inline ReturnStatement( ReturnStatement&& right ) noexcept
444+ {
445+ this->op = right.op;
446+
447+ right.op = nullptr;
448+ }
449+
450+ COSNode *op;
451+};
452+
453+struct DeclarationStatement final : public COSNode
454+{
455+ inline DeclarationStatement( COSNode *name = nullptr, COSNode *type = nullptr, COSNode *initializer = nullptr ) noexcept : name( name ), type( type ), initializer( initializer )
456+ {
457+ return;
458+ }
459+ inline DeclarationStatement( const DeclarationStatement& ) = default;
460+ inline DeclarationStatement( DeclarationStatement&& right ) noexcept
461+ {
462+ this->name = right.name;
463+ this->type = right.type;
464+ this->initializer = right.initializer;
465+
466+ right.name = nullptr;
467+ right.type = nullptr;
468+ right.initializer = nullptr;
469+ }
470+
471+ COSNode *name;
472+ COSNode *type;
473+ COSNode *initializer;
474+};
475+struct MultiDeclarationStatement final : public COSNode
476+{
477+ // Just a pack of declarations because we cannot keep them outside.
478+
479+ inline MultiDeclarationStatement( cosCommonVector <DeclarationStatement*> decls = {} ) noexcept : decls( std::move( decls ) )
480+ {}
481+ inline MultiDeclarationStatement( const MultiDeclarationStatement& ) = default;
482+ inline MultiDeclarationStatement( MultiDeclarationStatement&& ) = default;
483+
484+ cosCommonVector <DeclarationStatement*> decls;
485+};
486+
487+struct TypedefStatement final : public COSNode
488+{
489+ inline TypedefStatement( COSNode *srctype = nullptr, COSNode *dsttype = nullptr ) noexcept : srctype( srctype ), dsttype( dsttype )
490+ {
491+ return;
492+ }
493+ inline TypedefStatement( const TypedefStatement& ) = default;
494+ inline TypedefStatement( TypedefStatement&& right ) noexcept
495+ {
496+ this->srctype = right.srctype;
497+ this->dsttype = right.dsttype;
498+
499+ right.srctype = nullptr;
500+ right.dsttype = nullptr;
501+ }
502+
503+ COSNode *srctype;
504+ COSNode *dsttype;
505+};
506+struct MultiTypedefStatement final : public COSNode
507+{
508+ inline MultiTypedefStatement( cosCommonVector <TypedefStatement*> defs = {} ) noexcept : defs( std::move( defs ) )
509+ {
510+ return;
511+ }
512+ inline MultiTypedefStatement( const MultiTypedefStatement& ) = default;
513+ inline MultiTypedefStatement( MultiTypedefStatement&& ) = default;
514+
515+ cosCommonVector <TypedefStatement*> defs;
516+};
517+
518+struct BlockStatement final : public COSNode
519+{
520+ inline BlockStatement( cosCommonVector <COSNode*> statements = {} ) noexcept : statements( std::move( statements ) )
521+ {
522+ return;
523+ }
524+ inline BlockStatement( const BlockStatement& ) = default;
525+ inline BlockStatement( BlockStatement&& right ) noexcept : statements( std::move( right.statements ) )
526+ {
527+ return;
528+ }
529+
530+ cosCommonVector <COSNode*> statements;
531+};
532+
533+struct ThrowStatement final : public COSNode
534+{
535+ inline ThrowStatement( COSNode *op = nullptr ) noexcept : op( op )
536+ {
537+ return;
538+ }
539+ inline ThrowStatement( const ThrowStatement& ) = default;
540+ inline ThrowStatement( ThrowStatement&& right ) noexcept
541+ {
542+ this->op = right.op;
543+
544+ right.op = nullptr;
545+ }
546+
547+ COSNode *op;
548+};
549+struct CatchStatement final : public COSNode
550+{
551+ inline CatchStatement( COSNode *caught_decl = nullptr, COSNode *catch_body = nullptr ) noexcept : caught_decl( caught_decl ), catch_body( catch_body )
552+ {
553+ return;
554+ }
555+ inline CatchStatement( const CatchStatement& ) = default;
556+ inline CatchStatement( CatchStatement&& right ) noexcept
557+ {
558+ this->caught_decl = right.caught_decl;
559+ this->catch_body = right.catch_body;
560+
561+ right.caught_decl = nullptr;
562+ right.catch_body = nullptr;
563+ }
564+
565+ COSNode *caught_decl;
566+ COSNode *catch_body;
567+};
568+struct TryStatement final : public COSNode
569+{
570+ inline TryStatement( COSNode *try_body = nullptr, cosCommonVector <CatchStatement*> errors = {} ) noexcept : try_body( try_body ), errors( std::move( errors ) )
571+ {
572+ return;
573+ }
574+ inline TryStatement( const TryStatement& ) = default;
575+ inline TryStatement( TryStatement&& right ) noexcept : errors( std::move( right.errors ) )
576+ {
577+ this->try_body = right.try_body;
578+
579+ right.try_body = nullptr;
580+ }
581+
582+ COSNode *try_body;
583+ cosCommonVector <CatchStatement*> errors;
584+};
585+
586+struct StructDefinition final : public COSNode
587+{
588+ inline StructDefinition( COSNode *name = nullptr, COSNode *body = nullptr ) noexcept : name( name ), body( body )
589+ {
590+ return;
591+ }
592+ inline StructDefinition( const StructDefinition& ) = default;
593+ inline StructDefinition( StructDefinition&& right ) noexcept
594+ {
595+ this->name = right.name;
596+ this->body = right.body;
597+
598+ right.name = nullptr;
599+ right.body = nullptr;
600+ }
601+
602+ COSNode *name;
603+ COSNode *body;
604+};
605+struct ConstructorDefinition final : public COSNode
606+{
607+ inline ConstructorDefinition( cosCommonVector <COSNode*> params = {}, COSNode *body = nullptr ) noexcept : params( std::move( params ) ), body( body )
608+ {
609+ return;
610+ }
611+ inline ConstructorDefinition( const ConstructorDefinition& ) = default;
612+ inline ConstructorDefinition( ConstructorDefinition&& right ) noexcept : params( std::move( right.params ) )
613+ {
614+ this->body = right.body;
615+
616+ right.body = nullptr;
617+ }
618+
619+ cosCommonVector <COSNode*> params;
620+ COSNode *body;
621+};
622+struct DestructorDefinition final : public COSNode
623+{
624+ inline DestructorDefinition( COSNode *body = nullptr ) noexcept
625+ {
626+ this->body = body;
627+ }
628+ inline DestructorDefinition( const DestructorDefinition& ) = default;
629+ inline DestructorDefinition( DestructorDefinition&& right ) noexcept
630+ {
631+ this->body = right.body;
632+
633+ right.body = nullptr;
634+ }
635+
636+ COSNode *body;
637+};
638+
639+struct SpecifierString final : public COSNode
640+{
641+ inline SpecifierString( cosCommonMultiString string = {} ) noexcept : string( std::move( string ) )
642+ {
643+ return;
644+ }
645+ inline SpecifierString( const SpecifierString& ) = default;
646+ inline SpecifierString( SpecifierString&& ) = default;
647+
648+ cosCommonMultiString string;
649+};
650+struct NumberString final : public COSNode
651+{
652+ inline NumberString( cosCommonMultiString string = {} ) noexcept : numeric_string( std::move( string ) )
653+ {
654+ return;
655+ }
656+ inline NumberString( const NumberString& ) = default;
657+ inline NumberString( NumberString&& ) = default;
658+
659+ cosCommonMultiString numeric_string;
660+};
661+struct SpecifierOperator final : public COSNode
662+{
663+ enum class eOpType
664+ {
665+ UNDEFINED,
666+
667+ ADD,
668+ SUBTRACT,
669+ MULTIPLY,
670+ DIVIDE,
671+ MODULUS,
672+ BIT_XOR,
673+ BIT_AND,
674+ BIT_OR,
675+ LOGICAL_NEGATE,
676+ DOT,
677+ ARROW,
678+ ASSIGN,
679+ BIT_NEGATE,
680+
681+ ASSIGN_ADD,
682+ ASSIGN_SUBTRACT,
683+ ASSIGN_MULTIPLY,
684+ ASSIGN_DIVIDE,
685+ ASSIGN_MODULUS,
686+ ASSIGN_BIT_XOR,
687+ ASSIGN_BIT_AND,
688+ ASSIGN_BIT_OR,
689+ ASSIGN_DOT,
690+ ASSIGN_ARROW,
691+ ASSIGN_BITSHIFT_LEFT,
692+ ASSIGN_BITSHIFT_RIGHT,
693+
694+ COMPARE_EQUALITY,
695+ COMPARE_GREATER_THAN,
696+ COMPARE_LESS_THAN,
697+ COMPARE_GREATER_THAN_EQUAL,
698+ COMPARE_LESS_THAN_EQUAL,
699+ COMPARE_INEQUALITY,
700+
701+ LOGICAL_AND,
702+ LOGICAL_OR,
703+ BITSHIFT_LEFT,
704+ BITSHIFT_RIGHT
705+ };
706+
707+ inline SpecifierOperator( eOpType op_type = eOpType::UNDEFINED ) noexcept : op_type( op_type )
708+ {
709+ return;
710+ }
711+ inline SpecifierOperator( const SpecifierOperator& ) = default;
712+ inline SpecifierOperator( SpecifierOperator&& ) = default;
713+
714+ eOpType op_type = eOpType::UNDEFINED;
715+};
716+
717+struct TypeSpecifier : public COSNode
718+{
719+ inline TypeSpecifier( COSNode *spec = nullptr ) noexcept : spec( spec )
720+ {}
721+ inline TypeSpecifier( const TypeSpecifier& ) = default;
722+ inline TypeSpecifier( TypeSpecifier&& right ) noexcept
723+ {
724+ this->spec = right.spec;
725+
726+ right.spec = nullptr;
727+ }
728+
729+ static inline COSNode* ResolveUntilMostSpecialized( COSNode *iter )
730+ {
731+ while ( true )
732+ {
733+ TypeSpecifier *type_spec = dynamic_cast <TypeSpecifier*> ( iter );
734+
735+ if ( type_spec == nullptr )
736+ {
737+ return iter;
738+ }
739+
740+ COSNode *more_specialized = type_spec->spec;
741+
742+ if ( more_specialized == nullptr )
743+ {
744+ return iter;
745+ }
746+
747+ iter = more_specialized;
748+ }
749+
750+ return nullptr;
751+ }
752+
753+ COSNode *spec;
754+};
755+struct PointerTypeSpecifier final : public TypeSpecifier
756+{
757+ using TypeSpecifier::TypeSpecifier;
758+};
759+struct RefTypeSpecifier final : public TypeSpecifier
760+{
761+ using TypeSpecifier::TypeSpecifier;
762+};
763+struct ArrayTypeSpecifier final : public TypeSpecifier
764+{
765+ inline ArrayTypeSpecifier( COSNode *spec = nullptr, COSNode *array_size_op = nullptr ) noexcept : TypeSpecifier( spec ), array_size_op( array_size_op )
766+ {
767+ return;
768+ }
769+ inline ArrayTypeSpecifier( const ArrayTypeSpecifier& ) = default;
770+ inline ArrayTypeSpecifier( ArrayTypeSpecifier&& right ) noexcept : TypeSpecifier( std::move( right ) )
771+ {
772+ this->array_size_op = right.array_size_op;
773+
774+ right.array_size_op = nullptr;
775+ }
776+
777+ COSNode *array_size_op;
778+};
779+
780+struct CurlyPack final : public COSNode
781+{
782+ inline CurlyPack( cosCommonVector <COSNode*> params = {} ) noexcept : params( std::move( params ) )
783+ {
784+ return;
785+ }
786+ inline CurlyPack( const CurlyPack& ) = default;
787+ inline CurlyPack( CurlyPack&& ) = default;
788+
789+ cosCommonVector <COSNode*> params;
790+};
791+struct ArrayDefinition final : public COSNode
792+{
793+ // { i1, ... in }
794+
795+ inline ArrayDefinition( cosCommonVector <COSNode*> items = {} ) noexcept : items( std::move( items ) )
796+ {
797+ return;
798+ }
799+ inline ArrayDefinition( const ArrayDefinition& ) = default;
800+ inline ArrayDefinition( ArrayDefinition&& ) = default;
801+
802+ cosCommonVector <COSNode*> items;
803+};
804+struct FuncsigDefinition final : public COSNode
805+{
806+ inline FuncsigDefinition( COSNode *return_type = nullptr, cosCommonVector <COSNode*> params = {} ) noexcept : return_type( return_type ), params( std::move( params ) )
807+ {}
808+ inline FuncsigDefinition( const FuncsigDefinition& ) = default;
809+ inline FuncsigDefinition( FuncsigDefinition&& right ) noexcept : params( std::move( right.params ) )
810+ {
811+ this->return_type = right.return_type;
812+
813+ right.return_type = nullptr;
814+ }
815+
816+ // Returns the left-most function signature definition of this node.
817+ inline FuncsigDefinition* GetDeepestReturnValueFunctionSignatureType( void )
818+ {
819+ FuncsigDefinition *deepest = this;
820+
821+ while ( FuncsigDefinition *any_deeper = dynamic_cast <FuncsigDefinition*> ( TypeSpecifier::ResolveUntilMostSpecialized( deepest->return_type ) ) )
822+ {
823+ deepest = any_deeper;
824+ }
825+
826+ return deepest;
827+ }
828+
829+ COSNode *return_type;
830+ cosCommonVector <COSNode*> params;
831+};
832+
833+struct NamespaceStatement final : public COSNode
834+{
835+ inline NamespaceStatement( COSNode *name = nullptr, COSNode *toinclude = nullptr ) noexcept : name( name ), toinclude( toinclude )
836+ {
837+ return;
838+ }
839+ inline NamespaceStatement( const NamespaceStatement& ) = default;
840+ inline NamespaceStatement( NamespaceStatement&& right ) noexcept
841+ {
842+ this->name = right.name;
843+ this->toinclude = right.toinclude;
844+
845+ right.name = nullptr;
846+ right.toinclude = nullptr;
847+ }
848+
849+ COSNode *name;
850+ COSNode *toinclude;
851+};
852+struct UsingNamespaceStatement final : public COSNode
853+{
854+ inline UsingNamespaceStatement( COSNode *nsname = nullptr ) noexcept : nsname( nsname )
855+ {
856+ return;
857+ }
858+ inline UsingNamespaceStatement( const UsingNamespaceStatement& ) = default;
859+ inline UsingNamespaceStatement( UsingNamespaceStatement&& right ) noexcept
860+ {
861+ this->nsname = right.nsname;
862+
863+ right.nsname = nullptr;
864+ }
865+
866+ COSNode *nsname;
867+};
868+
869+struct EnumDefinition final : public COSNode
870+{
871+ struct item
872+ {
873+ COSNode *key;
874+ COSNode *value;
875+ };
876+
877+ inline EnumDefinition( COSNode *name = nullptr, cosCommonVector <item> items = {} ) noexcept : name( name ), items( std::move( items ) )
878+ {
879+ return;
880+ }
881+ inline EnumDefinition( const EnumDefinition& ) = default;
882+ inline EnumDefinition( EnumDefinition&& right ) noexcept : items( std::move( right.items ) )
883+ {
884+ this->name = right.name;
885+
886+ right.name = nullptr;
887+ }
888+
889+ COSNode *name;
890+ cosCommonVector <item> items;
891+};
892+
893+}; // namespace COS
\ No newline at end of file
--- commonlangs/include/commonlangs/cos_env.h (nonexistent)
+++ commonlangs/include/commonlangs/cos_env.h (revision 73)
@@ -0,0 +1,2462 @@
1+#pragma once
2+
3+// Compiler-Objects-Syntax environment structure.
4+
5+#include <sdk/eirutils.h>
6+
7+#include "cos.h"
8+
9+#include <eircompile/lexing.h>
10+#include <eircompile/lexing_compile.h>
11+
12+namespace COS
13+{
14+
15+#define COS_TEMPLARGS \
16+template <eir::MemoryAllocator allocatorType>
17+
18+#define COS_TEMPLUSE \
19+<allocatorType>
20+
21+COS_TEMPLARGS
22+struct COSEnvironment
23+{
24+private:
25+ static inline bool is_num_nonzero( char c ) noexcept
26+ {
27+ static const char num_nonzero[] = "123456789";
28+
29+ for ( char oc : num_nonzero )
30+ {
31+ if ( oc == c )
32+ return true;
33+ }
34+ return false;
35+ }
36+
37+ static inline bool is_num( char c ) noexcept
38+ {
39+ return ( c == '0' ) || is_num_nonzero( c );
40+ }
41+
42+ static inline bool is_alpha( char c ) noexcept
43+ {
44+ static const char alpha[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
45+
46+ for ( char oc : alpha )
47+ {
48+ if ( oc == c )
49+ return true;
50+ }
51+ return false;
52+ }
53+
54+ static inline bool is_alpha_num( char c ) noexcept
55+ {
56+ return is_num( c ) || is_alpha( c );
57+ }
58+
59+ static inline bool is_name_special( char c ) noexcept
60+ {
61+ static const char spc[] = "_";
62+
63+ for ( char oc : spc )
64+ {
65+ if ( oc == c )
66+ return true;
67+ }
68+ return false;
69+ }
70+
71+ static inline bool is_name_char( char c ) noexcept
72+ {
73+ return is_alpha_num( c ) || is_name_special( c );
74+ }
75+
76+ static inline bool is_name_alpha( char c ) noexcept
77+ {
78+ return is_alpha( c ) || is_name_special( c );
79+ }
80+
81+ static inline bool is_space_char( char c ) noexcept
82+ {
83+ static const char spaces[] = " \t\n\r";
84+
85+ for ( char oc : spaces )
86+ {
87+ if ( oc == c )
88+ return true;
89+ }
90+ return false;
91+ }
92+
93+ struct EnvironmentAllocator
94+ {
95+ inline EnvironmentAllocator( COSEnvironment *env ) noexcept : env( env )
96+ {}
97+
98+ inline void* Allocate( void *refPtr, size_t memSize, size_t align ) noexcept
99+ {
100+ return env->allocMan.Allocate( nullptr, memSize, align );
101+ }
102+
103+ inline bool Resize( void *refPtr, void *memPtr, size_t memSize ) noexcept requires ( eir::ResizeMemoryAllocator <allocatorType> )
104+ {
105+ return env->allocMan.Resize( nullptr, memPtr, memSize );
106+ }
107+
108+ inline void* Realloc( void *refPtr, void *memPtr, size_t memSize, size_t align ) noexcept requires ( eir::ReallocMemoryAllocator <allocatorType> )
109+ {
110+ return env->allocMan.Realloc( nullptr, memPtr, memSize, align );
111+ }
112+
113+ inline void Free( void *refPtr, void *memPtr ) noexcept
114+ {
115+ env->allocMan.Free( nullptr, memPtr );
116+ }
117+
118+ private:
119+ COSEnvironment *env;
120+ };
121+
122+ // Data members.
123+ [[no_unique_address]] allocatorType allocMan;
124+
125+ DEFINE_HEAP_REDIR_ALLOC_BYSTRUCT( lexer_redirAlloc, allocatorType );
126+
127+ Lexer <char, COSNode, lexer_redirAlloc> lexer;
128+
129+ typedef typename decltype(lexer)::RuntimeEnv COSRuntimeEnv;
130+
131+public:
132+ template <typename... allocArgs>
133+ inline COSEnvironment( eir::constr_with_alloc _, allocArgs&&... args ) : allocMan( std::forward <allocArgs> ( args )... )
134+ {
135+ auto& lexer = this->lexer;
136+
137+ LexingCompiler <char, COSRuntimeEnv, EnvironmentAllocator> compiler( eir::constr_with_alloc::DEFAULT, this );
138+
139+ // Generate the COS syntax.
140+ assert( lexer.CompileProduction( compiler, "S", "spaces [<0,e>statement, spaces]" ) == true );
141+ {
142+ struct program_dispatcher
143+ {
144+ inline Program* CreateNode( COSNode *first )
145+ {
146+ Program *node = new Program();
147+ node->statements.AddToBack( first );
148+ return node;
149+ }
150+
151+ static inline bool AssignNodeTo( Program *assign_to, const eir::FixedString <char>& attrib, COSNode *node )
152+ {
153+ assign_to->statements.AddToBack( node );
154+ return true;
155+ }
156+ };
157+ lexer.GetNamedProduction( "S" ).setSelector <mintwo_specialized_selector <char, Program, COSNode, program_dispatcher, COSRuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
158+ }
159+ assert( lexer.CompileProduction( compiler, "statement", "typedef | block | loop | if | except | objmod | namespace | enum | multdecl | takefirst operation spaces ';'" ) == true );
160+ assert( lexer.CompileProduction( compiler, "funcbody", "^(statement, <b> funcstatement)" ) == true );
161+ assert( lexer.CompileProduction( compiler, "funcstatement", "\"return\" spaces (op:operation spaces)^0:1 ';'" ) == true );
162+ {
163+ struct return_dispatcher
164+ {
165+ static inline bool AssignNodeTo( ReturnStatement *assign_to, const eir::FixedString <char>& attrib, COSNode *node )
166+ {
167+ if ( attrib == "op" )
168+ {
169+ assign_to->op = node;
170+ return true;
171+ }
172+ return false;
173+ }
174+ };
175+ lexer.GetNamedProduction( "funcstatement" ).GetLastStep()->setSelector <direct_obj_build_selector <char, ReturnStatement, COSNode, return_dispatcher, COSRuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
176+ }
177+ assert( lexer.CompileProduction( compiler, "optoksingle_epostfix", "\"->\" | \"<<\" | \">>\" | '+-*/%^&|!.=<>'" ) == true );
178+ assert( lexer.CompileProduction( compiler, "optoksingle", "'~' | optoksingle_epostfix" ) == true );
179+ assert( lexer.CompileProduction( compiler, "optoks", "\"&&\" | \"||\" | optoksingle_epostfix '=' | optoksingle" ) == true );
180+ assert( lexer.CompileProduction( compiler, "spec", "\"operator\" spaces optok:optoks" ) == true );
181+ {
182+ struct specifier_op_dispatcher
183+ {
184+ static inline void AssignAttributeTo( SpecifierOperator *assign_to, const eir::FixedString <char>& attrib, const eir::FixedString <char>& value )
185+ {
186+ if ( attrib != "optok" )
187+ return;
188+
189+ typedef SpecifierOperator::eOpType eOpType;
190+
191+ if ( value == "+" )
192+ {
193+ assign_to->op_type = eOpType::ADD;
194+ }
195+ else if ( value == "+=" )
196+ {
197+ assign_to->op_type = eOpType::ASSIGN_ADD;
198+ }
199+ else if ( value == "-" )
200+ {
201+ assign_to->op_type = eOpType::SUBTRACT;
202+ }
203+ else if ( value == "-=" )
204+ {
205+ assign_to->op_type = eOpType::ASSIGN_SUBTRACT;
206+ }
207+ else if ( value == "*" )
208+ {
209+ assign_to->op_type = eOpType::MULTIPLY;
210+ }
211+ else if ( value == "*=" )
212+ {
213+ assign_to->op_type = eOpType::ASSIGN_MULTIPLY;
214+ }
215+ else if ( value == "/" )
216+ {
217+ assign_to->op_type = eOpType::DIVIDE;
218+ }
219+ else if ( value == "/=" )
220+ {
221+ assign_to->op_type = eOpType::ASSIGN_DIVIDE;
222+ }
223+ else if ( value == "%" )
224+ {
225+ assign_to->op_type = eOpType::MODULUS;
226+ }
227+ else if ( value == "%=" )
228+ {
229+ assign_to->op_type = eOpType::ASSIGN_MODULUS;
230+ }
231+ else if ( value == "^" )
232+ {
233+ assign_to->op_type = eOpType::BIT_XOR;
234+ }
235+ else if ( value == "^=" )
236+ {
237+ assign_to->op_type = eOpType::ASSIGN_BIT_XOR;
238+ }
239+ else if ( value == "&" )
240+ {
241+ assign_to->op_type = eOpType::BIT_AND;
242+ }
243+ else if ( value == "&=" )
244+ {
245+ assign_to->op_type = eOpType::ASSIGN_BIT_AND;
246+ }
247+ else if ( value == "|" )
248+ {
249+ assign_to->op_type = eOpType::BIT_OR;
250+ }
251+ else if ( value == "|=" )
252+ {
253+ assign_to->op_type = eOpType::ASSIGN_BIT_OR;
254+ }
255+ else if ( value == "!" )
256+ {
257+ assign_to->op_type = eOpType::LOGICAL_NEGATE;
258+ }
259+ else if ( value == "!=" )
260+ {
261+ assign_to->op_type = eOpType::COMPARE_INEQUALITY;
262+ }
263+ else if ( value == "." )
264+ {
265+ assign_to->op_type = eOpType::DOT;
266+ }
267+ else if ( value == ".=" )
268+ {
269+ assign_to->op_type = eOpType::ASSIGN_DOT;
270+ }
271+ else if ( value == "->" )
272+ {
273+ assign_to->op_type = eOpType::ARROW;
274+ }
275+ else if ( value == "->=" )
276+ {
277+ assign_to->op_type = eOpType::ASSIGN_ARROW;
278+ }
279+ else if ( value == "=" )
280+ {
281+ assign_to->op_type = eOpType::ASSIGN;
282+ }
283+ else if ( value == "==" )
284+ {
285+ assign_to->op_type = eOpType::COMPARE_EQUALITY;
286+ }
287+ else if ( value == "~" )
288+ {
289+ assign_to->op_type = eOpType::BIT_NEGATE;
290+ }
291+ else if ( value == "<" )
292+ {
293+ assign_to->op_type = eOpType::COMPARE_LESS_THAN;
294+ }
295+ else if ( value == "<=" )
296+ {
297+ assign_to->op_type = eOpType::COMPARE_LESS_THAN_EQUAL;
298+ }
299+ else if ( value == ">" )
300+ {
301+ assign_to->op_type = eOpType::COMPARE_GREATER_THAN;
302+ }
303+ else if ( value == ">=" )
304+ {
305+ assign_to->op_type = eOpType::COMPARE_GREATER_THAN_EQUAL;
306+ }
307+ else if ( value == "&&" )
308+ {
309+ assign_to->op_type = eOpType::BIT_AND;
310+ }
311+ else if ( value == "||" )
312+ {
313+ assign_to->op_type = eOpType::BIT_OR;
314+ }
315+ else if ( value == "<<" )
316+ {
317+ assign_to->op_type = eOpType::BITSHIFT_LEFT;
318+ }
319+ else if ( value == "<<=" )
320+ {
321+ assign_to->op_type = eOpType::ASSIGN_BITSHIFT_LEFT;
322+ }
323+ else if ( value == ">>" )
324+ {
325+ assign_to->op_type = eOpType::BITSHIFT_RIGHT;
326+ }
327+ else if ( value == ">>=" )
328+ {
329+ assign_to->op_type = eOpType::ASSIGN_BITSHIFT_RIGHT;
330+ }
331+ }
332+ };
333+ lexer.GetNamedProduction( "spec" ).GetLastStep()->setSelector <direct_obj_build_selector <char, SpecifierOperator, COSNode, specifier_op_dispatcher, COSRuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
334+ }
335+ assert( lexer.CompileProduction( compiler, "spec", "npath" ) == true );
336+ assert( lexer.CompileProduction( compiler, "spec", "\"$[\" spaces op:operation spaces ']'" ) == true );
337+ {
338+ struct dynspec_dispatcher
339+ {
340+ static inline bool AssignNodeTo( ResolveSpecifierOperation *assign_to, const eir::FixedString <char>& attrib, COSNode *node )
341+ {
342+ if ( attrib == "op" )
343+ {
344+ assign_to->op = node;
345+ return true;
346+ }
347+ return false;
348+ }
349+ };
350+ lexer.GetNamedProduction( "spec" ).GetLastStep()->setSelector <direct_obj_build_selector <char, ResolveSpecifierOperation, COSNode, dynspec_dispatcher, COSRuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
351+ }
352+ assert( lexer.CompileProduction( compiler, "dtypedef", "takefirst \"typedef\" spaces tmultdecl spaces ';'" ) == true );
353+ assert( lexer.CompileProduction( compiler, "block", "'{' spaces [<0>statement:extended statement, spaces] spaces '}'" ) == true );
354+ assert( lexer.CompileProduction( compiler, "nblock", "'{' spaces [<0>statement:statement, spaces] spaces '}'" ) == true );
355+ {
356+ struct block_dispatcher
357+ {
358+ static inline bool AssignNodeTo( BlockStatement *assign_to, const eir::FixedString <char>& attrib, COSNode *node )
359+ {
360+ if ( attrib == "statement" )
361+ {
362+ assign_to->statements.AddToBack( node );
363+ return true;
364+ }
365+ return false;
366+ }
367+ };
368+ lexer.GetNamedProduction( "block" ).setSelector <direct_obj_build_selector <char, BlockStatement, COSNode, block_dispatcher, COSRuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
369+ lexer.GetNamedProduction( "nblock" ).setSelector <direct_obj_build_selector <char, BlockStatement, COSNode, block_dispatcher, COSRuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
370+ }
371+
372+ // Create the special "operation" step.
373+ {
374+ auto operation = lexer.MakeStep <COSRuntimeEnv::StepProceduralSequence> ();
375+
376+ assert( lexer.CompileInto( compiler, operation, "[opitem:operation, spaces optype:('=' | \"+=\" | \"-=\" | \"*=\" | \"/=\" | \"%=\" | \"^=\" | \"&=\" | \"|=\" | \".=\" | \"->=\") spaces]" ) != nullptr );
377+ {
378+ struct assignment_dispatcher
379+ {
380+ enum class eOpType
381+ {
382+ UNSPECIFIED,
383+ ASSIGN,
384+ ASSIGN_ADD,
385+ ASSIGN_SUB,
386+ ASSIGN_MUL,
387+ ASSIGN_DIV,
388+ ASSIGN_MODULUS,
389+ ASSIGN_BIT_XOR,
390+ ASSIGN_BIT_AND,
391+ ASSIGN_BIT_OR,
392+ ASSIGN_DOT,
393+ ASSIGN_ARROW,
394+ ASSIGN_BITSHIFT_LEFT,
395+ ASSIGN_BITSHIFT_RIGHT
396+ };
397+
398+ inline void AssignAttribute( const eir::FixedString <char>& attrib, const eir::FixedString <char>& value )
399+ {
400+ if ( attrib != "optype" )
401+ return;
402+
403+ if ( value == "=" )
404+ {
405+ this->op_type = eOpType::ASSIGN;
406+ }
407+ else if ( value == "+=" )
408+ {
409+ this->op_type = eOpType::ASSIGN_ADD;
410+ }
411+ else if ( value == "-=" )
412+ {
413+ this->op_type = eOpType::ASSIGN_SUB;
414+ }
415+ else if ( value == "*=" )
416+ {
417+ this->op_type = eOpType::ASSIGN_MUL;
418+ }
419+ else if ( value == "/=" )
420+ {
421+ this->op_type = eOpType::ASSIGN_DIV;
422+ }
423+ else if ( value == "%=" )
424+ {
425+ this->op_type = eOpType::ASSIGN_MODULUS;
426+ }
427+ else if ( value == "^=" )
428+ {
429+ this->op_type = eOpType::ASSIGN_BIT_XOR;
430+ }
431+ else if ( value == "&=" )
432+ {
433+ this->op_type = eOpType::ASSIGN_BIT_AND;
434+ }
435+ else if ( value == "|=" )
436+ {
437+ this->op_type = eOpType::ASSIGN_BIT_OR;
438+ }
439+ else if ( value == ".=" )
440+ {
441+ this->op_type = eOpType::ASSIGN_DOT;
442+ }
443+ else if ( value == "->=" )
444+ {
445+ this->op_type = eOpType::ASSIGN_ARROW;
446+ }
447+ else if ( value == "<<=" )
448+ {
449+ this->op_type = eOpType::ASSIGN_BITSHIFT_LEFT;
450+ }
451+ else if ( value == ">>=" )
452+ {
453+ this->op_type = eOpType::ASSIGN_BITSHIFT_RIGHT;
454+ }
455+ }
456+
457+ inline COSNode* CreateOperation( COSNode *left, COSNode *right ) const
458+ {
459+ eOpType op_type = this->op_type;
460+
461+ if ( op_type == eOpType::ASSIGN )
462+ {
463+ return new AssignmentOperation( left, right );
464+ }
465+ else if ( op_type == eOpType::ASSIGN_ADD )
466+ {
467+ return new AssignAddOperation( left, right );
468+ }
469+ else if ( op_type == eOpType::ASSIGN_SUB )
470+ {
471+ return new AssignSubOperation( left, right );
472+ }
473+ else if ( op_type == eOpType::ASSIGN_MUL )
474+ {
475+ return new AssignMulOperation( left, right );
476+ }
477+ else if ( op_type == eOpType::ASSIGN_DIV )
478+ {
479+ return new AssignDivOperation( left, right );
480+ }
481+ else if ( op_type == eOpType::ASSIGN_MODULUS )
482+ {
483+ return new AssignModulusOperation( left, right );
484+ }
485+ else if ( op_type == eOpType::ASSIGN_BIT_XOR )
486+ {
487+ return new AssignBitwiseXorOperation( left, right );
488+ }
489+ else if ( op_type == eOpType::ASSIGN_BIT_AND )
490+ {
491+ return new AssignBitwiseAndOperation( left, right );
492+ }
493+ else if ( op_type == eOpType::ASSIGN_BIT_OR )
494+ {
495+ return new AssignBitwiseOrOperation( left, right );
496+ }
497+ else if ( op_type == eOpType::ASSIGN_DOT )
498+ {
499+ return new AssignDotOperation( left, right );
500+ }
501+ else if ( op_type == eOpType::ASSIGN_ARROW )
502+ {
503+ return new AssignArrowOperation( left, right );
504+ }
505+ else if ( op_type == eOpType::ASSIGN_BITSHIFT_LEFT )
506+ {
507+ return new AssignBitshiftLeftOperation( left, right );
508+ }
509+ else if ( op_type == eOpType::ASSIGN_BITSHIFT_RIGHT )
510+ {
511+ return new AssignBitshiftRightOperation( left, right );
512+ }
513+
514+ throw lexing_invalid_parameter_exception();
515+ }
516+
517+ eOpType op_type = eOpType::UNSPECIFIED;
518+ };
519+ operation.GetLastStep()->setSelector <right_associative_selector <char, COSNode, assignment_dispatcher, COSRuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
520+ }
521+ assert( lexer.CompileInto( compiler, operation, "[opitem:operation, spaces optype:\"||\" spaces]" ) != nullptr );
522+ {
523+ struct logical_or_dispatcher
524+ {
525+ inline void AssignAttribute( const eir::FixedString <char>& attrib, const eir::FixedString <char>& value )
526+ {
527+ return;
528+ }
529+
530+ inline COSNode* CreateOperation( COSNode *left, COSNode *right )
531+ {
532+ return new LogicalOrOperation( left, right );
533+ }
534+ };
535+ operation.GetLastStep()->setSelector <left_associative_selector <char, COSNode, logical_or_dispatcher, COSRuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
536+ }
537+ assert( lexer.CompileInto( compiler, operation, "[opitem:operation, spaces optype:\"&&\" spaces]" ) != nullptr );
538+ {
539+ struct logical_and_dispatcher
540+ {
541+ inline void AssignAttribute( const eir::FixedString <char>& attrib, const eir::FixedString <char>& value )
542+ {
543+ return;
544+ }
545+
546+ inline COSNode* CreateOperation( COSNode *left, COSNode *right )
547+ {
548+ return new LogicalAndOperation( left, right );
549+ }
550+ };
551+ operation.GetLastStep()->setSelector <left_associative_selector <char, COSNode, logical_and_dispatcher, COSRuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
552+ }
553+ assert( lexer.CompileInto( compiler, operation, "[opitem:operation, spaces optype:'|' spaces]" ) != nullptr );
554+ {
555+ struct bor_dispatcher
556+ {
557+ inline void AssignAttribute( const eir::FixedString <char>& attrib, const eir::FixedString <char>& value )
558+ {
559+ return;
560+ }
561+
562+ inline COSNode* CreateOperation( COSNode *left, COSNode *right )
563+ {
564+ return new BitwiseOrOperation( left, right );
565+ }
566+ };
567+ operation.GetLastStep()->setSelector <left_associative_selector <char, COSNode, bor_dispatcher, COSRuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
568+ }
569+ assert( lexer.CompileInto( compiler, operation, "[opitem:operation, spaces optype:'^' spaces]" ) != nullptr );
570+ {
571+ struct bxor_dispatcher
572+ {
573+ inline void AssignAttribute( const eir::FixedString <char>& attrib, const eir::FixedString <char>& value )
574+ {
575+ return;
576+ }
577+
578+ inline COSNode* CreateOperation( COSNode *left, COSNode *right )
579+ {
580+ return new BitwiseXorOperation( left, right );
581+ }
582+ };
583+ operation.GetLastStep()->setSelector <left_associative_selector <char, COSNode, bxor_dispatcher, COSRuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
584+ }
585+ assert( lexer.CompileInto( compiler, operation, "[opitem:operation, spaces optype:('&'^1:2) spaces]" ) != nullptr );
586+ {
587+ struct band_dispatcher
588+ {
589+ inline void AssignAttribute( const eir::FixedString <char>& attrib, const eir::FixedString <char>& value )
590+ {
591+ if ( attrib == "optype" )
592+ {
593+ if ( value == "&&" )
594+ {
595+ // This is important because a double-ampersand can never be a bitwise-and.
596+ throw lexing_invalid_parameter_exception();
597+ }
598+ }
599+ }
600+
601+ inline COSNode* CreateOperation( COSNode *left, COSNode *right )
602+ {
603+ return new BitwiseAndOperation( left, right );
604+ }
605+ };
606+ operation.GetLastStep()->setSelector <left_associative_selector <char, COSNode, band_dispatcher, COSRuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
607+ }
608+ assert( lexer.CompileInto( compiler, operation, "[opitem:operation, spaces optype:(\"==\" | \"!=\" | \"<=\" | \">=\" | '<' | '>') spaces]" ) != nullptr );
609+ {
610+ struct logical_comparison_dispatcher
611+ {
612+ enum class eCompType
613+ {
614+ UNDEFINED,
615+ EQUALITY,
616+ INEQUALITY,
617+ LESS_THAN,
618+ GREATER_THAN,
619+ LESS_EQUAL_THAN,
620+ GREATER_EQUAL_THAN
621+ };
622+
623+ inline void AssignAttribute( const eir::FixedString <char>& attrib, const eir::FixedString <char>& value )
624+ {
625+ if ( attrib == "optype" )
626+ {
627+ if ( value == "==" )
628+ {
629+ this->comp_type = eCompType::EQUALITY;
630+ }
631+ else if ( value == "!=" )
632+ {
633+ this->comp_type = eCompType::INEQUALITY;
634+ }
635+ else if ( value == "<" )
636+ {
637+ this->comp_type = eCompType::LESS_THAN;
638+ }
639+ else if ( value == ">" )
640+ {
641+ this->comp_type = eCompType::GREATER_THAN;
642+ }
643+ else if ( value == "<=" )
644+ {
645+ this->comp_type = eCompType::LESS_EQUAL_THAN;
646+ }
647+ else if ( value == ">=" )
648+ {
649+ this->comp_type = eCompType::GREATER_EQUAL_THAN;
650+ }
651+ }
652+ }
653+
654+ inline COSNode* CreateOperation( COSNode *left, COSNode *right )
655+ {
656+ eCompType comp_type = this->comp_type;
657+
658+ if ( comp_type == eCompType::EQUALITY )
659+ {
660+ return new CompareEqualityOperation( left, right );
661+ }
662+ else if ( comp_type == eCompType::INEQUALITY )
663+ {
664+ return new CompareInequalityOperation( left, right );
665+ }
666+ else if ( comp_type == eCompType::LESS_THAN )
667+ {
668+ return new CompareLessThanOperation( left, right );
669+ }
670+ else if ( comp_type == eCompType::GREATER_THAN )
671+ {
672+ return new CompareGreaterThanOperation( left, right );
673+ }
674+ else if ( comp_type == eCompType::LESS_EQUAL_THAN )
675+ {
676+ return new CompareLessThanEqualOperation( left, right );
677+ }
678+ else if ( comp_type == eCompType::GREATER_EQUAL_THAN )
679+ {
680+ return new CompareGreaterThanEqualOperation( left, right );
681+ }
682+ else
683+ {
684+ throw lexing_invalid_parameter_exception();
685+ }
686+ }
687+
688+ eCompType comp_type = eCompType::UNDEFINED;
689+ };
690+ operation.GetLastStep()->setSelector <left_associative_selector <char, COSNode, logical_comparison_dispatcher, COSRuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
691+ }
692+ assert( lexer.CompileInto( compiler, operation, "[opitem:operation, spaces optype:(\"<<\"|\">>\") spaces]" ) != nullptr );
693+ {
694+ struct bitwise_shift_dispatcher
695+ {
696+ enum class eOpType
697+ {
698+ UNDEFINED,
699+ LEFT_SHIFT,
700+ RIGHT_SHIFT
701+ };
702+
703+ inline void AssignAttribute( const eir::FixedString <char>& attrib, const eir::FixedString <char>& value )
704+ {
705+ if ( attrib == "optype" )
706+ {
707+ if ( value == "<<" )
708+ {
709+ this->op_type = eOpType::LEFT_SHIFT;
710+ }
711+ else if ( value == ">>" )
712+ {
713+ this->op_type = eOpType::RIGHT_SHIFT;
714+ }
715+ }
716+ }
717+
718+ inline COSNode* CreateOperation( COSNode *left, COSNode *right )
719+ {
720+ eOpType op_type = this->op_type;
721+
722+ if ( op_type == eOpType::LEFT_SHIFT )
723+ {
724+ return new BitshiftLeftOperation( left, right );
725+ }
726+ else if ( op_type == eOpType::RIGHT_SHIFT )
727+ {
728+ return new BitshiftRightOperation( left, right );
729+ }
730+
731+ throw lexing_invalid_parameter_exception();
732+ }
733+
734+ eOpType op_type = eOpType::UNDEFINED;
735+ };
736+ operation.GetLastStep()->setSelector <left_associative_selector <char, COSNode, bitwise_shift_dispatcher, COSRuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
737+ }
738+ assert( lexer.CompileInto( compiler, operation, "[opitem:operation, spaces optype:('-'|'+') spaces]" ) != nullptr );
739+ {
740+ struct summation_dispatcher
741+ {
742+ enum class eOpType
743+ {
744+ UNDEFINED,
745+ ADDITION,
746+ SUBTRACTION
747+ };
748+
749+ inline void AssignAttribute( const eir::FixedString <char>& attrib, const eir::FixedString <char>& value )
750+ {
751+ if ( attrib == "optype" )
752+ {
753+ if ( value == "+" )
754+ {
755+ this->op_type = eOpType::ADDITION;
756+ }
757+ else if ( value == "-" )
758+ {
759+ this->op_type = eOpType::SUBTRACTION;
760+ }
761+ }
762+ }
763+
764+ inline COSNode* CreateOperation( COSNode *left, COSNode *right )
765+ {
766+ eOpType op_type = this->op_type;
767+
768+ if ( op_type == eOpType::ADDITION )
769+ {
770+ return new AddOperation( left, right );
771+ }
772+ else if ( op_type == eOpType::SUBTRACTION )
773+ {
774+ return new SubOperation( left, right );
775+ }
776+
777+ throw lexing_invalid_parameter_exception();
778+ }
779+
780+ eOpType op_type = eOpType::UNDEFINED;
781+ };
782+ operation.GetLastStep()->setSelector <left_associative_selector <char, COSNode, summation_dispatcher, COSRuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
783+ }
784+ assert( lexer.CompileInto( compiler, operation, "[opitem:operation, spaces optype:('*'|'/'|'%') spaces]" ) != nullptr );
785+ {
786+ struct muldiv_dispatcher
787+ {
788+ enum class eOpType
789+ {
790+ UNDEFINED,
791+ MULTIPLY,
792+ DIVIDE,
793+ MODULUS
794+ };
795+
796+ inline void AssignAttribute( const eir::FixedString <char>& attrib, const eir::FixedString <char>& value )
797+ {
798+ if ( attrib == "optype" )
799+ {
800+ if ( value == "*" )
801+ {
802+ this->op_type = eOpType::MULTIPLY;
803+ }
804+ else if ( value == "/" )
805+ {
806+ this->op_type = eOpType::DIVIDE;
807+ }
808+ else if ( value == "%" )
809+ {
810+ this->op_type = eOpType::MODULUS;
811+ }
812+ }
813+ }
814+
815+ inline COSNode* CreateOperation( COSNode *left, COSNode *right )
816+ {
817+ eOpType op_type = this->op_type;
818+
819+ if ( op_type == eOpType::MULTIPLY )
820+ {
821+ return new MulOperation( left, right );
822+ }
823+ else if ( op_type == eOpType::DIVIDE )
824+ {
825+ return new DivOperation( left, right );
826+ }
827+ else if ( op_type == eOpType::MODULUS )
828+ {
829+ return new ModulusOperation( left, right );
830+ }
831+
832+ throw lexing_invalid_parameter_exception();
833+ }
834+
835+ eOpType op_type = eOpType::UNDEFINED;
836+ };
837+ operation.GetLastStep()->setSelector <left_associative_selector <char, COSNode, muldiv_dispatcher, COSRuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
838+ }
839+ assert( lexer.CompileInto( compiler, operation, "[<0,e>pre_optype:(\"++\" | \"--\"), spaces] opitem:operation [<0,e> spaces, post_optype:(\"++\" | \"--\")]" ) != nullptr );
840+ {
841+ struct quickunamod_dispatcher
842+ {
843+ enum class eOpType
844+ {
845+ UNDEFINED,
846+ PRE_INCREMENT,
847+ PRE_DECREMENT,
848+ POST_INCREMENT,
849+ POST_DECREMENT
850+ };
851+
852+ inline void AssignAttribute( const eir::FixedString <char>& attrib, const eir::FixedString <char>& value )
853+ {
854+ if ( attrib == "pre_optype" )
855+ {
856+ if ( value == "++" )
857+ {
858+ this->op_type = eOpType::PRE_INCREMENT;
859+ }
860+ else if ( value == "--" )
861+ {
862+ this->op_type = eOpType::PRE_DECREMENT;
863+ }
864+ }
865+ else if ( attrib == "post_optype" )
866+ {
867+ if ( value == "++" )
868+ {
869+ this->op_type = eOpType::POST_INCREMENT;
870+ }
871+ else if ( value == "--" )
872+ {
873+ this->op_type = eOpType::POST_DECREMENT;
874+ }
875+ }
876+ }
877+
878+ inline COSNode* CreateOperation( COSNode *op )
879+ {
880+ eOpType op_type = this->op_type;
881+
882+ if ( op_type == eOpType::PRE_INCREMENT )
883+ {
884+ return new PreIncrementOperation( op );
885+ }
886+ else if ( op_type == eOpType::PRE_DECREMENT )
887+ {
888+ return new PreDecrementOperation( op );
889+ }
890+ else if ( op_type == eOpType::POST_INCREMENT )
891+ {
892+ return new PostIncrementOperation( op );
893+ }
894+ else if ( op_type == eOpType::POST_DECREMENT )
895+ {
896+ return new PostDecrementOperation( op );
897+ }
898+
899+ throw lexing_invalid_parameter_exception();
900+ }
901+
902+ eOpType op_type = eOpType::UNDEFINED;
903+ };
904+ operation.GetLastStep()->setSelector <unary_operation_selector <char, COSNode, quickunamod_dispatcher, COSRuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
905+ }
906+ assert( lexer.CompileInto( compiler, operation, "[<0,e>optype:'-~!*&', spaces] opitem:operation" ) != nullptr );
907+ {
908+ struct unary_negation_dispatcher
909+ {
910+ enum class eOpType
911+ {
912+ UNDEFINED,
913+ NUMERIC_NEGATION,
914+ BITWISE_NEGATION,
915+ LOGICAL_NEGATION,
916+ PTR_RESOLVE,
917+ ADDRESS_OF
918+ };
919+
920+ inline void AssignAttribute( const eir::FixedString <char>& attrib, const eir::FixedString <char>& value )
921+ {
922+ if ( attrib == "optype" )
923+ {
924+ if ( value == "-" )
925+ {
926+ this->op_type = eOpType::NUMERIC_NEGATION;
927+ }
928+ else if ( value == "~" )
929+ {
930+ this->op_type = eOpType::BITWISE_NEGATION;
931+ }
932+ else if ( value == "!" )
933+ {
934+ this->op_type = eOpType::LOGICAL_NEGATION;
935+ }
936+ else if ( value == "*" )
937+ {
938+ this->op_type = eOpType::PTR_RESOLVE;
939+ }
940+ else if ( value == "&" )
941+ {
942+ this->op_type = eOpType::ADDRESS_OF;
943+ }
944+ }
945+ }
946+
947+ inline COSNode* CreateOperation( COSNode *op )
948+ {
949+ eOpType op_type = this->op_type;
950+
951+ if ( op_type == eOpType::NUMERIC_NEGATION )
952+ {
953+ return new NumericNegationOperation( op );
954+ }
955+ else if ( op_type == eOpType::BITWISE_NEGATION )
956+ {
957+ return new BitwiseNegationOperation( op );
958+ }
959+ else if ( op_type == eOpType::LOGICAL_NEGATION )
960+ {
961+ return new LogicalNegationOperation( op );
962+ }
963+ else if ( op_type == eOpType::PTR_RESOLVE )
964+ {
965+ return new PointerResolveOperation( op );
966+ }
967+ else if ( op_type == eOpType::ADDRESS_OF )
968+ {
969+ return new AddressOfOperation( op );
970+ }
971+
972+ throw lexing_invalid_parameter_exception();
973+ }
974+
975+ eOpType op_type = eOpType::UNDEFINED;
976+ };
977+ operation.GetLastStep()->setSelector <unary_operation_selector <char, COSNode, unary_negation_dispatcher, COSRuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
978+ }
979+ assert( lexer.CompileInto( compiler, operation, "tocall:operation (spaces [begcall:'(' spaces [<0>param:procgate operation, spaces ',' spaces] spaces endcall:')', spaces])^0:1" ) != nullptr );
980+ {
981+ struct call_selector
982+ {
983+ inline call_selector( COSRuntimeEnv *env ) noexcept : env( env )
984+ {
985+ return;
986+ }
987+ inline call_selector( const call_selector& right )
988+ : env( right.env ), root( right.root ), call_params( right.call_params ), is_call( right.is_call )
989+ {
990+ auto *env = this->env;
991+
992+ if ( COSNode *root = this->root )
993+ {
994+ env->lifetimeMan.AddRef( root );
995+ }
996+
997+ for ( COSNode *n : this->call_params )
998+ {
999+ env->lifetimeMan.AddRef( n );
1000+ }
1001+ }
1002+ inline call_selector( call_selector&& right ) noexcept
1003+ : env( right.env ), call_params( std::move( right.call_params ) ), is_call( right.is_call )
1004+ {
1005+ this->root = right.root;
1006+
1007+ right.root = nullptr;
1008+ }
1009+ inline ~call_selector( void )
1010+ {
1011+ auto *env = this->env;
1012+
1013+ if ( COSNode *root = this->root )
1014+ {
1015+ env->lifetimeMan.RemRef( root );
1016+ }
1017+
1018+ for ( COSNode *n : this->call_params )
1019+ {
1020+ env->lifetimeMan.RemRef( n );
1021+ }
1022+ }
1023+
1024+ inline COSNode* DetachFinishedNode( void )
1025+ {
1026+ COSNode *result = this->root;
1027+
1028+ if ( result )
1029+ {
1030+ this->env->lifetimeMan.RemRef( result );
1031+ }
1032+
1033+ this->root = nullptr;
1034+
1035+ return result;
1036+ }
1037+
1038+ inline void AssignAttribute( const eir::FixedString <char>& attrib, const eir::FixedString <char>& value )
1039+ {
1040+ if ( attrib == "begcall" )
1041+ {
1042+ this->is_call = true;
1043+ }
1044+ else if ( attrib == "endcall" )
1045+ {
1046+ this->is_call = false;
1047+
1048+ auto *env = this->env;
1049+
1050+ COSNode *cur_node = this->root;
1051+
1052+ if ( cur_node )
1053+ {
1054+ env->lifetimeMan.RemRef( cur_node );
1055+ }
1056+
1057+ cur_node = new FunctionCallOperation( cur_node, std::move( this->call_params ) );
1058+
1059+ env->lifetimeMan.AddRef( cur_node );
1060+
1061+ this->root = cur_node;
1062+ }
1063+ }
1064+
1065+ inline bool AssignNode( const eir::FixedString <char>& attrib, COSNode *node )
1066+ {
1067+ if ( attrib == "param" )
1068+ {
1069+ this->call_params.AddToBack( node );
1070+ goto success;
1071+ }
1072+ else if ( attrib == "tocall" )
1073+ {
1074+ this->root = node;
1075+ goto success;
1076+ }
1077+
1078+ return false;
1079+
1080+ success:
1081+ this->env->lifetimeMan.AddRef( node );
1082+ return true;
1083+ }
1084+
1085+ COSRuntimeEnv *env;
1086+ COSNode *root = nullptr;
1087+ depVector <COSNode*> call_params;
1088+ bool is_call = false;
1089+ };
1090+ operation.GetLastStep()->setSelector <call_selector> ( &lexer.GetRuntimeEnvironment() );
1091+ }
1092+ assert( lexer.CompileInto( compiler, operation, "base:operation (spaces ['[' spaces key:procgate operation spaces ']', spaces])^0:1" ) != nullptr );
1093+ {
1094+ struct key_dispatcher
1095+ {
1096+ inline void AssignAttribute( const eir::FixedString <char>& attrib, const eir::FixedString <char>& value )
1097+ {
1098+ return;
1099+ }
1100+
1101+ inline COSNode* CreateOperation( COSNode *left, COSNode *right )
1102+ {
1103+ return new EdgeBracketsOperation( left, right );
1104+ }
1105+ };
1106+ operation.GetLastStep()->setSelector <left_associative_selector <char, COSNode, key_dispatcher, COSRuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
1107+ }
1108+ assert( lexer.CompileInto( compiler, operation, "op:operation (spaces '{' spaces [<0> item:procgate operation, spaces ',' spaces] spaces endarrtok:'}')^0:1" ) != nullptr );
1109+ {
1110+ struct arrayinit_selector
1111+ {
1112+ inline void AssignAttribute( const eir::FixedString <char>& attrib, const eir::FixedString <char>& value )
1113+ {
1114+ if ( attrib == "endarrtok" )
1115+ {
1116+ this->root = new ArrayInitOperation( this->root, std::move( this->items ) );
1117+ }
1118+ }
1119+
1120+ inline bool AssignNode( const eir::FixedString <char>& attrib, COSNode *node )
1121+ {
1122+ if ( attrib == "op" )
1123+ {
1124+ this->root = node;
1125+ return true;
1126+ }
1127+ if ( attrib == "item" )
1128+ {
1129+ this->items.AddToBack( node );
1130+ return true;
1131+ }
1132+
1133+ return false;
1134+ }
1135+
1136+ inline COSNode* DetachFinishedNode( void ) noexcept
1137+ {
1138+ COSNode *result = this->root;
1139+
1140+ this->root = nullptr;
1141+
1142+ return result;
1143+ }
1144+
1145+ COSNode *root = nullptr;
1146+ depVector <COSNode*> items;
1147+ };
1148+ operation.GetLastStep()->setSelector <arrayinit_selector> ();
1149+ }
1150+ assert( lexer.CompileInto( compiler, operation, "&(npgate templinst_templ, itemtempl=operation)" ) != nullptr );
1151+
1152+ auto tailop = lexer.MakeStep <COSRuntimeEnv::StepAlternatives> ();
1153+
1154+ assert( lexer.CompileInto( compiler, tailop, "\"new\" spaces type:spec spaces (curlypack)^0:1" ) != nullptr );
1155+ {
1156+ struct new_dispatcher
1157+ {
1158+ static inline bool AssignNodeTo( NewOperation *assign_to, const eir::FixedString <char>& attrib, COSNode *node )
1159+ {
1160+ if ( attrib == "type" )
1161+ {
1162+ assign_to->type = node;
1163+ return true;
1164+ }
1165+ else if ( attrib == "param" )
1166+ {
1167+ assign_to->params.AddToBack( node );
1168+ return true;
1169+ }
1170+
1171+ return false;
1172+ }
1173+ };
1174+ tailop.GetLastStep()->setSelector <direct_obj_build_selector <char, NewOperation, COSNode, new_dispatcher, COSRuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
1175+ }
1176+ assert( lexer.CompileInto( compiler, tailop, "\"cast\" spaces '<' spaces totype:type spaces '>' spaces '(' spaces castobj:procgate operation spaces ')'" ) != nullptr );
1177+ {
1178+ struct cast_dispatcher
1179+ {
1180+ static inline bool AssignNodeTo( CastOperation *assign_to, const eir::FixedString <char>& attrib, COSNode *node )
1181+ {
1182+ if ( attrib == "totype" )
1183+ {
1184+ assign_to->totype = node;
1185+ return true;
1186+ }
1187+ if ( attrib == "castobj" )
1188+ {
1189+ assign_to->castobj = node;
1190+ return true;
1191+ }
1192+
1193+ return false;
1194+ }
1195+ };
1196+ tailop.GetLastStep()->setSelector <direct_obj_build_selector <char, CastOperation, COSNode, cast_dispatcher, COSRuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
1197+ }
1198+ assert( lexer.CompileInto( compiler, tailop, "name" ) != nullptr );
1199+ assert( lexer.CompileInto( compiler, tailop, "number" ) != nullptr );
1200+ assert( lexer.CompileInto( compiler, tailop, "'{' spaces [item:procgate operation, spaces ',' spaces] spaces '}'" ) != nullptr );
1201+ {
1202+ struct array_dispatcher
1203+ {
1204+ static inline bool AssignNodeTo( ArrayDefinition *assign_to, const eir::FixedString <char>& attrib, COSNode *node )
1205+ {
1206+ if ( attrib == "item" )
1207+ {
1208+ assign_to->items.AddToBack( node );
1209+ return true;
1210+ }
1211+ return false;
1212+ }
1213+ };
1214+ tailop.GetLastStep()->setSelector <direct_obj_build_selector <char, ArrayDefinition, COSNode, array_dispatcher, COSRuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
1215+ }
1216+ // Not ideal for again serializing into text, but we should be automatically detecting such a case anyway due to a fixed
1217+ // operational binding strength.
1218+ assert( lexer.CompileInto( compiler, tailop, "'(' spaces procgate operation spaces ')'" ) != nullptr );
1219+
1220+ lexer.AddStepInto( operation, std::move( tailop ) );
1221+
1222+ lexer.AddStep( "operation", std::move( operation ) );
1223+
1224+ // We know that "operation" will never recurse infinitely, so make sure the runtime respects this.
1225+ // This is important because the halting-problem cannot be efficiently solved in distinct space,
1226+ // but we can create grammar rules that will always halt, if proven on paper.
1227+ lexer.GetNamedProduction( "operation" ).disable_empty_recursion_protection = true;
1228+ }
1229+
1230+ lexer.AddProgrammableTokenStep( "name",
1231+ []( COSRuntimeEnv::LexingPoint& pt ) -> std::optional <eir::FixedString <char>>
1232+ {
1233+ const char *startdata = pt.GetCurrentData();
1234+ size_t startoff = pt.GetOffset();
1235+
1236+ bool first_char = true;
1237+
1238+ while ( pt.GetRemainder() > 0 )
1239+ {
1240+ size_t oldoff = pt.GetOffset();
1241+
1242+ auto ucp = pt.ReadCharacter();
1243+
1244+ bool validchar;
1245+
1246+ if ( first_char )
1247+ {
1248+ validchar = is_name_alpha( ucp );
1249+ first_char = false;
1250+ }
1251+ else
1252+ {
1253+ validchar = is_name_char( ucp );
1254+ }
1255+
1256+ if ( validchar == false )
1257+ {
1258+ pt.SetOffset( oldoff );
1259+ break;
1260+ }
1261+ }
1262+
1263+ size_t cplen = ( pt.GetOffset() - startoff );
1264+
1265+ if ( cplen == 0 )
1266+ return std::nullopt;
1267+
1268+ return eir::FixedString( startdata, cplen );
1269+ }
1270+ );
1271+ {
1272+ struct name_dispatcher
1273+ {
1274+ static inline void AssignAttributeTo( SpecifierString *assign_to, const eir::FixedString <char>& attrib, const eir::FixedString <char>& value )
1275+ {
1276+ if ( attrib == "str" )
1277+ {
1278+ assign_to->string = value;
1279+ }
1280+ }
1281+ };
1282+ auto& nameprod = lexer.GetNamedProduction( "name" );
1283+ nameprod.attribute_key = "str";
1284+ nameprod.setSelector <direct_obj_build_selector <char, SpecifierString, COSNode, name_dispatcher, COSRuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
1285+ }
1286+ lexer.AddProgrammableTokenStep( "number",
1287+ []( COSRuntimeEnv::LexingPoint& pt ) -> std::optional <eir::FixedString <char>>
1288+ {
1289+ const char *startdata = pt.GetCurrentData();
1290+ size_t startoff = pt.GetOffset();
1291+
1292+ bool first_char = true;
1293+
1294+ while ( pt.GetRemainder() > 0 )
1295+ {
1296+ size_t oldoff = pt.GetOffset();
1297+
1298+ auto ucp = pt.ReadCharacter();
1299+
1300+ bool validchar = is_num( ucp );
1301+
1302+ if ( validchar == false )
1303+ {
1304+ pt.SetOffset( oldoff );
1305+ break;
1306+ }
1307+ }
1308+
1309+ size_t cplen = ( pt.GetOffset() - startoff );
1310+
1311+ if ( cplen == 0 )
1312+ return std::nullopt;
1313+
1314+ return eir::FixedString( startdata, cplen );
1315+ }
1316+ );
1317+ {
1318+ struct numeric_dispatcher
1319+ {
1320+ static inline void AssignAttributeTo( NumberString *assign_to, const eir::FixedString <char>& attrib, const eir::FixedString <char>& value )
1321+ {
1322+ if ( attrib == "str" )
1323+ {
1324+ assign_to->numeric_string = value;
1325+ }
1326+ }
1327+ };
1328+ auto& numprod = lexer.GetNamedProduction( "number" );
1329+ numprod.attribute_key = "str";
1330+ numprod.setSelector <direct_obj_build_selector <char, NumberString, COSNode, numeric_dispatcher, COSRuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
1331+ }
1332+ lexer.AddProgrammableTokenStep( "spaces",
1333+ []( COSRuntimeEnv::LexingPoint& pt )
1334+ {
1335+ size_t resetoff = pt.GetOffset();
1336+
1337+ while ( pt.GetRemainder() > 0 )
1338+ {
1339+ char ucp = pt.ReadCharacter();
1340+
1341+ if ( is_space_char( ucp ) == false )
1342+ {
1343+ pt.SetOffset( resetoff );
1344+ break;
1345+ }
1346+
1347+ resetoff++;
1348+ }
1349+
1350+ return eir::FixedString <char> ();
1351+ }
1352+ );
1353+
1354+ assert( lexer.CompileProduction( compiler, "whileloop", "\"while\" spaces '(' spaces cond:operation spaces ')' spaces body:loopbody" ) == true );
1355+ {
1356+ struct while_dispatcher
1357+ {
1358+ static inline bool AssignNodeTo( WhileLoopStatement *assign_to, const eir::FixedString <char>& attrib, COSNode *node )
1359+ {
1360+ if ( attrib == "cond" )
1361+ {
1362+ assign_to->condition = node;
1363+ }
1364+ else if ( attrib == "body" )
1365+ {
1366+ assign_to->exec = node;
1367+ }
1368+ return false;
1369+ }
1370+ };
1371+ lexer.GetNamedProduction( "whileloop" ).setSelector <direct_obj_build_selector <char, WhileLoopStatement, COSNode, while_dispatcher, COSRuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
1372+ }
1373+ assert( lexer.CompileProduction( compiler, "loopbody", "^(extended statement, <b> loopstatement)" ) == true );
1374+ assert( lexer.CompileProduction( compiler, "loopstatement", "\"break\" spaces ';'" ) == true );
1375+ {
1376+ lexer.GetNamedProduction( "loopstatement" ).GetLastStep()->setConstructor(
1377+ []
1378+ {
1379+ return new BreakStatement();
1380+ }
1381+ );
1382+ }
1383+ assert( lexer.CompileProduction( compiler, "loopstatement", "\"continue\" spaces ';'" ) == true );
1384+ {
1385+ lexer.GetNamedProduction( "loopstatement" ).GetLastStep()->setConstructor(
1386+ []
1387+ {
1388+ return new ContinueStatement();
1389+ }
1390+ );
1391+ }
1392+ assert( lexer.CompileProduction( compiler, "if", "\"if\" spaces '(' spaces cond:operation spaces ')' spaces true_branch:extended statement (spaces \"else\" spaces false_branch:extended statement)^0:1" ) == true );
1393+ {
1394+ struct if_dispatcher
1395+ {
1396+ static inline bool AssignNodeTo( IfStatement *assign_to, const eir::FixedString <char>& attrib, COSNode *node )
1397+ {
1398+ if ( attrib == "cond" )
1399+ {
1400+ assign_to->condition = node;
1401+ return true;
1402+ }
1403+ else if ( attrib == "true_branch" )
1404+ {
1405+ assign_to->true_branch = node;
1406+ return true;
1407+ }
1408+ else if ( attrib == "false_branch" )
1409+ {
1410+ assign_to->false_branch = node;
1411+ return true;
1412+ }
1413+
1414+ return false;
1415+ }
1416+ };
1417+ lexer.GetNamedProduction( "if" ).setSelector <direct_obj_build_selector <char, IfStatement, COSNode, if_dispatcher, COSRuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
1418+ }
1419+ assert( lexer.CompileProduction( compiler, "except", "\"throw\" spaces (op:operation spaces)^0:1 ';'" ) == true );
1420+ {
1421+ struct throw_dispatcher
1422+ {
1423+ static inline bool AssignNodeTo( ThrowStatement *assign_to, const eir::FixedString <char>& attrib, COSNode *node )
1424+ {
1425+ if ( attrib == "op" )
1426+ {
1427+ assign_to->op = node;
1428+ return true;
1429+ }
1430+ return false;
1431+ }
1432+ };
1433+ lexer.GetNamedProduction( "except" ).GetLastStep()->setSelector <direct_obj_build_selector <char, ThrowStatement, COSNode, throw_dispatcher, COSRuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
1434+ }
1435+ assert( lexer.CompileProduction( compiler, "catch", "\"catch\" spaces '(' spaces (caught_decl:decl_optnoinit spaces)^0:1 ')' spaces catch_body:extended statement" ) == true );
1436+ {
1437+ struct catch_dispatcher
1438+ {
1439+ static inline bool AssignNodeTo( CatchStatement *assign_to, const eir::FixedString <char>& attrib, COSNode *node )
1440+ {
1441+ if ( attrib == "caught_decl" )
1442+ {
1443+ assign_to->caught_decl = node;
1444+ return true;
1445+ }
1446+ else if ( attrib == "catch_body" )
1447+ {
1448+ assign_to->catch_body = node;
1449+ return true;
1450+ }
1451+ return false;
1452+ }
1453+ };
1454+ lexer.GetNamedProduction( "catch" ).setSelector <direct_obj_build_selector <char, CatchStatement, COSNode, catch_dispatcher, COSRuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
1455+ }
1456+ assert( lexer.CompileProduction( compiler, "except", "\"try\" spaces try_body:extended statement spaces [error:catch, spaces]" ) == true );
1457+ {
1458+ struct try_dispatcher
1459+ {
1460+ static inline bool AssignNodeTo( TryStatement *assign_to, const eir::FixedString <char>& attrib, COSNode *node )
1461+ {
1462+ if ( attrib == "try_body" )
1463+ {
1464+ assign_to->try_body = node;
1465+ return true;
1466+ }
1467+ else if ( attrib == "error" )
1468+ {
1469+ assign_to->errors.AddToBack( dynamic_cast <CatchStatement*> ( node ) );
1470+ return true;
1471+ }
1472+ return false;
1473+ }
1474+ };
1475+ lexer.GetNamedProduction( "except" ).GetLastStep()->setSelector <direct_obj_build_selector <char, TryStatement, COSNode, try_dispatcher, COSRuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
1476+ }
1477+ assert( lexer.CompileProduction( compiler, "forloop", "\"for\" spaces '(' spaces loop_init:(declaration | operation) spaces ';' spaces loop_cond:operation spaces ';' spaces loop_iteration:operation spaces ')' spaces body:loopbody" ) == true );
1478+ {
1479+ struct for_dispatcher
1480+ {
1481+ static inline bool AssignNodeTo( ForLoopStatement *assign_to, const eir::FixedString <char>& attrib, COSNode *node )
1482+ {
1483+ if ( attrib == "loop_init" )
1484+ {
1485+ assign_to->init = node;
1486+ return true;
1487+ }
1488+ else if ( attrib == "loop_cond" )
1489+ {
1490+ assign_to->condition = node;
1491+ return true;
1492+ }
1493+ else if ( attrib == "loop_iteration" )
1494+ {
1495+ assign_to->iteration = node;
1496+ return true;
1497+ }
1498+ else if ( attrib == "body" )
1499+ {
1500+ assign_to->exec = node;
1501+ return true;
1502+ }
1503+ return false;
1504+ }
1505+ };
1506+ lexer.GetNamedProduction( "forloop" ).setSelector <direct_obj_build_selector <char, ForLoopStatement, COSNode, for_dispatcher, COSRuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
1507+ }
1508+ assert( lexer.CompileProduction( compiler, "loop", "whileloop | forloop" ) == true );
1509+ assert( lexer.CompileProduction( compiler, "structdef", "\"struct\" spaces name:spec spaces ^!(body:block, <b> statement+typestatement) spaces ';'" ) == true );
1510+ {
1511+ struct struct_dispatcher
1512+ {
1513+ static inline bool AssignNodeTo( StructDefinition *assign_to, const eir::FixedString <char>& attrib, COSNode *node )
1514+ {
1515+ if ( attrib == "name" )
1516+ {
1517+ assign_to->name = node;
1518+ return true;
1519+ }
1520+ else if ( attrib == "body" )
1521+ {
1522+ assign_to->body = node;
1523+ return true;
1524+ }
1525+ return false;
1526+ }
1527+ };
1528+ lexer.GetNamedProduction( "structdef" ).setSelector <direct_obj_build_selector <char, StructDefinition, COSNode, struct_dispatcher, COSRuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
1529+ }
1530+ assert( lexer.CompileProduction( compiler, "typedef", "dtypedef | structdef" ) == true );
1531+ assert( lexer.CompileProduction( compiler, "typestatement", "constructor | destructor" ) == true );
1532+ assert( lexer.CompileProduction( compiler, "constructor", "\"constructor\" spaces '(' spaces paramlist_opt spaces ')' spaces body:funcbody" ) == true );
1533+ {
1534+ struct constructor_dispatcher
1535+ {
1536+ static inline bool AssignNodeTo( ConstructorDefinition *assign_to, const eir::FixedString <char>& attrib, COSNode *node )
1537+ {
1538+ if ( attrib == "param" )
1539+ {
1540+ assign_to->params.AddToBack( node );
1541+ return true;
1542+ }
1543+ else if ( attrib == "body" )
1544+ {
1545+ assign_to->body = node;
1546+ return true;
1547+ }
1548+ return false;
1549+ }
1550+ };
1551+ lexer.GetNamedProduction( "constructor" ).setSelector <direct_obj_build_selector <char, ConstructorDefinition, COSNode, constructor_dispatcher, COSRuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
1552+ }
1553+ assert( lexer.CompileProduction( compiler, "destructor", "\"destructor\" spaces body:funcbody" ) == true );
1554+ {
1555+ struct destructor_dispatcher
1556+ {
1557+ static inline bool AssignNodeTo( DestructorDefinition *assign_to, const eir::FixedString <char>& attrib, COSNode *node )
1558+ {
1559+ if ( attrib == "body" )
1560+ {
1561+ assign_to->body = node;
1562+ return true;
1563+ }
1564+ return false;
1565+ }
1566+ };
1567+ lexer.GetNamedProduction( "destructor" ).setSelector <direct_obj_build_selector <char, DestructorDefinition, COSNode, destructor_dispatcher, COSRuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
1568+ }
1569+ assert( lexer.CompileProduction( compiler, "deleteop", "\"delete\" spaces op:operation spaces ';'" ) == true );
1570+ {
1571+ struct delete_dispatcher
1572+ {
1573+ static inline bool AssignNodeTo( DeleteOperation *assign_to, const eir::FixedString <char>& attrib, COSNode *node )
1574+ {
1575+ if ( attrib == "op" )
1576+ {
1577+ assign_to->op = node;
1578+ return true;
1579+ }
1580+ return false;
1581+ }
1582+ };
1583+ lexer.GetNamedProduction( "deleteop" ).setSelector <direct_obj_build_selector <char, DeleteOperation, COSNode, delete_dispatcher, COSRuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
1584+ }
1585+ assert( lexer.CompileProduction( compiler, "replaceop", "\"replace\" spaces what:operation spaces \"with\" spaces with:operation spaces ';'" ) == true );
1586+ {
1587+ struct replace_dispatcher
1588+ {
1589+ static inline bool AssignNodeTo( ReplaceOperation *assign_to, const eir::FixedString <char>& attrib, COSNode *node )
1590+ {
1591+ if ( attrib == "what" )
1592+ {
1593+ assign_to->what = node;
1594+ return true;
1595+ }
1596+ else if ( attrib == "with" )
1597+ {
1598+ assign_to->with = node;
1599+ return true;
1600+ }
1601+ return false;
1602+ }
1603+ };
1604+ lexer.GetNamedProduction( "replaceop" ).setSelector <direct_obj_build_selector <char, ReplaceOperation, COSNode, replace_dispatcher, COSRuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
1605+ }
1606+ assert( lexer.CompileProduction( compiler, "objmod", "deleteop | replaceop" ) == true );
1607+ assert( lexer.CompileProduction( compiler, "templinst_templ", "[\"template\" spaces dotitem:replaceable itemtempl spaces '<' spaces [<0> templarg:procgate type, spaces ',' spaces] spaces endtempl:'>' | dotitem:replaceable itemtempl, spaces optok:(\"->\"|'.') spaces]" ) == true );
1608+ {
1609+ struct dot_with_templ_selector
1610+ {
1611+ enum class eOpType
1612+ {
1613+ DOT,
1614+ ARROW
1615+ };
1616+
1617+ inline void AddNodeAsRootDot( COSNode *node )
1618+ {
1619+ COSNode *prev_root = this->root;
1620+
1621+ if ( prev_root == nullptr )
1622+ {
1623+ this->root = node;
1624+ return;
1625+ }
1626+
1627+ eOpType op_type = this->op_type;
1628+
1629+ if ( op_type == eOpType::ARROW )
1630+ {
1631+ this->root = new ArrowOperation( prev_root, node );
1632+ }
1633+ else if ( op_type == eOpType::DOT )
1634+ {
1635+ this->root = new DotOperation( prev_root, node );
1636+ }
1637+ }
1638+
1639+ inline void AssignAttribute( const eir::FixedString <char>& attrib, const eir::FixedString <char>& value )
1640+ {
1641+ if ( attrib == "endtempl" )
1642+ {
1643+ this->root = new TemplateInstantiationOperation( this->root, std::move( this->templargs ) );
1644+ }
1645+ else if ( attrib == "optok" )
1646+ {
1647+ if ( value == "." )
1648+ {
1649+ this->op_type = eOpType::DOT;
1650+ }
1651+ else if ( value == "->" )
1652+ {
1653+ this->op_type = eOpType::ARROW;
1654+ }
1655+ }
1656+ }
1657+
1658+ inline bool AssignNode( const eir::FixedString <char>& attrib, COSNode *node )
1659+ {
1660+ if ( attrib == "dotitem" )
1661+ {
1662+ this->AddNodeAsRootDot( node );
1663+ return true;
1664+ }
1665+ else if ( attrib == "templarg" )
1666+ {
1667+ this->templargs.AddToBack( node );
1668+ return true;
1669+ }
1670+
1671+ return false;
1672+ }
1673+
1674+ inline COSNode* DetachFinishedNode( void ) noexcept
1675+ {
1676+ COSNode *result = this->root;
1677+
1678+ this->root = nullptr;
1679+
1680+ return result;
1681+ }
1682+
1683+ COSNode *root = nullptr;
1684+ depVector <COSNode*> templargs;
1685+ eOpType op_type = eOpType::DOT;
1686+ };
1687+ lexer.GetNamedProduction( "templinst_templ" ).setSelector <dot_with_templ_selector> ();
1688+ }
1689+ assert( lexer.CompileProduction( compiler, "npath", "&(templinst_templ, itemtempl=name)" ) == true );
1690+ assert( lexer.CompileProduction( compiler, "curlypack", "'(' spaces [<0> param:operation, spaces ',' spaces] spaces ')'" ) == true );
1691+ {
1692+ struct curlypack_dispatcher
1693+ {
1694+ static inline bool AssignNodeTo( CurlyPack *assign_to, const eir::FixedString <char>& attrib, COSNode *node )
1695+ {
1696+ if ( attrib == "param" )
1697+ {
1698+ assign_to->params.AddToBack( node );
1699+ return true;
1700+ }
1701+ return false;
1702+ }
1703+ };
1704+ lexer.GetNamedProduction( "curlypack" ).setSelector <direct_obj_build_selector <char, CurlyPack, COSNode, curlypack_dispatcher, COSRuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
1705+ }
1706+
1707+ struct declaratory_locator_builder
1708+ {
1709+ enum class eLocatorType
1710+ {
1711+ POINTER,
1712+ REFERENCE
1713+ };
1714+
1715+ struct array_spec
1716+ {
1717+ inline array_spec( COSNode *size_op = nullptr ) noexcept : size_op( size_op )
1718+ {}
1719+ inline array_spec( const array_spec& ) = default;
1720+ inline array_spec( array_spec&& right ) noexcept
1721+ {
1722+ this->size_op = right.size_op;
1723+
1724+ right.size_op = nullptr;
1725+ }
1726+
1727+ COSNode *size_op;
1728+ };
1729+
1730+ inline void AssignAttribute( const eir::FixedString <char>& attrib, const eir::FixedString <char>& value )
1731+ {
1732+ if ( attrib == "loc" )
1733+ {
1734+ if ( value == "*" )
1735+ {
1736+ locators.AddToBack( eLocatorType::POINTER );
1737+ }
1738+ else if ( value == "&" )
1739+ {
1740+ locators.AddToBack( eLocatorType::REFERENCE );
1741+ }
1742+ }
1743+ else if ( attrib == "arrspec.endtok" )
1744+ {
1745+ locators.AddToBack( std::move( _build_arrspec ) );
1746+ }
1747+ }
1748+
1749+ inline bool AssignNode( const eir::FixedString <char>& attrib, COSNode *node )
1750+ {
1751+ if ( attrib == "arrspec.idx" )
1752+ {
1753+ _build_arrspec.size_op = node;
1754+ return true;
1755+ }
1756+ return false;
1757+ }
1758+
1759+ inline COSNode* EncapsulateByTypeLocators( COSNode *node )
1760+ {
1761+ COSNode *return_node = node;
1762+
1763+ for ( loc_variant_t& item : this->locators )
1764+ {
1765+ if ( std::holds_alternative <eLocatorType> ( item ) )
1766+ {
1767+ eLocatorType basic_loctype = std::get <eLocatorType> ( item );
1768+
1769+ if ( basic_loctype == eLocatorType::POINTER )
1770+ {
1771+ return_node = new PointerTypeSpecifier( return_node );
1772+ }
1773+ else if ( basic_loctype == eLocatorType::REFERENCE )
1774+ {
1775+ return_node = new RefTypeSpecifier( return_node );
1776+ }
1777+ }
1778+ else if ( std::holds_alternative <array_spec> ( item ) )
1779+ {
1780+ array_spec& arrspec = std::get <array_spec> ( item );
1781+
1782+ return_node = new ArrayTypeSpecifier( return_node, arrspec.size_op );
1783+ }
1784+ }
1785+
1786+ return return_node;
1787+ }
1788+
1789+ inline void Reset( void )
1790+ {
1791+ this->locators.Clear();
1792+ this->_build_arrspec.size_op = nullptr;
1793+ }
1794+
1795+ typedef std::variant <eLocatorType, array_spec> loc_variant_t;
1796+
1797+ depVector <loc_variant_t> locators;
1798+
1799+ // Temporary build variables.
1800+ array_spec _build_arrspec;
1801+ };
1802+
1803+ // Type system COS structures.
1804+ assert( lexer.CompileProduction( compiler, "locator", "[<0>loc:'*',spaces] (spaces loc:'&')^0:1" ) == true ); // helper
1805+ assert( lexer.CompileProduction( compiler, "tmultdecl", "&(mdecltempl, nameplacehold=spec, initplacehold=empty)" ) == true );
1806+ {
1807+ struct tmultdecl_selector
1808+ {
1809+ inline TypedefStatement* DetachTypedef( void )
1810+ {
1811+ COSNode *underlying_type = this->locbuild.EncapsulateByTypeLocators( this->utype );
1812+
1813+ COSNode *srctype;
1814+
1815+ if ( COSNode *func = this->func )
1816+ {
1817+ FuncsigDefinition *actual_func = dynamic_cast <FuncsigDefinition*> ( TypeSpecifier::ResolveUntilMostSpecialized( func ) );
1818+
1819+ FuncsigDefinition *left_most_func = actual_func->GetDeepestReturnValueFunctionSignatureType();
1820+
1821+ left_most_func->return_type = underlying_type;
1822+
1823+ srctype = func;
1824+ }
1825+ else
1826+ {
1827+ srctype = underlying_type;
1828+ }
1829+
1830+ this->tdef.srctype = srctype;
1831+
1832+ return new TypedefStatement( std::move( this->tdef ) );
1833+ }
1834+
1835+ inline void PushDefinition( void )
1836+ {
1837+ this->multidef.defs.AddToBack( this->DetachTypedef() );
1838+
1839+ // Reset the typedef builder fields, but not utype.
1840+ this->locbuild.Reset();
1841+ this->func = nullptr;
1842+ }
1843+
1844+ inline void AssignAttribute( const eir::FixedString <char>& attrib, const eir::FixedString <char>& value )
1845+ {
1846+ if ( attrib == "nextdecl" )
1847+ {
1848+ this->PushDefinition();
1849+ }
1850+ else
1851+ {
1852+ locbuild.AssignAttribute( attrib, value );
1853+ }
1854+ }
1855+
1856+ inline bool AssignNode( const eir::FixedString <char>& attrib, COSNode *node )
1857+ {
1858+ if ( attrib == "utype" )
1859+ {
1860+ this->utype = node;
1861+ return true;
1862+ }
1863+ else if ( attrib == "func" )
1864+ {
1865+ this->func = node;
1866+ return true;
1867+ }
1868+ else if ( LexingEnvUtils::GetLastAttributionItemInPathFixed( attrib ) == "name" )
1869+ {
1870+ this->tdef.dsttype = node;
1871+ return true;
1872+ }
1873+ else if ( locbuild.AssignNode( attrib, node ) )
1874+ {
1875+ return true;
1876+ }
1877+
1878+ return false;
1879+ }
1880+
1881+ inline COSNode* DetachFinishedNode( void )
1882+ {
1883+ if ( this->multidef.defs.GetCount() == 0 )
1884+ {
1885+ // Just return the single typedef.
1886+ return this->DetachTypedef();
1887+ }
1888+ else
1889+ {
1890+ this->PushDefinition();
1891+
1892+ return new MultiTypedefStatement( std::move( this->multidef ) );
1893+ }
1894+ }
1895+
1896+ COSNode *utype = nullptr;
1897+ COSNode *func = nullptr;
1898+ declaratory_locator_builder locbuild;
1899+ TypedefStatement tdef;
1900+ MultiTypedefStatement multidef;
1901+ };
1902+ lexer.GetNamedProduction( "tmultdecl" ).setSelector <tmultdecl_selector> ();
1903+ }
1904+ assert( lexer.CompileProduction( compiler, "funcsigtempl", "functag spaces ( '(' spaces locator spaces (subfunc:funcsigtempl|locnametempl) spaces ')' | name:replaceable nameplacehold ) spaces '(' spaces paramlist_opt spaces ')'" ) == true );
1905+ {
1906+ struct funcsig_selector
1907+ {
1908+ inline void AssignAttribute( const eir::FixedString <char>& attrib, const eir::FixedString <char>& value )
1909+ {
1910+ locbuild.AssignAttribute( attrib, value );
1911+ }
1912+
1913+ inline bool AssignNode( const eir::FixedString <char>& attrib, COSNode *node )
1914+ {
1915+ if ( attrib == "param" )
1916+ {
1917+ this->funcsig.params.AddToBack( node );
1918+ return true;
1919+ }
1920+ else if ( attrib == "subfunc" )
1921+ {
1922+ this->subfunc = node;
1923+ return true;
1924+ }
1925+ else if ( LexingEnvUtils::GetLastAttributionItemInPathFixed( attrib ) == "name" )
1926+ {
1927+ throw lexing_value_transgression_exception();
1928+ }
1929+ else if ( locbuild.AssignNode( attrib, node ) )
1930+ {
1931+ return true;
1932+ }
1933+ return false;
1934+ }
1935+
1936+ inline COSNode* DetachFinishedNode( void )
1937+ {
1938+ COSNode *return_node;
1939+
1940+ COSNode *detached_func = this->locbuild.EncapsulateByTypeLocators( new FuncsigDefinition( std::move( this->funcsig ) ) );
1941+
1942+ if ( COSNode *subfunc = this->subfunc )
1943+ {
1944+ FuncsigDefinition *actual_subfunc = dynamic_cast <FuncsigDefinition*> ( TypeSpecifier::ResolveUntilMostSpecialized( subfunc ) );
1945+
1946+ FuncsigDefinition *left_most_sig = actual_subfunc->GetDeepestReturnValueFunctionSignatureType();
1947+
1948+ left_most_sig->return_type = detached_func;
1949+
1950+ return_node = subfunc;
1951+ }
1952+ else
1953+ {
1954+ return_node = detached_func;
1955+ }
1956+
1957+ return return_node;
1958+ }
1959+
1960+ declaratory_locator_builder locbuild;
1961+ FuncsigDefinition funcsig;
1962+ COSNode *subfunc = nullptr;
1963+ };
1964+ lexer.GetNamedProduction( "funcsigtempl" ).setSelector <funcsig_selector> ();
1965+ }
1966+ assert( lexer.CompileProduction( compiler, "funcsigdecl", "&(funcsigtempl, nameplacehold=spec)" ) == true );
1967+ assert( lexer.CompileProduction( compiler, "locnametempl", "name:replaceable nameplacehold (spaces [arrspec:arrayspec, spaces])^0:1" ) == true ); // helper
1968+ assert( lexer.CompileProduction( compiler, "arrayspec", "'[' spaces (idx:operation spaces)^0:1 endtok:']'" ) == true ); // helper
1969+ // Set-up both of the following productions in one block.
1970+ assert( lexer.CompileProduction( compiler, "decltemplate", "utype:spec spaces locator spaces (func:funcsigtempl|locnametempl) replaceable initplacehold" ) == true ); // helper
1971+ assert( lexer.CompileProduction( compiler, "mdecltempl", "utype:spec spaces [locator spaces (func:funcsigtempl|locnametempl) replaceable initplacehold, spaces nextdecl:',' spaces]" ) == true );
1972+ assert( lexer.CompileProduction( compiler, "declaration", "&(decltemplate, nameplacehold=spec, initplacehold=declinit)" ) == true );
1973+ assert( lexer.CompileProduction( compiler, "decl_optnoinit", "&(decltemplate, nameplacehold=(spec)^0:1, initplacehold=empty)" ) == true );
1974+ assert( lexer.CompileProduction( compiler, "decl_opt", "&(decltemplate, nameplacehold=(spec)^0:1, initplacehold=declinit)" ) == true );
1975+ assert( lexer.CompileProduction( compiler, "multdecl", "&(mdecltempl, nameplacehold=spec, initplacehold=declinit) mdeclterm" ) == true );
1976+ {
1977+ struct declaration_selector
1978+ {
1979+ inline void AssignAttribute( const eir::FixedString <char>& attrib, const eir::FixedString <char>& value )
1980+ {
1981+ locbuild.AssignAttribute( attrib, value );
1982+ }
1983+
1984+ inline bool AssignNode( const eir::FixedString <char>& attrib, COSNode *node )
1985+ {
1986+ if ( attrib == "utype" )
1987+ {
1988+ this->utype = node;
1989+ return true;
1990+ }
1991+ else if ( attrib == "func" )
1992+ {
1993+ this->func = node;
1994+ return true;
1995+ }
1996+ else if ( attrib == "init" )
1997+ {
1998+ this->decl.initializer = node;
1999+ return true;
2000+ }
2001+ else if ( attrib == "init_s" )
2002+ {
2003+ this->decl.initializer = node;
2004+ this->special_init = true;
2005+ return true;
2006+ }
2007+ else if ( LexingEnvUtils::GetLastAttributionItemInPathFixed( attrib ) == "name" )
2008+ {
2009+ this->decl.name = node;
2010+ return true;
2011+ }
2012+ else if ( locbuild.AssignNode( attrib, node ) )
2013+ {
2014+ return true;
2015+ }
2016+ return false;
2017+ }
2018+
2019+ inline COSNode* GetBuiltType( void )
2020+ {
2021+ if ( COSNode *built_type = this->built_type )
2022+ return built_type;
2023+
2024+ // Build the underlying type completely.
2025+ COSNode *underlying_type = locbuild.EncapsulateByTypeLocators( this->utype );
2026+
2027+ COSNode *built_type;
2028+
2029+ if ( COSNode *func = this->func )
2030+ {
2031+ FuncsigDefinition *actual_func = dynamic_cast <FuncsigDefinition*> ( TypeSpecifier::ResolveUntilMostSpecialized( func ) );
2032+
2033+ FuncsigDefinition *left_most_sig = actual_func->GetDeepestReturnValueFunctionSignatureType();
2034+
2035+ left_most_sig->return_type = underlying_type;
2036+
2037+ built_type = func;
2038+ }
2039+ else
2040+ {
2041+ built_type = underlying_type;
2042+ }
2043+
2044+ this->built_type = built_type;
2045+
2046+ return built_type;
2047+ }
2048+
2049+ inline DeclarationStatement* DetachFinishedNode( void )
2050+ {
2051+ this->decl.type = this->GetBuiltType();
2052+
2053+ return new DeclarationStatement( std::move( this->decl ) );
2054+ }
2055+
2056+ inline void ResetForMulti( void )
2057+ {
2058+ // Do not reset utype field.
2059+
2060+ this->func = nullptr;
2061+ this->locbuild.Reset();
2062+ this->decl.type = nullptr;
2063+ this->decl.name = nullptr;
2064+ this->decl.initializer = nullptr;
2065+ this->built_type = nullptr;
2066+ }
2067+
2068+ COSNode *utype = nullptr;
2069+ COSNode *func = nullptr;
2070+ declaratory_locator_builder locbuild;
2071+ DeclarationStatement decl;
2072+ bool special_init = false;
2073+ COSNode *built_type = nullptr;
2074+ };
2075+ lexer.GetNamedProduction( "declaration" ).setSelector <declaration_selector> ();
2076+ lexer.GetNamedProduction( "decl_optnoinit" ).setSelector <declaration_selector> ();
2077+ lexer.GetNamedProduction( "decl_opt" ).setSelector <declaration_selector> ();
2078+
2079+ struct multdecl_selector
2080+ {
2081+ inline void PushDeclaration( void )
2082+ {
2083+ this->multdecl.decls.AddToBack( this->declsel.DetachFinishedNode() );
2084+
2085+ // Clear type information other than the utype field.
2086+ this->declsel.ResetForMulti();
2087+ }
2088+
2089+ inline void AssignAttribute( const eir::FixedString <char>& attrib, const eir::FixedString <char>& value )
2090+ {
2091+ if ( attrib == "nextdecl" )
2092+ {
2093+ this->PushDeclaration();
2094+ }
2095+ else
2096+ {
2097+ declsel.AssignAttribute( attrib, value );
2098+ }
2099+ }
2100+
2101+ inline bool AssignNode( const eir::FixedString <char>& attrib, COSNode *node )
2102+ {
2103+ return declsel.AssignNode( attrib, node );
2104+ }
2105+
2106+ inline COSNode* DetachFinishedNode( void )
2107+ {
2108+ if ( this->multdecl.decls.GetCount() == 0 )
2109+ {
2110+ // Just return a single declaration.
2111+ return this->declsel.DetachFinishedNode();
2112+ }
2113+ else
2114+ {
2115+ this->PushDeclaration();
2116+
2117+ return new MultiDeclarationStatement( std::move( this->multdecl ) );
2118+ }
2119+ }
2120+
2121+ MultiDeclarationStatement multdecl;
2122+ declaration_selector declsel;
2123+ };
2124+ lexer.GetNamedProduction( "multdecl" ).setSelector <multdecl_selector> ();
2125+
2126+ auto special_declinit = lexer.MakeStep <COSRuntimeEnv::StepCustomIndirection> ();
2127+
2128+ // INDEX 0: array enclosure.
2129+ auto *step_arrenclose = lexer.CompileInto( compiler, special_declinit, "'{' spaces ([item:initexpr, spaces ',' spaces] spaces)^0:1 '}'" );
2130+ {
2131+ struct arrenclose_dispatcher
2132+ {
2133+ static inline bool AssignNodeTo( ArrayDefinition *assign_to, const eir::FixedString <char>& attrib, COSNode *node )
2134+ {
2135+ if ( attrib == "item" )
2136+ {
2137+ assign_to->items.AddToBack( node );
2138+ return true;
2139+ }
2140+
2141+ return false;
2142+ }
2143+ };
2144+ step_arrenclose->setSelector <direct_obj_build_selector <char, ArrayDefinition, COSNode, arrenclose_dispatcher, COSRuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
2145+ }
2146+
2147+ // INDEX 1: outer value.
2148+ auto *step_outerval = lexer.CompileInto( compiler, special_declinit, "'{' spaces operation spaces '}'" );
2149+
2150+ // We also need the following productions which are already defined:
2151+ // * operation
2152+ // * funcbody
2153+
2154+ // Cache important steps.
2155+ auto *step_declaration = &lexer.GetNamedProduction( "declaration" );
2156+ auto *step_decl_opt = &lexer.GetNamedProduction( "decl_opt" );
2157+ auto *step_multdecl = &lexer.GetNamedProduction( "multdecl" );
2158+ auto *step_declinit = &lexer.GetNamedProduction( "initexpr" );
2159+ auto *step_funcbody = &lexer.GetNamedProduction( "funcbody" );
2160+ auto *step_operation = &lexer.GetNamedProduction( "operation" );
2161+
2162+ special_declinit.callback =
2163+ [step_arrenclose, step_outerval, step_declaration, step_decl_opt, step_multdecl, step_declinit, step_funcbody, step_operation]
2164+ ( COSRuntimeEnv::ProductionMachine& machine ) mutable -> COSRuntimeEnv::Step*
2165+ {
2166+
2167+ size_t cstack_cnt = machine.GetCurrentCalcStackSize();
2168+
2169+ size_t cstack_idx = ( cstack_cnt - 2 ); // skip us.
2170+
2171+ declaration_selector *decl_sel = nullptr;
2172+ multdecl_selector *multdecl_sel = nullptr;
2173+
2174+ size_t init_depth = 0;
2175+
2176+ while ( cstack_idx > 0 )
2177+ {
2178+ cstack_idx--;
2179+
2180+ auto *step = machine.GetCurrentExecutionStepByIndex( cstack_idx );
2181+
2182+ if ( step == step_declaration || step == step_decl_opt )
2183+ {
2184+ decl_sel = (declaration_selector*)machine.GetCurrentExecutionSelectorDataByIndex( cstack_idx );
2185+ break;
2186+ }
2187+ else if ( step == step_multdecl )
2188+ {
2189+ multdecl_sel = (multdecl_selector*)machine.GetCurrentExecutionSelectorDataByIndex( cstack_idx );
2190+ break;
2191+ }
2192+ else if ( step == step_declinit )
2193+ {
2194+ init_depth++;
2195+ }
2196+ }
2197+
2198+ COSNode *type = nullptr;
2199+
2200+ if ( decl_sel )
2201+ {
2202+ type = decl_sel->GetBuiltType();
2203+ }
2204+ else if ( multdecl_sel )
2205+ {
2206+ type = multdecl_sel->declsel.GetBuiltType();
2207+ }
2208+
2209+ if ( type )
2210+ {
2211+ // Go as deep as required by init_depth to find the init-type.
2212+ COSNode *init_type = type;
2213+ {
2214+ size_t init_iter = init_depth;
2215+
2216+ while ( init_iter > 0 )
2217+ {
2218+ init_iter--;
2219+
2220+ if ( TypeSpecifier *ptrspec = dynamic_cast <TypeSpecifier*> ( init_type ) )
2221+ {
2222+ init_type = ptrspec->spec;
2223+ }
2224+ else
2225+ {
2226+ // Unknown.
2227+ return nullptr;
2228+ }
2229+ }
2230+ }
2231+
2232+ if ( dynamic_cast <ArrayTypeSpecifier*> ( init_type ) )
2233+ {
2234+ // We want to build an array.
2235+ return step_arrenclose;
2236+ }
2237+ else if ( dynamic_cast <FuncsigDefinition*> ( init_type ) )
2238+ {
2239+ // Expect function body.
2240+ return step_funcbody;
2241+ }
2242+ else if ( init_depth > 0 )
2243+ {
2244+ // Expect operation.
2245+ return step_operation;
2246+ }
2247+ else
2248+ {
2249+ // Expect an outer-value.
2250+ return step_outerval;
2251+ }
2252+ }
2253+
2254+ return nullptr;
2255+ };
2256+
2257+ lexer.AddStep( "initexpr", std::move( special_declinit ) );
2258+
2259+ // Implement the terminator after the multi-declaration.
2260+ auto mdeclterm = lexer.MakeStep <COSRuntimeEnv::StepCustomIndirection> ();
2261+
2262+ auto *step_spaceterm = lexer.CompileInto( compiler, mdeclterm, "spaces ';'" );
2263+
2264+ mdeclterm.callback = [step_spaceterm, step_multdecl]( COSRuntimeEnv::ProductionMachine& machine ) mutable -> COSRuntimeEnv::Step*
2265+ {
2266+ size_t cstack_size = machine.GetCurrentCalcStackSize() - 2;
2267+
2268+ multdecl_selector *mdecl_sel = nullptr;
2269+
2270+ while ( cstack_size > 0 )
2271+ {
2272+ cstack_size--;
2273+
2274+ auto *cstep = machine.GetCurrentExecutionStepByIndex( cstack_size );
2275+
2276+ if ( cstep == step_multdecl )
2277+ {
2278+ mdecl_sel = (multdecl_selector*)machine.GetCurrentExecutionSelectorDataByIndex( cstack_size );
2279+ break;
2280+ }
2281+ }
2282+
2283+ if ( mdecl_sel )
2284+ {
2285+ if ( dynamic_cast <FuncsigDefinition*> ( mdecl_sel->declsel.GetBuiltType() ) != nullptr &&
2286+ mdecl_sel->declsel.special_init == true )
2287+ {
2288+ // Empty and successful.
2289+ return nullptr;
2290+ }
2291+ }
2292+
2293+ // Just the regular terminator with the semi-colon.
2294+ return step_spaceterm;
2295+ };
2296+
2297+ lexer.AddStep( "mdeclterm", std::move( mdeclterm ) );
2298+ }
2299+ assert( lexer.CompileProduction( compiler, "declinit", "( spaces init_s:initexpr | spaces '=' spaces init:operation | spaces init:curlypack )^0:1" ) == true );
2300+ assert( lexer.CompileProduction( compiler, "functag", "\"func\" | \"proc\"" ) == true );
2301+ assert( lexer.CompileProduction( compiler, "type", "&(decltemplate, nameplacehold=empty, initplacehold=empty)" ) == true );
2302+ {
2303+ struct type_selector
2304+ {
2305+ inline void AssignAttribute( const eir::FixedString <char>& attrib, const eir::FixedString <char>& value )
2306+ {
2307+ locbuild.AssignAttribute( attrib, value );
2308+ }
2309+
2310+ inline bool AssignNode( const eir::FixedString <char>& attrib, COSNode *node )
2311+ {
2312+ if ( attrib == "utype" )
2313+ {
2314+ this->utype = node;
2315+ return true;
2316+ }
2317+ else if ( attrib == "func" )
2318+ {
2319+ this->func = node;
2320+ return true;
2321+ }
2322+ return locbuild.AssignNode( attrib, node );
2323+ }
2324+
2325+ inline COSNode* DetachFinishedNode( void )
2326+ {
2327+ COSNode *underlying_type = this->locbuild.EncapsulateByTypeLocators( this->utype );
2328+
2329+ if ( COSNode *func = this->func )
2330+ {
2331+ FuncsigDefinition *actual_func = dynamic_cast <FuncsigDefinition*> ( TypeSpecifier::ResolveUntilMostSpecialized( func ) );
2332+
2333+ FuncsigDefinition *left_most_func = actual_func->GetDeepestReturnValueFunctionSignatureType();
2334+
2335+ left_most_func->return_type = underlying_type;
2336+
2337+ return func;
2338+ }
2339+ else
2340+ {
2341+ return underlying_type;
2342+ }
2343+ }
2344+
2345+ COSNode *utype = nullptr;
2346+ declaratory_locator_builder locbuild;
2347+ COSNode *func = nullptr;
2348+ };
2349+ lexer.GetNamedProduction( "type" ).setSelector <type_selector> ();
2350+ }
2351+ assert( lexer.CompileProduction( compiler, "paramlist_opt", "[<0>param:decl_opt, spaces ',' spaces]" ) == true );
2352+ assert( lexer.CompileProduction( compiler, "namespace", "\"namespace\" spaces name:spec spaces toinclude:nblock" ) == true );
2353+ {
2354+ struct ns_stmt_dispatcher
2355+ {
2356+ static inline bool AssignNodeTo( NamespaceStatement *assign_to, const eir::FixedString <char>& attrib, COSNode *node )
2357+ {
2358+ if ( attrib == "name" )
2359+ {
2360+ assign_to->name = node;
2361+ return true;
2362+ }
2363+ if ( attrib == "toinclude" )
2364+ {
2365+ assign_to->toinclude = node;
2366+ return true;
2367+ }
2368+
2369+ return false;
2370+ }
2371+ };
2372+ lexer.GetNamedProduction( "namespace" ).GetLastStep()->setSelector <direct_obj_build_selector <char, NamespaceStatement, COSNode, ns_stmt_dispatcher, COSRuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
2373+ }
2374+ assert( lexer.CompileProduction( compiler, "namespace", "\"using\" spaces \"namespace\" spaces nsname:spec spaces ';'" ) == true );
2375+ {
2376+ struct ns_using_dispatcher
2377+ {
2378+ static inline bool AssignNodeTo( UsingNamespaceStatement *assign_to, const eir::FixedString <char>& attrib, COSNode *node )
2379+ {
2380+ if ( attrib == "nsname" )
2381+ {
2382+ assign_to->nsname = node;
2383+ return true;
2384+ }
2385+
2386+ return false;
2387+ }
2388+ };
2389+ lexer.GetNamedProduction( "namespace" ).GetLastStep()->setSelector <direct_obj_build_selector <char, UsingNamespaceStatement, COSNode, ns_using_dispatcher, COSRuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
2390+ }
2391+ assert( lexer.CompileProduction( compiler, "enum", "\"enum\" spaces name:spec spaces '{' spaces [item:name (spaces '=' spaces inum:number)^0:1, spaces ',' spaces] spaces '}' spaces ';'" ) == true );
2392+ {
2393+ struct enum_selector
2394+ {
2395+ inline void PushItem( COSNode *val_node )
2396+ {
2397+ EnumDefinition::item entry;
2398+ entry.key = this->curKeyNode;
2399+ entry.value = val_node;
2400+
2401+ this->enumobj.items.AddToBack( std::move( entry ) );
2402+
2403+ this->curKeyNode = nullptr;
2404+ }
2405+
2406+ inline bool AssignNode( const eir::FixedString <char>& attrib, COSNode *node )
2407+ {
2408+ if ( attrib == "name" )
2409+ {
2410+ this->enumobj.name = node;
2411+ return true;
2412+ }
2413+ if ( attrib == "item" )
2414+ {
2415+ if ( this->curKeyNode != nullptr )
2416+ {
2417+ this->PushItem( nullptr );
2418+ }
2419+
2420+ this->curKeyNode = node;
2421+ return true;
2422+ }
2423+ if ( attrib == "inum" )
2424+ {
2425+ this->PushItem( node );
2426+ return true;
2427+ }
2428+
2429+ return false;
2430+ }
2431+
2432+ inline COSNode* DetachFinishedNode( void )
2433+ {
2434+ if ( this->curKeyNode != nullptr )
2435+ {
2436+ this->PushItem( nullptr );
2437+ }
2438+
2439+ return new EnumDefinition( std::move( this->enumobj ) );
2440+ }
2441+
2442+ EnumDefinition enumobj;
2443+ COSNode *curKeyNode = nullptr;
2444+ };
2445+ lexer.GetNamedProduction( "enum" ).GetLastStep()->setSelector <enum_selector> ();
2446+ }
2447+ }
2448+
2449+ inline bool TestCompilation( const char *programCode )
2450+ {
2451+ return lexer.TestProduction( programCode );
2452+ }
2453+
2454+ inline COSNode* Compile( const char *programCode )
2455+ {
2456+ return lexer.StartProduction( programCode );
2457+ }
2458+};
2459+
2460+IMPL_HEAP_REDIR_DYN_ALLOC_TEMPLATEBASE( COSEnvironment, COS_TEMPLARGS, COS_TEMPLUSE, lexer_redirAlloc, COSEnvironment, lexer, allocMan, allocatorType );
2461+
2462+} // namespace COS
\ No newline at end of file
--- eircompile/include/eircompile/lexing_compile.h (revision 72)
+++ eircompile/include/eircompile/lexing_compile.h (revision 73)
@@ -15,7 +15,15 @@
1515 #include <assert.h>
1616 #endif //_DEBUG
1717
18+#define LEXCOMP_TEMPLARGS \
1819 template <eir::CharacterType charType, typename compileForEnvType, eir::MemoryAllocator allocatorType = CRTHeapAllocator>
20+#define LEXCOMP_TEMPLARGS_NODEF \
21+template <eir::CharacterType charType, typename compileForEnvType, eir::MemoryAllocator allocatorType>
22+
23+#define LEXCOMP_TEMPLUSE \
24+<charType, compileForEnvType, allocatorType>
25+
26+LEXCOMP_TEMPLARGS
1927 struct LexingCompiler
2028 {
2129 typedef typename compileForEnvType::Step ExecStep;
@@ -23,7 +31,7 @@
2331 private:
2432 struct compilerRuntimeLifetimeManager
2533 {
26- inline compilerRuntimeLifetimeManager( LexingCompiler *compiler ) : compiler( compiler )
34+ inline compilerRuntimeLifetimeManager( LexingCompiler *compiler ) noexcept : compiler( compiler )
2735 {
2836 return;
2937 }
@@ -49,10 +57,14 @@
4957 LexingCompiler *compiler;
5058 };
5159
60+ DEFINE_HEAP_REDIR_ALLOC_BYSTRUCT( cenv_redirAlloc, allocatorType );
61+
5262 public:
53- typedef LexingEnvironment <charType, typename compileForEnvType::Step, allocatorType, compilerRuntimeLifetimeManager> cenv_t;
63+ typedef LexingEnvironment <charType, typename compileForEnvType::Step, cenv_redirAlloc, compilerRuntimeLifetimeManager> cenv_t;
5464
5565 private:
66+ [[no_unique_address]] allocatorType allocMan;
67+
5668 // Variable of the runtime environment we currently compile for.
5769 compileForEnvType *runtime_env = nullptr;
5870
@@ -310,7 +322,7 @@
310322
311323 template <typename... allocArgs> requires ( eir::constructible_from <allocatorType, allocArgs...> )
312324 LexingCompiler( eir::constr_with_alloc _, allocArgs&&... args )
313- : cenv( std::tuple <allocArgs&&...> ( std::forward <allocArgs> ( args )... ), std::tuple( this ) )
325+ : allocMan( std::forward <allocArgs> ( args )... ), cenv( std::tuple(), std::tuple( this ) )
314326 {
315327 // Since we are using a procedural alternatives step with no self, we have to be careful to enable
316328 // retreat if we have certain enclosed steps.
@@ -2744,4 +2756,6 @@
27442756 }
27452757 };
27462758
2759+IMPL_HEAP_REDIR_DYN_ALLOC_TEMPLATEBASE( LexingCompiler, LEXCOMP_TEMPLARGS_NODEF, LEXCOMP_TEMPLUSE, cenv_redirAlloc, LexingCompiler, cenv, allocMan, allocatorType );
2760+
27472761 #endif //_EIRCOMPILE_LEXING_COMPILER_HEADER_
\ No newline at end of file
--- eircompile/include/eircompile/lexing_env.h (revision 72)
+++ eircompile/include/eircompile/lexing_env.h (revision 73)
@@ -1,6 +1,9 @@
11 #ifndef _EIRCOMPILE_LEXING_ENVIRONMENT_
22 #define _EIRCOMPILE_LEXING_ENVIRONMENT_
33
4+// TODO: LexingEnvironment is currently not performing any memory-allocator refPtr consolidation, so common
5+// allocator templates do not work. This should be fixed.
6+
47 #include "common.h"
58 #include "nodescheduler.h"
69 #include "lexing_utils.h"
@@ -5583,23 +5586,23 @@
55835586 #endif //_DEBUG
55845587 }; // struct LexingEnvironment
55855588
5586-IMPL_HEAP_REDIR_DYN_ALLOC_TEMPLATEBASE( LexingEnvironment, LEXENV_TEMPLARGS_NODEF, LEXENV_TEMPLUSE, noprogress_data::edge_use_map_redirAlloc, noprogress_data, edge_use_map, theStep->env->allocMan, allocatorType );
5587-IMPL_HEAP_REDIR_DYN_ALLOC_TEMPLATEBASE( LexingEnvironment, LEXENV_TEMPLARGS_NODEF, LEXENV_TEMPLUSE, Step::attribute_key_redirAlloc, Step, attribute_key, env->allocMan, allocatorType );
5588-IMPL_HEAP_REDIR_DYN_ALLOC_TEMPLATEBASE( LexingEnvironment, LEXENV_TEMPLARGS_NODEF, LEXENV_TEMPLUSE, StepCall::production_name_redirAlloc, StepCall, production_name, env->allocMan, allocatorType );
5589-IMPL_HEAP_REDIR_DYN_ALLOC_TEMPLATEBASE( LexingEnvironment, LEXENV_TEMPLARGS_NODEF, LEXENV_TEMPLUSE, StepToken::token_str_redirAlloc, StepToken, token_str, env->allocMan, allocatorType );
5590-IMPL_HEAP_REDIR_DYN_ALLOC_TEMPLATEBASE( LexingEnvironment, LEXENV_TEMPLARGS_NODEF, LEXENV_TEMPLUSE, StepProgrammableToken::callback_redirAlloc, StepProgrammableToken, callback, env->allocMan, allocatorType );
5591-IMPL_HEAP_REDIR_DYN_ALLOC_TEMPLATEBASE( LexingEnvironment, LEXENV_TEMPLARGS_NODEF, LEXENV_TEMPLUSE, StepAlternatives::alts_redirAlloc, StepAlternatives, alts, env->allocMan, allocatorType );
5592-IMPL_HEAP_REDIR_DYN_ALLOC_TEMPLATEBASE( LexingEnvironment, LEXENV_TEMPLARGS_NODEF, LEXENV_TEMPLUSE, SerializedStep::steps_redirAlloc, SerializedStep, steps, env->allocMan, allocatorType );
5593-IMPL_HEAP_REDIR_DYN_ALLOC_TEMPLATEBASE( LexingEnvironment, LEXENV_TEMPLARGS_NODEF, LEXENV_TEMPLUSE, StepExtensionPoint::extensions_redirAlloc, StepExtensionPoint, extensions, env->allocMan, allocatorType );
5594-IMPL_HEAP_REDIR_DYN_ALLOC_TEMPLATEBASE( LexingEnvironment, LEXENV_TEMPLARGS_NODEF, LEXENV_TEMPLUSE, StepProceduralAlternatives::alts_redirAlloc, StepProceduralAlternatives, alts, env->allocMan, allocatorType );
5595-IMPL_HEAP_REDIR_DYN_ALLOC_TEMPLATEBASE( LexingEnvironment, LEXENV_TEMPLARGS_NODEF, LEXENV_TEMPLUSE, StepProceduralSequence::steps_redirAlloc, StepProceduralSequence, steps, env->allocMan, allocatorType );
5596-IMPL_HEAP_REDIR_DYN_ALLOC_TEMPLATEBASE( LexingEnvironment, LEXENV_TEMPLARGS_NODEF, LEXENV_TEMPLUSE, StepCustomIndirection::refs_redirAlloc, StepCustomIndirection, refs, env->allocMan, allocatorType );
5597-IMPL_HEAP_REDIR_DYN_ALLOC_TEMPLATEBASE( LexingEnvironment, LEXENV_TEMPLARGS_NODEF, LEXENV_TEMPLUSE, StepCustomIndirection::callback_redirAlloc, StepCustomIndirection, callback, env->allocMan, allocatorType );
5598-IMPL_HEAP_REDIR_DYN_ALLOC_TEMPLATEBASE( LexingEnvironment, LEXENV_TEMPLARGS_NODEF, LEXENV_TEMPLUSE, StepReplacementPoint::replacements_redirAlloc, StepReplacementPoint, replacements, env->allocMan, allocatorType );
5599-IMPL_HEAP_REDIR_DYN_ALLOC_TEMPLATEBASE( LexingEnvironment, LEXENV_TEMPLARGS_NODEF, LEXENV_TEMPLUSE, StepReplacementPoint::valrefs_redirAlloc, StepReplacementPoint, valrefs, env->allocMan, allocatorType );
5600-IMPL_HEAP_REDIR_DYN_ALLOC_TEMPLATEBASE( LexingEnvironment, LEXENV_TEMPLARGS_NODEF, LEXENV_TEMPLUSE, ProductionMachine::CalcPathEntry::attrib_prefix_redirAlloc, CalcPathEntry, attrib_prefix, current_step->env->allocMan, allocatorType );
5601-IMPL_HEAP_REDIR_DYN_ALLOC_TEMPLATEBASE( LexingEnvironment, LEXENV_TEMPLARGS_NODEF, LEXENV_TEMPLUSE, ProductionMachine::CalcPathEntry::noprogress_map_redirAlloc, CalcPathEntry, noprogress_map, current_step->env->allocMan, allocatorType );
5602-IMPL_HEAP_REDIR_DYN_ALLOC_TEMPLATEBASE( LexingEnvironment, LEXENV_TEMPLARGS_NODEF, LEXENV_TEMPLUSE, ProductionMachine::debug_breaks_redirAlloc, ProductionMachine, debug_breaks, env->allocMan, allocatorType );
5589+IMPL_HEAP_REDIR_DYNRPTR_ALLOC_TEMPLATEBASE( LexingEnvironment, LEXENV_TEMPLARGS_NODEF, LEXENV_TEMPLUSE, noprogress_data::edge_use_map_redirAlloc, noprogress_data, edge_use_map, theStep->env, allocMan, allocatorType );
5590+IMPL_HEAP_REDIR_DYNRPTR_ALLOC_TEMPLATEBASE( LexingEnvironment, LEXENV_TEMPLARGS_NODEF, LEXENV_TEMPLUSE, Step::attribute_key_redirAlloc, Step, attribute_key, env, allocMan, allocatorType );
5591+IMPL_HEAP_REDIR_DYNRPTR_ALLOC_TEMPLATEBASE( LexingEnvironment, LEXENV_TEMPLARGS_NODEF, LEXENV_TEMPLUSE, StepCall::production_name_redirAlloc, StepCall, production_name, env, allocMan, allocatorType );
5592+IMPL_HEAP_REDIR_DYNRPTR_ALLOC_TEMPLATEBASE( LexingEnvironment, LEXENV_TEMPLARGS_NODEF, LEXENV_TEMPLUSE, StepToken::token_str_redirAlloc, StepToken, token_str, env, allocMan, allocatorType );
5593+IMPL_HEAP_REDIR_DYNRPTR_ALLOC_TEMPLATEBASE( LexingEnvironment, LEXENV_TEMPLARGS_NODEF, LEXENV_TEMPLUSE, StepProgrammableToken::callback_redirAlloc, StepProgrammableToken, callback, env, allocMan, allocatorType );
5594+IMPL_HEAP_REDIR_DYNRPTR_ALLOC_TEMPLATEBASE( LexingEnvironment, LEXENV_TEMPLARGS_NODEF, LEXENV_TEMPLUSE, StepAlternatives::alts_redirAlloc, StepAlternatives, alts, env, allocMan, allocatorType );
5595+IMPL_HEAP_REDIR_DYNRPTR_ALLOC_TEMPLATEBASE( LexingEnvironment, LEXENV_TEMPLARGS_NODEF, LEXENV_TEMPLUSE, SerializedStep::steps_redirAlloc, SerializedStep, steps, env, allocMan, allocatorType );
5596+IMPL_HEAP_REDIR_DYNRPTR_ALLOC_TEMPLATEBASE( LexingEnvironment, LEXENV_TEMPLARGS_NODEF, LEXENV_TEMPLUSE, StepExtensionPoint::extensions_redirAlloc, StepExtensionPoint, extensions, env, allocMan, allocatorType );
5597+IMPL_HEAP_REDIR_DYNRPTR_ALLOC_TEMPLATEBASE( LexingEnvironment, LEXENV_TEMPLARGS_NODEF, LEXENV_TEMPLUSE, StepProceduralAlternatives::alts_redirAlloc, StepProceduralAlternatives, alts, env, allocMan, allocatorType );
5598+IMPL_HEAP_REDIR_DYNRPTR_ALLOC_TEMPLATEBASE( LexingEnvironment, LEXENV_TEMPLARGS_NODEF, LEXENV_TEMPLUSE, StepProceduralSequence::steps_redirAlloc, StepProceduralSequence, steps, env, allocMan, allocatorType );
5599+IMPL_HEAP_REDIR_DYNRPTR_ALLOC_TEMPLATEBASE( LexingEnvironment, LEXENV_TEMPLARGS_NODEF, LEXENV_TEMPLUSE, StepCustomIndirection::refs_redirAlloc, StepCustomIndirection, refs, env, allocMan, allocatorType );
5600+IMPL_HEAP_REDIR_DYNRPTR_ALLOC_TEMPLATEBASE( LexingEnvironment, LEXENV_TEMPLARGS_NODEF, LEXENV_TEMPLUSE, StepCustomIndirection::callback_redirAlloc, StepCustomIndirection, callback, env, allocMan, allocatorType );
5601+IMPL_HEAP_REDIR_DYNRPTR_ALLOC_TEMPLATEBASE( LexingEnvironment, LEXENV_TEMPLARGS_NODEF, LEXENV_TEMPLUSE, StepReplacementPoint::replacements_redirAlloc, StepReplacementPoint, replacements, env, allocMan, allocatorType );
5602+IMPL_HEAP_REDIR_DYNRPTR_ALLOC_TEMPLATEBASE( LexingEnvironment, LEXENV_TEMPLARGS_NODEF, LEXENV_TEMPLUSE, StepReplacementPoint::valrefs_redirAlloc, StepReplacementPoint, valrefs, env, allocMan, allocatorType );
5603+IMPL_HEAP_REDIR_DYNRPTR_ALLOC_TEMPLATEBASE( LexingEnvironment, LEXENV_TEMPLARGS_NODEF, LEXENV_TEMPLUSE, ProductionMachine::CalcPathEntry::attrib_prefix_redirAlloc, CalcPathEntry, attrib_prefix, current_step->env, allocMan, allocatorType );
5604+IMPL_HEAP_REDIR_DYNRPTR_ALLOC_TEMPLATEBASE( LexingEnvironment, LEXENV_TEMPLARGS_NODEF, LEXENV_TEMPLUSE, ProductionMachine::CalcPathEntry::noprogress_map_redirAlloc, CalcPathEntry, noprogress_map, current_step->env, allocMan, allocatorType );
5605+IMPL_HEAP_REDIR_DYNRPTR_ALLOC_TEMPLATEBASE( LexingEnvironment, LEXENV_TEMPLARGS_NODEF, LEXENV_TEMPLUSE, ProductionMachine::debug_breaks_redirAlloc, ProductionMachine, debug_breaks, env, allocMan, allocatorType );
56035606 IMPL_HEAP_REDIR_DYN_ALLOC_TEMPLATEBASE( LexingEnvironment, LEXENV_TEMPLARGS_NODEF, LEXENV_TEMPLUSE, nonterminal_namespace_redirAlloc, LexingEnvironment, nonterminal_namespace, allocMan, allocatorType );
56045607
56055608 #endif //_EIRCOMPILE_LEXING_ENVIRONMENT_
\ No newline at end of file
--- testcompiler/src/cos_tests.cpp (revision 72)
+++ testcompiler/src/cos_tests.cpp (revision 73)
@@ -1,5 +1,8 @@
11 #include <eircompile/lexing.h>
22
3+#include <commonlangs/cos.h>
4+#include <commonlangs/cos_env.h>
5+
36 // We define a test-version of the COS here and run calculations on it.
47 // Proof-of-concept so to speak.
58
@@ -7,3279 +10,27 @@
710
811 #include <assert.h>
912
10-namespace COS
11-{
12-
13-struct COSNode
14-{
15- virtual ~COSNode( void )
16- {}
17-
18- inline void Delete( void ) noexcept
19- {
20- delete this;
21- }
22-
23- // Thanks to selector-based nodes we can detach the actual node building from the node logic itself.
24- // This were a burden because it would require character-based methods that we would not want to lock to character encodings.
25-};
26-
27-struct Program : public COSNode
28-{
29- inline Program( depVector <COSNode*> statements = {} ) noexcept : statements( std::move( statements ) )
30- {
31- return;
32- }
33- inline Program( const Program& ) = default;
34- inline Program( Program&& ) = default;
35-
36- depVector <COSNode*> statements;
37-};
38-
39-struct Operation : public COSNode
40-{
41-};
42-
43-struct UnaryOperation : public COSNode
44-{
45- inline UnaryOperation( COSNode *op = nullptr ) noexcept : op( op )
46- {
47- return;
48- }
49- inline UnaryOperation( const UnaryOperation& ) = default;
50- inline UnaryOperation( UnaryOperation&& ) = default;
51-
52- COSNode *op;
53-};
54-
55-struct LogicalNegationOperation : public UnaryOperation
56-{
57- using UnaryOperation::UnaryOperation;
58-};
59-struct BitwiseNegationOperation : public UnaryOperation
60-{
61- using UnaryOperation::UnaryOperation;
62-};
63-struct NumericNegationOperation : public UnaryOperation
64-{
65- using UnaryOperation::UnaryOperation;
66-};
67-struct PreIncrementOperation : public UnaryOperation
68-{
69- using UnaryOperation::UnaryOperation;
70-};
71-struct PreDecrementOperation : public UnaryOperation
72-{
73- using UnaryOperation::UnaryOperation;
74-};
75-struct PostIncrementOperation : public UnaryOperation
76-{
77- using UnaryOperation::UnaryOperation;
78-};
79-struct PostDecrementOperation : public UnaryOperation
80-{
81- using UnaryOperation::UnaryOperation;
82-};
83-struct ResolveSpecifierOperation : public UnaryOperation
84-{
85- using UnaryOperation::UnaryOperation;
86-};
87-struct PointerResolveOperation : public UnaryOperation
88-{
89- using UnaryOperation::UnaryOperation;
90-};
91-struct AddressOfOperation : public UnaryOperation
92-{
93- using UnaryOperation::UnaryOperation;
94-};
95-
96-struct BinaryOperation : public Operation
97-{
98- inline BinaryOperation( COSNode *left = nullptr, COSNode *right = nullptr ) noexcept : left( left ), right( right )
99- {
100- return;
101- }
102- inline BinaryOperation( const BinaryOperation& ) = default;
103- inline BinaryOperation( BinaryOperation&& ) = default;
104-
105- COSNode *left;
106- COSNode *right;
107-};
108-
109-struct AddOperation : public BinaryOperation
110-{
111- using BinaryOperation::BinaryOperation;
112-};
113-struct SubOperation : public BinaryOperation
114-{
115- using BinaryOperation::BinaryOperation;
116-};
117-struct MulOperation : public BinaryOperation
118-{
119- using BinaryOperation::BinaryOperation;
120-};
121-struct DivOperation : public BinaryOperation
122-{
123- using BinaryOperation::BinaryOperation;
124-};
125-struct ModulusOperation : public BinaryOperation
126-{
127- using BinaryOperation::BinaryOperation;
128-};
129-struct BitwiseAndOperation : public BinaryOperation
130-{
131- using BinaryOperation::BinaryOperation;
132-};
133-struct BitwiseOrOperation : public BinaryOperation
134-{
135- using BinaryOperation::BinaryOperation;
136-};
137-struct BitwiseXorOperation : public BinaryOperation
138-{
139- using BinaryOperation::BinaryOperation;
140-};
141-struct BitshiftLeftOperation : public BinaryOperation
142-{
143- using BinaryOperation::BinaryOperation;
144-};
145-struct BitshiftRightOperation : public BinaryOperation
146-{
147- using BinaryOperation::BinaryOperation;
148-};
149-struct CompareEqualityOperation : public BinaryOperation
150-{
151- using BinaryOperation::BinaryOperation;
152-};
153-struct CompareInequalityOperation : public BinaryOperation
154-{
155- using BinaryOperation::BinaryOperation;
156-};
157-struct CompareLessThanOperation : public BinaryOperation
158-{
159- using BinaryOperation::BinaryOperation;
160-};
161-struct CompareGreaterThanOperation : public BinaryOperation
162-{
163- using BinaryOperation::BinaryOperation;
164-};
165-struct CompareLessThanEqualOperation : public BinaryOperation
166-{
167- using BinaryOperation::BinaryOperation;
168-};
169-struct CompareGreaterThanEqualOperation : public BinaryOperation
170-{
171- using BinaryOperation::BinaryOperation;
172-};
173-struct LogicalAndOperation : public BinaryOperation
174-{
175- using BinaryOperation::BinaryOperation;
176-};
177-struct LogicalOrOperation : public BinaryOperation
178-{
179- using BinaryOperation::BinaryOperation;
180-};
181-struct AssignmentOperation : public BinaryOperation
182-{
183- using BinaryOperation::BinaryOperation;
184-};
185-struct EdgeBracketsOperation : public BinaryOperation
186-{
187- // a[b]
188- using BinaryOperation::BinaryOperation;
189-};
190-struct DotOperation : public BinaryOperation
191-{
192- // a.b
193- using BinaryOperation::BinaryOperation;
194-};
195-struct ArrowOperation : public BinaryOperation
196-{
197- using BinaryOperation::BinaryOperation;
198-};
199-
200-struct AssignAddOperation : public BinaryOperation
201-{
202- using BinaryOperation::BinaryOperation;
203-};
204-struct AssignSubOperation : public BinaryOperation
205-{
206- using BinaryOperation::BinaryOperation;
207-};
208-struct AssignMulOperation : public BinaryOperation
209-{
210- using BinaryOperation::BinaryOperation;
211-};
212-struct AssignDivOperation : public BinaryOperation
213-{
214- using BinaryOperation::BinaryOperation;
215-};
216-struct AssignModulusOperation : public BinaryOperation
217-{
218- using BinaryOperation::BinaryOperation;
219-};
220-struct AssignBitwiseXorOperation : public BinaryOperation
221-{
222- using BinaryOperation::BinaryOperation;
223-};
224-struct AssignBitwiseAndOperation : public BinaryOperation
225-{
226- using BinaryOperation::BinaryOperation;
227-};
228-struct AssignBitwiseOrOperation : public BinaryOperation
229-{
230- using BinaryOperation::BinaryOperation;
231-};
232-struct AssignDotOperation : public BinaryOperation
233-{
234- using BinaryOperation::BinaryOperation;
235-};
236-struct AssignArrowOperation : public BinaryOperation
237-{
238- using BinaryOperation::BinaryOperation;
239-};
240-struct AssignBitshiftLeftOperation : public BinaryOperation
241-{
242- using BinaryOperation::BinaryOperation;
243-};
244-struct AssignBitshiftRightOperation : public BinaryOperation
245-{
246- using BinaryOperation::BinaryOperation;
247-};
248-
249-struct FunctionCallOperation : public Operation
250-{
251- inline FunctionCallOperation( COSNode *what = nullptr, depVector <COSNode*> params = {} ) noexcept : what( what ), params( std::move( params ) )
252- {
253- return;
254- }
255- inline FunctionCallOperation( const FunctionCallOperation& ) = default;
256- inline FunctionCallOperation( FunctionCallOperation&& right ) noexcept : params( std::move( right.params ) )
257- {
258- this->what = right.what;
259-
260- right.what = nullptr;
261- }
262-
263- COSNode *what;
264- depVector <COSNode*> params;
265-};
266-struct ArrayInitOperation : public Operation
267-{
268- inline ArrayInitOperation( COSNode *what = nullptr, depVector <COSNode*> items = {} ) noexcept : what( what ), items( std::move( items ) )
269- {
270- return;
271- }
272- inline ArrayInitOperation( const ArrayInitOperation& ) = default;
273- inline ArrayInitOperation( ArrayInitOperation&& right ) noexcept : items( std::move( right.items ) )
274- {
275- this->what = right.what;
276-
277- right.what = nullptr;
278- }
279-
280- COSNode *what;
281- depVector <COSNode*> items;
282-};
283-
284-struct NewOperation : public Operation
285-{
286- inline NewOperation( COSNode *type = nullptr, depVector <COSNode*> params = {} ) noexcept : type( type ), params( std::move( params ) )
287- {
288- return;
289- }
290- inline NewOperation( const NewOperation& ) = default;
291- inline NewOperation( NewOperation&& right ) noexcept : params( std::move( right.params ) )
292- {
293- this->type = right.type;
294-
295- right.type = nullptr;
296- }
297-
298- COSNode *type;
299- depVector <COSNode*> params;
300-};
301-struct ReplaceOperation : public Operation
302-{
303- inline ReplaceOperation( COSNode *what = nullptr, COSNode *with = nullptr ) noexcept : what( what ), with( with )
304- {
305- return;
306- }
307- inline ReplaceOperation( const ReplaceOperation& ) = default;
308- inline ReplaceOperation( ReplaceOperation&& ) = default;
309-
310- COSNode *what;
311- COSNode *with;
312-};
313-struct DeleteOperation : public UnaryOperation
314-{
315- using UnaryOperation::UnaryOperation;
316-};
317-
318-struct CastOperation : public Operation
319-{
320- inline CastOperation( COSNode *totype = nullptr, COSNode *castobj = nullptr ) noexcept : totype( totype ), castobj( castobj )
321- {
322- return;
323- }
324- inline CastOperation( const CastOperation& ) = default;
325- inline CastOperation( CastOperation&& right ) noexcept
326- {
327- this->totype = right.totype;
328- this->castobj = right.castobj;
329-
330- right.totype = nullptr;
331- right.castobj = nullptr;
332- }
333-
334- COSNode *totype;
335- COSNode *castobj;
336-};
337-
338-struct TemplateInstantiationOperation : public Operation
339-{
340- inline TemplateInstantiationOperation( COSNode *templ = nullptr, depVector <COSNode*> tparams = {} ) noexcept : templ( templ ), tparams( std::move( tparams ) )
341- {
342- return;
343- }
344- inline TemplateInstantiationOperation( const TemplateInstantiationOperation& ) = default;
345- inline TemplateInstantiationOperation( TemplateInstantiationOperation&& right ) noexcept : tparams( std::move( right.tparams ) )
346- {
347- this->templ = right.templ;
348-
349- right.templ = nullptr;
350- }
351-
352- COSNode *templ;
353- depVector <COSNode*> tparams;
354-};
355-
356-struct IfStatement : public COSNode
357-{
358- inline IfStatement( COSNode *condition = nullptr, COSNode *true_branch = nullptr, COSNode *false_branch = nullptr ) noexcept : condition( condition ), true_branch( true_branch ), false_branch( false_branch )
359- {
360- return;
361- }
362- inline IfStatement( const IfStatement& ) = default;
363- inline IfStatement( IfStatement&& right ) noexcept
364- {
365- this->condition = right.condition;
366- this->true_branch = right.true_branch;
367- this->false_branch = right.false_branch;
368-
369- right.condition = nullptr;
370- right.true_branch = nullptr;
371- right.false_branch = nullptr;
372- }
373-
374- COSNode *condition;
375- COSNode *true_branch;
376- COSNode *false_branch;
377-};
378-struct WhileLoopStatement : public COSNode
379-{
380- inline WhileLoopStatement( COSNode *condition = nullptr, COSNode *exec = nullptr ) noexcept : condition( condition ), exec( exec )
381- {
382- return;
383- }
384- inline WhileLoopStatement( const WhileLoopStatement& ) = default;
385- inline WhileLoopStatement( WhileLoopStatement&& right ) noexcept
386- {
387- this->condition = right.condition;
388- this->exec = right.exec;
389-
390- right.condition = nullptr;
391- right.exec = nullptr;
392- }
393-
394- COSNode *condition;
395- COSNode *exec;
396-};
397-struct ForLoopStatement : public COSNode
398-{
399- inline ForLoopStatement( COSNode *init = nullptr, COSNode *condition = nullptr, COSNode *iteration = nullptr, COSNode *exec = nullptr ) noexcept : init( init ), condition( condition ), iteration( iteration ), exec( exec )
400- {
401- return;
402- }
403- inline ForLoopStatement( const ForLoopStatement& ) = default;
404- inline ForLoopStatement( ForLoopStatement&& right ) noexcept
405- {
406- this->init = right.init;
407- this->condition = right.condition;
408- this->iteration = right.iteration;
409- this->exec = right.exec;
410-
411- right.init = nullptr;
412- right.condition = nullptr;
413- right.iteration = nullptr;
414- right.exec = nullptr;
415- }
416-
417- COSNode *init;
418- COSNode *condition;
419- COSNode *iteration;
420- COSNode *exec;
421-};
422-struct ContinueStatement : public COSNode
423-{
424-};
425-struct BreakStatement : public COSNode
426-{
427-};
428-
429-struct ReturnStatement : public COSNode
430-{
431- inline ReturnStatement( COSNode *op = nullptr ) noexcept : op( op )
432- {
433- return;
434- }
435- inline ReturnStatement( const ReturnStatement& ) = default;
436- inline ReturnStatement( ReturnStatement&& right ) noexcept
437- {
438- this->op = right.op;
439-
440- right.op = nullptr;
441- }
442-
443- COSNode *op;
444-};
445-
446-struct DeclarationStatement : public COSNode
447-{
448- inline DeclarationStatement( COSNode *name = nullptr, COSNode *type = nullptr, COSNode *initializer = nullptr ) noexcept : name( name ), type( type ), initializer( initializer )
449- {
450- return;
451- }
452- inline DeclarationStatement( const DeclarationStatement& ) = default;
453- inline DeclarationStatement( DeclarationStatement&& right ) noexcept
454- {
455- this->name = right.name;
456- this->type = right.type;
457- this->initializer = right.initializer;
458-
459- right.name = nullptr;
460- right.type = nullptr;
461- right.initializer = nullptr;
462- }
463-
464- COSNode *name;
465- COSNode *type;
466- COSNode *initializer;
467-};
468-struct MultiDeclarationStatement : public COSNode
469-{
470- // Just a pack of declarations because we cannot keep them outside.
471-
472- inline MultiDeclarationStatement( depVector <DeclarationStatement*> decls = {} ) noexcept : decls( std::move( decls ) )
473- {}
474- inline MultiDeclarationStatement( const MultiDeclarationStatement& ) = default;
475- inline MultiDeclarationStatement( MultiDeclarationStatement&& ) = default;
476-
477- depVector <DeclarationStatement*> decls;
478-};
479-
480-struct TypedefStatement : public COSNode
481-{
482- inline TypedefStatement( COSNode *srctype = nullptr, COSNode *dsttype = nullptr ) noexcept : srctype( srctype ), dsttype( dsttype )
483- {
484- return;
485- }
486- inline TypedefStatement( const TypedefStatement& ) = default;
487- inline TypedefStatement( TypedefStatement&& right ) noexcept
488- {
489- this->srctype = right.srctype;
490- this->dsttype = right.dsttype;
491-
492- right.srctype = nullptr;
493- right.dsttype = nullptr;
494- }
495-
496- COSNode *srctype;
497- COSNode *dsttype;
498-};
499-struct MultiTypedefStatement : public COSNode
500-{
501- inline MultiTypedefStatement( depVector <TypedefStatement*> defs = {} ) noexcept : defs( std::move( defs ) )
502- {
503- return;
504- }
505- inline MultiTypedefStatement( const MultiTypedefStatement& ) = default;
506- inline MultiTypedefStatement( MultiTypedefStatement&& ) = default;
507-
508- depVector <TypedefStatement*> defs;
509-};
510-
511-struct BlockStatement : public COSNode
512-{
513- inline BlockStatement( depVector <COSNode*> statements = {} ) noexcept : statements( std::move( statements ) )
514- {
515- return;
516- }
517- inline BlockStatement( const BlockStatement& ) = default;
518- inline BlockStatement( BlockStatement&& right ) noexcept : statements( std::move( right.statements ) )
519- {
520- return;
521- }
522-
523- depVector <COSNode*> statements;
524-};
525-
526-struct ThrowStatement : public COSNode
527-{
528- inline ThrowStatement( COSNode *op = nullptr ) noexcept : op( op )
529- {
530- return;
531- }
532- inline ThrowStatement( const ThrowStatement& ) = default;
533- inline ThrowStatement( ThrowStatement&& right ) noexcept
534- {
535- this->op = right.op;
536-
537- right.op = nullptr;
538- }
539-
540- COSNode *op;
541-};
542-struct CatchStatement : public COSNode
543-{
544- inline CatchStatement( COSNode *caught_decl = nullptr, COSNode *catch_body = nullptr ) noexcept : caught_decl( caught_decl ), catch_body( catch_body )
545- {
546- return;
547- }
548- inline CatchStatement( const CatchStatement& ) = default;
549- inline CatchStatement( CatchStatement&& right ) noexcept
550- {
551- this->caught_decl = right.caught_decl;
552- this->catch_body = right.catch_body;
553-
554- right.caught_decl = nullptr;
555- right.catch_body = nullptr;
556- }
557-
558- COSNode *caught_decl;
559- COSNode *catch_body;
560-};
561-struct TryStatement : public COSNode
562-{
563- inline TryStatement( COSNode *try_body = nullptr, depVector <CatchStatement*> errors = {} ) noexcept : try_body( try_body ), errors( std::move( errors ) )
564- {
565- return;
566- }
567- inline TryStatement( const TryStatement& ) = default;
568- inline TryStatement( TryStatement&& right ) noexcept : errors( std::move( right.errors ) )
569- {
570- this->try_body = right.try_body;
571-
572- right.try_body = nullptr;
573- }
574-
575- COSNode *try_body;
576- depVector <CatchStatement*> errors;
577-};
578-
579-struct StructDefinition : public COSNode
580-{
581- inline StructDefinition( COSNode *name = nullptr, COSNode *body = nullptr ) noexcept : name( name ), body( body )
582- {
583- return;
584- }
585- inline StructDefinition( const StructDefinition& ) = default;
586- inline StructDefinition( StructDefinition&& right ) noexcept
587- {
588- this->name = right.name;
589- this->body = right.body;
590-
591- right.name = nullptr;
592- right.body = nullptr;
593- }
594-
595- COSNode *name;
596- COSNode *body;
597-};
598-struct ConstructorDefinition : public COSNode
599-{
600- inline ConstructorDefinition( depVector <COSNode*> params = {}, COSNode *body = nullptr ) noexcept : params( std::move( params ) ), body( body )
601- {
602- return;
603- }
604- inline ConstructorDefinition( const ConstructorDefinition& ) = default;
605- inline ConstructorDefinition( ConstructorDefinition&& right ) noexcept : params( std::move( right.params ) )
606- {
607- this->body = right.body;
608-
609- right.body = nullptr;
610- }
611-
612- depVector <COSNode*> params;
613- COSNode *body;
614-};
615-struct DestructorDefinition : public COSNode
616-{
617- inline DestructorDefinition( COSNode *body = nullptr ) noexcept
618- {
619- this->body = body;
620- }
621- inline DestructorDefinition( const DestructorDefinition& ) = default;
622- inline DestructorDefinition( DestructorDefinition&& right ) noexcept
623- {
624- this->body = right.body;
625-
626- right.body = nullptr;
627- }
628-
629- COSNode *body;
630-};
631-
632-struct SpecifierString : public COSNode
633-{
634- inline SpecifierString( depMultiString string = {} ) noexcept : string( std::move( string ) )
635- {
636- return;
637- }
638- inline SpecifierString( const SpecifierString& ) = default;
639- inline SpecifierString( SpecifierString&& ) = default;
640-
641- depMultiString string;
642-};
643-struct NumberString : public COSNode
644-{
645- inline NumberString( depMultiString string = {} ) noexcept : numeric_string( std::move( string ) )
646- {
647- return;
648- }
649- inline NumberString( const NumberString& ) = default;
650- inline NumberString( NumberString&& ) = default;
651-
652- depMultiString numeric_string;
653-};
654-struct SpecifierOperator : public COSNode
655-{
656- enum class eOpType
657- {
658- UNDEFINED,
659-
660- ADD,
661- SUBTRACT,
662- MULTIPLY,
663- DIVIDE,
664- MODULUS,
665- BIT_XOR,
666- BIT_AND,
667- BIT_OR,
668- LOGICAL_NEGATE,
669- DOT,
670- ARROW,
671- ASSIGN,
672- BIT_NEGATE,
673-
674- ASSIGN_ADD,
675- ASSIGN_SUBTRACT,
676- ASSIGN_MULTIPLY,
677- ASSIGN_DIVIDE,
678- ASSIGN_MODULUS,
679- ASSIGN_BIT_XOR,
680- ASSIGN_BIT_AND,
681- ASSIGN_BIT_OR,
682- ASSIGN_DOT,
683- ASSIGN_ARROW,
684- ASSIGN_BITSHIFT_LEFT,
685- ASSIGN_BITSHIFT_RIGHT,
686-
687- COMPARE_EQUALITY,
688- COMPARE_GREATER_THAN,
689- COMPARE_LESS_THAN,
690- COMPARE_GREATER_THAN_EQUAL,
691- COMPARE_LESS_THAN_EQUAL,
692- COMPARE_INEQUALITY,
693-
694- LOGICAL_AND,
695- LOGICAL_OR,
696- BITSHIFT_LEFT,
697- BITSHIFT_RIGHT
698- };
699-
700- inline SpecifierOperator( eOpType op_type = eOpType::UNDEFINED ) noexcept : op_type( op_type )
701- {
702- return;
703- }
704- inline SpecifierOperator( const SpecifierOperator& ) = default;
705- inline SpecifierOperator( SpecifierOperator&& ) = default;
706-
707- eOpType op_type = eOpType::UNDEFINED;
708-};
709-
710-struct TypeSpecifier : public COSNode
711-{
712- inline TypeSpecifier( COSNode *spec = nullptr ) noexcept : spec( spec )
713- {}
714- inline TypeSpecifier( const TypeSpecifier& ) = default;
715- inline TypeSpecifier( TypeSpecifier&& right ) noexcept
716- {
717- this->spec = right.spec;
718-
719- right.spec = nullptr;
720- }
721-
722- static inline COSNode* ResolveUntilMostSpecialized( COSNode *iter )
723- {
724- while ( true )
725- {
726- TypeSpecifier *type_spec = dynamic_cast <TypeSpecifier*> ( iter );
727-
728- if ( type_spec == nullptr )
729- {
730- return iter;
731- }
732-
733- COSNode *more_specialized = type_spec->spec;
734-
735- if ( more_specialized == nullptr )
736- {
737- return iter;
738- }
739-
740- iter = more_specialized;
741- }
742-
743- return nullptr;
744- }
745-
746- COSNode *spec;
747-};
748-struct PointerTypeSpecifier : public TypeSpecifier
749-{
750- using TypeSpecifier::TypeSpecifier;
751-};
752-struct RefTypeSpecifier : public TypeSpecifier
753-{
754- using TypeSpecifier::TypeSpecifier;
755-};
756-struct ArrayTypeSpecifier : public TypeSpecifier
757-{
758- inline ArrayTypeSpecifier( COSNode *spec = nullptr, COSNode *array_size_op = nullptr ) noexcept : TypeSpecifier( spec ), array_size_op( array_size_op )
759- {
760- return;
761- }
762- inline ArrayTypeSpecifier( const ArrayTypeSpecifier& ) = default;
763- inline ArrayTypeSpecifier( ArrayTypeSpecifier&& right ) noexcept : TypeSpecifier( std::move( right ) )
764- {
765- this->array_size_op = right.array_size_op;
766-
767- right.array_size_op = nullptr;
768- }
769-
770- COSNode *array_size_op;
771-};
772-
773-struct CurlyPack : public COSNode
774-{
775- inline CurlyPack( depVector <COSNode*> params = {} ) noexcept : params( std::move( params ) )
776- {
777- return;
778- }
779- inline CurlyPack( const CurlyPack& ) = default;
780- inline CurlyPack( CurlyPack&& ) = default;
781-
782- depVector <COSNode*> params;
783-};
784-struct ArrayDefinition : public COSNode
785-{
786- // { i1, ... in }
787-
788- inline ArrayDefinition( depVector <COSNode*> items = {} ) noexcept : items( std::move( items ) )
789- {
790- return;
791- }
792- inline ArrayDefinition( const ArrayDefinition& ) = default;
793- inline ArrayDefinition( ArrayDefinition&& ) = default;
794-
795- depVector <COSNode*> items;
796-};
797-struct FuncsigDefinition : public COSNode
798-{
799- inline FuncsigDefinition( COSNode *return_type = nullptr, depVector <COSNode*> params = {} ) noexcept : return_type( return_type ), params( std::move( params ) )
800- {}
801- inline FuncsigDefinition( const FuncsigDefinition& ) = default;
802- inline FuncsigDefinition( FuncsigDefinition&& right ) noexcept : params( std::move( right.params ) )
803- {
804- this->return_type = right.return_type;
805-
806- right.return_type = nullptr;
807- }
808-
809- // Returns the left-most function signature definition of this node.
810- inline FuncsigDefinition* GetDeepestReturnValueFunctionSignatureType( void )
811- {
812- FuncsigDefinition *deepest = this;
813-
814- while ( FuncsigDefinition *any_deeper = dynamic_cast <FuncsigDefinition*> ( TypeSpecifier::ResolveUntilMostSpecialized( deepest->return_type ) ) )
815- {
816- deepest = any_deeper;
817- }
818-
819- return deepest;
820- }
821-
822- COSNode *return_type;
823- depVector <COSNode*> params;
824-};
825-
826-struct NamespaceStatement : public COSNode
827-{
828- inline NamespaceStatement( COSNode *name = nullptr, COSNode *toinclude = nullptr ) noexcept : name( name ), toinclude( toinclude )
829- {
830- return;
831- }
832- inline NamespaceStatement( const NamespaceStatement& ) = default;
833- inline NamespaceStatement( NamespaceStatement&& right ) noexcept
834- {
835- this->name = right.name;
836- this->toinclude = right.toinclude;
837-
838- right.name = nullptr;
839- right.toinclude = nullptr;
840- }
841-
842- COSNode *name;
843- COSNode *toinclude;
844-};
845-struct UsingNamespaceStatement : public COSNode
846-{
847- inline UsingNamespaceStatement( COSNode *nsname = nullptr ) noexcept : nsname( nsname )
848- {
849- return;
850- }
851- inline UsingNamespaceStatement( const UsingNamespaceStatement& ) = default;
852- inline UsingNamespaceStatement( UsingNamespaceStatement&& right ) noexcept
853- {
854- this->nsname = right.nsname;
855-
856- right.nsname = nullptr;
857- }
858-
859- COSNode *nsname;
860-};
861-
862-struct EnumDefinition : public COSNode
863-{
864- struct item
865- {
866- COSNode *key;
867- COSNode *value;
868- };
869-
870- inline EnumDefinition( COSNode *name = nullptr, depVector <item> items = {} ) noexcept : name( name ), items( std::move( items ) )
871- {
872- return;
873- }
874- inline EnumDefinition( const EnumDefinition& ) = default;
875- inline EnumDefinition( EnumDefinition&& right ) noexcept : items( std::move( right.items ) )
876- {
877- this->name = right.name;
878-
879- right.name = nullptr;
880- }
881-
882- COSNode *name;
883- depVector <item> items;
884-};
885-
886-}; // namespace COS
887-
888-static inline bool is_num_nonzero( char c )
889-{
890- static const char num_nonzero[] = "123456789";
891-
892- for ( char oc : num_nonzero )
893- {
894- if ( oc == c )
895- return true;
896- }
897- return false;
898-}
899-
900-static inline bool is_num( char c )
901-{
902- return ( c == '0' ) || is_num_nonzero( c );
903-}
904-
905-static inline bool is_alpha( char c )
906-{
907- static const char alpha[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
908-
909- for ( char oc : alpha )
910- {
911- if ( oc == c )
912- return true;
913- }
914- return false;
915-}
916-
917-static inline bool is_alpha_num( char c )
918-{
919- return is_num( c ) || is_alpha( c );
920-}
921-
922-static inline bool is_name_special( char c )
923-{
924- static const char spc[] = "_";
925-
926- for ( char oc : spc )
927- {
928- if ( oc == c )
929- return true;
930- }
931- return false;
932-}
933-
934-static inline bool is_name_char( char c )
935-{
936- return is_alpha_num( c ) || is_name_special( c );
937-}
938-
939-static inline bool is_name_alpha( char c )
940-{
941- return is_alpha( c ) || is_name_special( c );
942-}
943-
944-static inline bool is_space_char( char c )
945-{
946- static const char spaces[] = " \t\n\r";
947-
948- for ( char oc : spaces )
949- {
950- if ( oc == c )
951- return true;
952- }
953- return false;
954-}
955-
95613 void COMPILEROBJECTSYNTAX_TESTS( void )
95714 {
95815 using namespace COS;
95916
960- Lexer <char, COSNode, EirHeapLinkAllocator> lexer( eir::constr_with_alloc::DEFAULT, &globalHeapAlloc );
961- LexingCompiler <char, decltype(lexer)::RuntimeEnv, EirHeapLinkAllocator> compiler( eir::constr_with_alloc::DEFAULT, &globalHeapAlloc );
17+ COSEnvironment <EirHeapLinkAllocator> cosEnv( eir::constr_with_alloc::DEFAULT, &globalHeapAlloc );
96218
963- // Generate the COS syntax.
964- assert( lexer.CompileProduction( compiler, "S", "spaces [<0,e>statement, spaces]" ) == true );
965- {
966- struct program_dispatcher
967- {
968- inline Program* CreateNode( COSNode *first )
969- {
970- Program *node = new Program();
971- node->statements.AddToBack( first );
972- return node;
973- }
974-
975- static inline bool AssignNodeTo( Program *assign_to, const eir::FixedString <char>& attrib, COSNode *node )
976- {
977- assign_to->statements.AddToBack( node );
978- return true;
979- }
980- };
981- lexer.GetNamedProduction( "S" ).setSelector <mintwo_specialized_selector <char, Program, COSNode, program_dispatcher, decltype(lexer)::RuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
982- }
983- assert( lexer.CompileProduction( compiler, "statement", "typedef | block | loop | if | except | objmod | namespace | enum | multdecl | takefirst operation spaces ';'" ) == true );
984- assert( lexer.CompileProduction( compiler, "funcbody", "^(statement, <b> funcstatement)" ) == true );
985- assert( lexer.CompileProduction( compiler, "funcstatement", "\"return\" spaces (op:operation spaces)^0:1 ';'" ) == true );
986- {
987- struct return_dispatcher
988- {
989- static inline bool AssignNodeTo( ReturnStatement *assign_to, const eir::FixedString <char>& attrib, COSNode *node )
990- {
991- if ( attrib == "op" )
992- {
993- assign_to->op = node;
994- return true;
995- }
996- return false;
997- }
998- };
999- lexer.GetNamedProduction( "funcstatement" ).GetLastStep()->setSelector <direct_obj_build_selector <char, ReturnStatement, COSNode, return_dispatcher, decltype(lexer)::RuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
1000- }
1001- assert( lexer.CompileProduction( compiler, "optoksingle_epostfix", "\"->\" | \"<<\" | \">>\" | '+-*/%^&|!.=<>'" ) == true );
1002- assert( lexer.CompileProduction( compiler, "optoksingle", "'~' | optoksingle_epostfix" ) == true );
1003- assert( lexer.CompileProduction( compiler, "optoks", "\"&&\" | \"||\" | optoksingle_epostfix '=' | optoksingle" ) == true );
1004- assert( lexer.CompileProduction( compiler, "spec", "\"operator\" spaces optok:optoks" ) == true );
1005- {
1006- struct specifier_op_dispatcher
1007- {
1008- static inline void AssignAttributeTo( SpecifierOperator *assign_to, const eir::FixedString <char>& attrib, const eir::FixedString <char>& value )
1009- {
1010- if ( attrib != "optok" )
1011- return;
1012-
1013- typedef SpecifierOperator::eOpType eOpType;
1014-
1015- if ( value == "+" )
1016- {
1017- assign_to->op_type = eOpType::ADD;
1018- }
1019- else if ( value == "+=" )
1020- {
1021- assign_to->op_type = eOpType::ASSIGN_ADD;
1022- }
1023- else if ( value == "-" )
1024- {
1025- assign_to->op_type = eOpType::SUBTRACT;
1026- }
1027- else if ( value == "-=" )
1028- {
1029- assign_to->op_type = eOpType::ASSIGN_SUBTRACT;
1030- }
1031- else if ( value == "*" )
1032- {
1033- assign_to->op_type = eOpType::MULTIPLY;
1034- }
1035- else if ( value == "*=" )
1036- {
1037- assign_to->op_type = eOpType::ASSIGN_MULTIPLY;
1038- }
1039- else if ( value == "/" )
1040- {
1041- assign_to->op_type = eOpType::DIVIDE;
1042- }
1043- else if ( value == "/=" )
1044- {
1045- assign_to->op_type = eOpType::ASSIGN_DIVIDE;
1046- }
1047- else if ( value == "%" )
1048- {
1049- assign_to->op_type = eOpType::MODULUS;
1050- }
1051- else if ( value == "%=" )
1052- {
1053- assign_to->op_type = eOpType::ASSIGN_MODULUS;
1054- }
1055- else if ( value == "^" )
1056- {
1057- assign_to->op_type = eOpType::BIT_XOR;
1058- }
1059- else if ( value == "^=" )
1060- {
1061- assign_to->op_type = eOpType::ASSIGN_BIT_XOR;
1062- }
1063- else if ( value == "&" )
1064- {
1065- assign_to->op_type = eOpType::BIT_AND;
1066- }
1067- else if ( value == "&=" )
1068- {
1069- assign_to->op_type = eOpType::ASSIGN_BIT_AND;
1070- }
1071- else if ( value == "|" )
1072- {
1073- assign_to->op_type = eOpType::BIT_OR;
1074- }
1075- else if ( value == "|=" )
1076- {
1077- assign_to->op_type = eOpType::ASSIGN_BIT_OR;
1078- }
1079- else if ( value == "!" )
1080- {
1081- assign_to->op_type = eOpType::LOGICAL_NEGATE;
1082- }
1083- else if ( value == "!=" )
1084- {
1085- assign_to->op_type = eOpType::COMPARE_INEQUALITY;
1086- }
1087- else if ( value == "." )
1088- {
1089- assign_to->op_type = eOpType::DOT;
1090- }
1091- else if ( value == ".=" )
1092- {
1093- assign_to->op_type = eOpType::ASSIGN_DOT;
1094- }
1095- else if ( value == "->" )
1096- {
1097- assign_to->op_type = eOpType::ARROW;
1098- }
1099- else if ( value == "->=" )
1100- {
1101- assign_to->op_type = eOpType::ASSIGN_ARROW;
1102- }
1103- else if ( value == "=" )
1104- {
1105- assign_to->op_type = eOpType::ASSIGN;
1106- }
1107- else if ( value == "==" )
1108- {
1109- assign_to->op_type = eOpType::COMPARE_EQUALITY;
1110- }
1111- else if ( value == "~" )
1112- {
1113- assign_to->op_type = eOpType::BIT_NEGATE;
1114- }
1115- else if ( value == "<" )
1116- {
1117- assign_to->op_type = eOpType::COMPARE_LESS_THAN;
1118- }
1119- else if ( value == "<=" )
1120- {
1121- assign_to->op_type = eOpType::COMPARE_LESS_THAN_EQUAL;
1122- }
1123- else if ( value == ">" )
1124- {
1125- assign_to->op_type = eOpType::COMPARE_GREATER_THAN;
1126- }
1127- else if ( value == ">=" )
1128- {
1129- assign_to->op_type = eOpType::COMPARE_GREATER_THAN_EQUAL;
1130- }
1131- else if ( value == "&&" )
1132- {
1133- assign_to->op_type = eOpType::BIT_AND;
1134- }
1135- else if ( value == "||" )
1136- {
1137- assign_to->op_type = eOpType::BIT_OR;
1138- }
1139- else if ( value == "<<" )
1140- {
1141- assign_to->op_type = eOpType::BITSHIFT_LEFT;
1142- }
1143- else if ( value == "<<=" )
1144- {
1145- assign_to->op_type = eOpType::ASSIGN_BITSHIFT_LEFT;
1146- }
1147- else if ( value == ">>" )
1148- {
1149- assign_to->op_type = eOpType::BITSHIFT_RIGHT;
1150- }
1151- else if ( value == ">>=" )
1152- {
1153- assign_to->op_type = eOpType::ASSIGN_BITSHIFT_RIGHT;
1154- }
1155- }
1156- };
1157- lexer.GetNamedProduction( "spec" ).GetLastStep()->setSelector <direct_obj_build_selector <char, SpecifierOperator, COSNode, specifier_op_dispatcher, decltype(lexer)::RuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
1158- }
1159- assert( lexer.CompileProduction( compiler, "spec", "npath" ) == true );
1160- assert( lexer.CompileProduction( compiler, "spec", "\"$[\" spaces op:operation spaces ']'" ) == true );
1161- {
1162- struct dynspec_dispatcher
1163- {
1164- static inline bool AssignNodeTo( ResolveSpecifierOperation *assign_to, const eir::FixedString <char>& attrib, COSNode *node )
1165- {
1166- if ( attrib == "op" )
1167- {
1168- assign_to->op = node;
1169- return true;
1170- }
1171- return false;
1172- }
1173- };
1174- lexer.GetNamedProduction( "spec" ).GetLastStep()->setSelector <direct_obj_build_selector <char, ResolveSpecifierOperation, COSNode, dynspec_dispatcher, decltype(lexer)::RuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
1175- }
1176- assert( lexer.CompileProduction( compiler, "dtypedef", "takefirst \"typedef\" spaces tmultdecl spaces ';'" ) == true );
1177- assert( lexer.CompileProduction( compiler, "block", "'{' spaces [<0>statement:extended statement, spaces] spaces '}'" ) == true );
1178- assert( lexer.CompileProduction( compiler, "nblock", "'{' spaces [<0>statement:statement, spaces] spaces '}'" ) == true );
1179- {
1180- struct block_dispatcher
1181- {
1182- static inline bool AssignNodeTo( BlockStatement *assign_to, const eir::FixedString <char>& attrib, COSNode *node )
1183- {
1184- if ( attrib == "statement" )
1185- {
1186- assign_to->statements.AddToBack( node );
1187- return true;
1188- }
1189- return false;
1190- }
1191- };
1192- lexer.GetNamedProduction( "block" ).setSelector <direct_obj_build_selector <char, BlockStatement, COSNode, block_dispatcher, decltype(lexer)::RuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
1193- lexer.GetNamedProduction( "nblock" ).setSelector <direct_obj_build_selector <char, BlockStatement, COSNode, block_dispatcher, decltype(lexer)::RuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
1194- }
1195-
1196- // Create the special "operation" step.
1197- {
1198- auto operation = lexer.MakeStep <decltype(lexer)::RuntimeEnv::StepProceduralSequence> ();
1199-
1200- assert( lexer.CompileInto( compiler, operation, "[opitem:operation, spaces optype:('=' | \"+=\" | \"-=\" | \"*=\" | \"/=\" | \"%=\" | \"^=\" | \"&=\" | \"|=\" | \".=\" | \"->=\") spaces]" ) != nullptr );
1201- {
1202- struct assignment_dispatcher
1203- {
1204- enum class eOpType
1205- {
1206- UNSPECIFIED,
1207- ASSIGN,
1208- ASSIGN_ADD,
1209- ASSIGN_SUB,
1210- ASSIGN_MUL,
1211- ASSIGN_DIV,
1212- ASSIGN_MODULUS,
1213- ASSIGN_BIT_XOR,
1214- ASSIGN_BIT_AND,
1215- ASSIGN_BIT_OR,
1216- ASSIGN_DOT,
1217- ASSIGN_ARROW,
1218- ASSIGN_BITSHIFT_LEFT,
1219- ASSIGN_BITSHIFT_RIGHT
1220- };
1221-
1222- inline void AssignAttribute( const eir::FixedString <char>& attrib, const eir::FixedString <char>& value )
1223- {
1224- if ( attrib != "optype" )
1225- return;
1226-
1227- if ( value == "=" )
1228- {
1229- this->op_type = eOpType::ASSIGN;
1230- }
1231- else if ( value == "+=" )
1232- {
1233- this->op_type = eOpType::ASSIGN_ADD;
1234- }
1235- else if ( value == "-=" )
1236- {
1237- this->op_type = eOpType::ASSIGN_SUB;
1238- }
1239- else if ( value == "*=" )
1240- {
1241- this->op_type = eOpType::ASSIGN_MUL;
1242- }
1243- else if ( value == "/=" )
1244- {
1245- this->op_type = eOpType::ASSIGN_DIV;
1246- }
1247- else if ( value == "%=" )
1248- {
1249- this->op_type = eOpType::ASSIGN_MODULUS;
1250- }
1251- else if ( value == "^=" )
1252- {
1253- this->op_type = eOpType::ASSIGN_BIT_XOR;
1254- }
1255- else if ( value == "&=" )
1256- {
1257- this->op_type = eOpType::ASSIGN_BIT_AND;
1258- }
1259- else if ( value == "|=" )
1260- {
1261- this->op_type = eOpType::ASSIGN_BIT_OR;
1262- }
1263- else if ( value == ".=" )
1264- {
1265- this->op_type = eOpType::ASSIGN_DOT;
1266- }
1267- else if ( value == "->=" )
1268- {
1269- this->op_type = eOpType::ASSIGN_ARROW;
1270- }
1271- else if ( value == "<<=" )
1272- {
1273- this->op_type = eOpType::ASSIGN_BITSHIFT_LEFT;
1274- }
1275- else if ( value == ">>=" )
1276- {
1277- this->op_type = eOpType::ASSIGN_BITSHIFT_RIGHT;
1278- }
1279- }
1280-
1281- inline COSNode* CreateOperation( COSNode *left, COSNode *right ) const
1282- {
1283- eOpType op_type = this->op_type;
1284-
1285- if ( op_type == eOpType::ASSIGN )
1286- {
1287- return new AssignmentOperation( left, right );
1288- }
1289- else if ( op_type == eOpType::ASSIGN_ADD )
1290- {
1291- return new AssignAddOperation( left, right );
1292- }
1293- else if ( op_type == eOpType::ASSIGN_SUB )
1294- {
1295- return new AssignSubOperation( left, right );
1296- }
1297- else if ( op_type == eOpType::ASSIGN_MUL )
1298- {
1299- return new AssignMulOperation( left, right );
1300- }
1301- else if ( op_type == eOpType::ASSIGN_DIV )
1302- {
1303- return new AssignDivOperation( left, right );
1304- }
1305- else if ( op_type == eOpType::ASSIGN_MODULUS )
1306- {
1307- return new AssignModulusOperation( left, right );
1308- }
1309- else if ( op_type == eOpType::ASSIGN_BIT_XOR )
1310- {
1311- return new AssignBitwiseXorOperation( left, right );
1312- }
1313- else if ( op_type == eOpType::ASSIGN_BIT_AND )
1314- {
1315- return new AssignBitwiseAndOperation( left, right );
1316- }
1317- else if ( op_type == eOpType::ASSIGN_BIT_OR )
1318- {
1319- return new AssignBitwiseOrOperation( left, right );
1320- }
1321- else if ( op_type == eOpType::ASSIGN_DOT )
1322- {
1323- return new AssignDotOperation( left, right );
1324- }
1325- else if ( op_type == eOpType::ASSIGN_ARROW )
1326- {
1327- return new AssignArrowOperation( left, right );
1328- }
1329- else if ( op_type == eOpType::ASSIGN_BITSHIFT_LEFT )
1330- {
1331- return new AssignBitshiftLeftOperation( left, right );
1332- }
1333- else if ( op_type == eOpType::ASSIGN_BITSHIFT_RIGHT )
1334- {
1335- return new AssignBitshiftRightOperation( left, right );
1336- }
1337-
1338- throw lexing_invalid_parameter_exception();
1339- }
1340-
1341- eOpType op_type = eOpType::UNSPECIFIED;
1342- };
1343- operation.GetLastStep()->setSelector <right_associative_selector <char, COSNode, assignment_dispatcher, decltype(lexer)::RuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
1344- }
1345- assert( lexer.CompileInto( compiler, operation, "[opitem:operation, spaces optype:\"||\" spaces]" ) != nullptr );
1346- {
1347- struct logical_or_dispatcher
1348- {
1349- inline void AssignAttribute( const eir::FixedString <char>& attrib, const eir::FixedString <char>& value )
1350- {
1351- return;
1352- }
1353-
1354- inline COSNode* CreateOperation( COSNode *left, COSNode *right )
1355- {
1356- return new LogicalOrOperation( left, right );
1357- }
1358- };
1359- operation.GetLastStep()->setSelector <left_associative_selector <char, COSNode, logical_or_dispatcher, decltype(lexer)::RuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
1360- }
1361- assert( lexer.CompileInto( compiler, operation, "[opitem:operation, spaces optype:\"&&\" spaces]" ) != nullptr );
1362- {
1363- struct logical_and_dispatcher
1364- {
1365- inline void AssignAttribute( const eir::FixedString <char>& attrib, const eir::FixedString <char>& value )
1366- {
1367- return;
1368- }
1369-
1370- inline COSNode* CreateOperation( COSNode *left, COSNode *right )
1371- {
1372- return new LogicalAndOperation( left, right );
1373- }
1374- };
1375- operation.GetLastStep()->setSelector <left_associative_selector <char, COSNode, logical_and_dispatcher, decltype(lexer)::RuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
1376- }
1377- assert( lexer.CompileInto( compiler, operation, "[opitem:operation, spaces optype:'|' spaces]" ) != nullptr );
1378- {
1379- struct bor_dispatcher
1380- {
1381- inline void AssignAttribute( const eir::FixedString <char>& attrib, const eir::FixedString <char>& value )
1382- {
1383- return;
1384- }
1385-
1386- inline COSNode* CreateOperation( COSNode *left, COSNode *right )
1387- {
1388- return new BitwiseOrOperation( left, right );
1389- }
1390- };
1391- operation.GetLastStep()->setSelector <left_associative_selector <char, COSNode, bor_dispatcher, decltype(lexer)::RuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
1392- }
1393- assert( lexer.CompileInto( compiler, operation, "[opitem:operation, spaces optype:'^' spaces]" ) != nullptr );
1394- {
1395- struct bxor_dispatcher
1396- {
1397- inline void AssignAttribute( const eir::FixedString <char>& attrib, const eir::FixedString <char>& value )
1398- {
1399- return;
1400- }
1401-
1402- inline COSNode* CreateOperation( COSNode *left, COSNode *right )
1403- {
1404- return new BitwiseXorOperation( left, right );
1405- }
1406- };
1407- operation.GetLastStep()->setSelector <left_associative_selector <char, COSNode, bxor_dispatcher, decltype(lexer)::RuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
1408- }
1409- assert( lexer.CompileInto( compiler, operation, "[opitem:operation, spaces optype:('&'^1:2) spaces]" ) != nullptr );
1410- {
1411- struct band_dispatcher
1412- {
1413- inline void AssignAttribute( const eir::FixedString <char>& attrib, const eir::FixedString <char>& value )
1414- {
1415- if ( attrib == "optype" )
1416- {
1417- if ( value == "&&" )
1418- {
1419- // This is important because a double-ampersand can never be a bitwise-and.
1420- throw lexing_invalid_parameter_exception();
1421- }
1422- }
1423- }
1424-
1425- inline COSNode* CreateOperation( COSNode *left, COSNode *right )
1426- {
1427- return new BitwiseAndOperation( left, right );
1428- }
1429- };
1430- operation.GetLastStep()->setSelector <left_associative_selector <char, COSNode, band_dispatcher, decltype(lexer)::RuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
1431- }
1432- assert( lexer.CompileInto( compiler, operation, "[opitem:operation, spaces optype:(\"==\" | \"!=\" | \"<=\" | \">=\" | '<' | '>') spaces]" ) != nullptr );
1433- {
1434- struct logical_comparison_dispatcher
1435- {
1436- enum class eCompType
1437- {
1438- UNDEFINED,
1439- EQUALITY,
1440- INEQUALITY,
1441- LESS_THAN,
1442- GREATER_THAN,
1443- LESS_EQUAL_THAN,
1444- GREATER_EQUAL_THAN
1445- };
1446-
1447- inline void AssignAttribute( const eir::FixedString <char>& attrib, const eir::FixedString <char>& value )
1448- {
1449- if ( attrib == "optype" )
1450- {
1451- if ( value == "==" )
1452- {
1453- this->comp_type = eCompType::EQUALITY;
1454- }
1455- else if ( value == "!=" )
1456- {
1457- this->comp_type = eCompType::INEQUALITY;
1458- }
1459- else if ( value == "<" )
1460- {
1461- this->comp_type = eCompType::LESS_THAN;
1462- }
1463- else if ( value == ">" )
1464- {
1465- this->comp_type = eCompType::GREATER_THAN;
1466- }
1467- else if ( value == "<=" )
1468- {
1469- this->comp_type = eCompType::LESS_EQUAL_THAN;
1470- }
1471- else if ( value == ">=" )
1472- {
1473- this->comp_type = eCompType::GREATER_EQUAL_THAN;
1474- }
1475- }
1476- }
1477-
1478- inline COSNode* CreateOperation( COSNode *left, COSNode *right )
1479- {
1480- eCompType comp_type = this->comp_type;
1481-
1482- if ( comp_type == eCompType::EQUALITY )
1483- {
1484- return new CompareEqualityOperation( left, right );
1485- }
1486- else if ( comp_type == eCompType::INEQUALITY )
1487- {
1488- return new CompareInequalityOperation( left, right );
1489- }
1490- else if ( comp_type == eCompType::LESS_THAN )
1491- {
1492- return new CompareLessThanOperation( left, right );
1493- }
1494- else if ( comp_type == eCompType::GREATER_THAN )
1495- {
1496- return new CompareGreaterThanOperation( left, right );
1497- }
1498- else if ( comp_type == eCompType::LESS_EQUAL_THAN )
1499- {
1500- return new CompareLessThanEqualOperation( left, right );
1501- }
1502- else if ( comp_type == eCompType::GREATER_EQUAL_THAN )
1503- {
1504- return new CompareGreaterThanEqualOperation( left, right );
1505- }
1506- else
1507- {
1508- throw lexing_invalid_parameter_exception();
1509- }
1510- }
1511-
1512- eCompType comp_type = eCompType::UNDEFINED;
1513- };
1514- operation.GetLastStep()->setSelector <left_associative_selector <char, COSNode, logical_comparison_dispatcher, decltype(lexer)::RuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
1515- }
1516- assert( lexer.CompileInto( compiler, operation, "[opitem:operation, spaces optype:(\"<<\"|\">>\") spaces]" ) != nullptr );
1517- {
1518- struct bitwise_shift_dispatcher
1519- {
1520- enum class eOpType
1521- {
1522- UNDEFINED,
1523- LEFT_SHIFT,
1524- RIGHT_SHIFT
1525- };
1526-
1527- inline void AssignAttribute( const eir::FixedString <char>& attrib, const eir::FixedString <char>& value )
1528- {
1529- if ( attrib == "optype" )
1530- {
1531- if ( value == "<<" )
1532- {
1533- this->op_type = eOpType::LEFT_SHIFT;
1534- }
1535- else if ( value == ">>" )
1536- {
1537- this->op_type = eOpType::RIGHT_SHIFT;
1538- }
1539- }
1540- }
1541-
1542- inline COSNode* CreateOperation( COSNode *left, COSNode *right )
1543- {
1544- eOpType op_type = this->op_type;
1545-
1546- if ( op_type == eOpType::LEFT_SHIFT )
1547- {
1548- return new BitshiftLeftOperation( left, right );
1549- }
1550- else if ( op_type == eOpType::RIGHT_SHIFT )
1551- {
1552- return new BitshiftRightOperation( left, right );
1553- }
1554-
1555- throw lexing_invalid_parameter_exception();
1556- }
1557-
1558- eOpType op_type = eOpType::UNDEFINED;
1559- };
1560- operation.GetLastStep()->setSelector <left_associative_selector <char, COSNode, bitwise_shift_dispatcher, decltype(lexer)::RuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
1561- }
1562- assert( lexer.CompileInto( compiler, operation, "[opitem:operation, spaces optype:('-'|'+') spaces]" ) != nullptr );
1563- {
1564- struct summation_dispatcher
1565- {
1566- enum class eOpType
1567- {
1568- UNDEFINED,
1569- ADDITION,
1570- SUBTRACTION
1571- };
1572-
1573- inline void AssignAttribute( const eir::FixedString <char>& attrib, const eir::FixedString <char>& value )
1574- {
1575- if ( attrib == "optype" )
1576- {
1577- if ( value == "+" )
1578- {
1579- this->op_type = eOpType::ADDITION;
1580- }
1581- else if ( value == "-" )
1582- {
1583- this->op_type = eOpType::SUBTRACTION;
1584- }
1585- }
1586- }
1587-
1588- inline COSNode* CreateOperation( COSNode *left, COSNode *right )
1589- {
1590- eOpType op_type = this->op_type;
1591-
1592- if ( op_type == eOpType::ADDITION )
1593- {
1594- return new AddOperation( left, right );
1595- }
1596- else if ( op_type == eOpType::SUBTRACTION )
1597- {
1598- return new SubOperation( left, right );
1599- }
1600-
1601- throw lexing_invalid_parameter_exception();
1602- }
1603-
1604- eOpType op_type = eOpType::UNDEFINED;
1605- };
1606- operation.GetLastStep()->setSelector <left_associative_selector <char, COSNode, summation_dispatcher, decltype(lexer)::RuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
1607- }
1608- assert( lexer.CompileInto( compiler, operation, "[opitem:operation, spaces optype:('*'|'/'|'%') spaces]" ) != nullptr );
1609- {
1610- struct muldiv_dispatcher
1611- {
1612- enum class eOpType
1613- {
1614- UNDEFINED,
1615- MULTIPLY,
1616- DIVIDE,
1617- MODULUS
1618- };
1619-
1620- inline void AssignAttribute( const eir::FixedString <char>& attrib, const eir::FixedString <char>& value )
1621- {
1622- if ( attrib == "optype" )
1623- {
1624- if ( value == "*" )
1625- {
1626- this->op_type = eOpType::MULTIPLY;
1627- }
1628- else if ( value == "/" )
1629- {
1630- this->op_type = eOpType::DIVIDE;
1631- }
1632- else if ( value == "%" )
1633- {
1634- this->op_type = eOpType::MODULUS;
1635- }
1636- }
1637- }
1638-
1639- inline COSNode* CreateOperation( COSNode *left, COSNode *right )
1640- {
1641- eOpType op_type = this->op_type;
1642-
1643- if ( op_type == eOpType::MULTIPLY )
1644- {
1645- return new MulOperation( left, right );
1646- }
1647- else if ( op_type == eOpType::DIVIDE )
1648- {
1649- return new DivOperation( left, right );
1650- }
1651- else if ( op_type == eOpType::MODULUS )
1652- {
1653- return new ModulusOperation( left, right );
1654- }
1655-
1656- throw lexing_invalid_parameter_exception();
1657- }
1658-
1659- eOpType op_type = eOpType::UNDEFINED;
1660- };
1661- operation.GetLastStep()->setSelector <left_associative_selector <char, COSNode, muldiv_dispatcher, decltype(lexer)::RuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
1662- }
1663- assert( lexer.CompileInto( compiler, operation, "[<0,e>pre_optype:(\"++\" | \"--\"), spaces] opitem:operation [<0,e> spaces, post_optype:(\"++\" | \"--\")]" ) != nullptr );
1664- {
1665- struct quickunamod_dispatcher
1666- {
1667- enum class eOpType
1668- {
1669- UNDEFINED,
1670- PRE_INCREMENT,
1671- PRE_DECREMENT,
1672- POST_INCREMENT,
1673- POST_DECREMENT
1674- };
1675-
1676- inline void AssignAttribute( const eir::FixedString <char>& attrib, const eir::FixedString <char>& value )
1677- {
1678- if ( attrib == "pre_optype" )
1679- {
1680- if ( value == "++" )
1681- {
1682- this->op_type = eOpType::PRE_INCREMENT;
1683- }
1684- else if ( value == "--" )
1685- {
1686- this->op_type = eOpType::PRE_DECREMENT;
1687- }
1688- }
1689- else if ( attrib == "post_optype" )
1690- {
1691- if ( value == "++" )
1692- {
1693- this->op_type = eOpType::POST_INCREMENT;
1694- }
1695- else if ( value == "--" )
1696- {
1697- this->op_type = eOpType::POST_DECREMENT;
1698- }
1699- }
1700- }
1701-
1702- inline COSNode* CreateOperation( COSNode *op )
1703- {
1704- eOpType op_type = this->op_type;
1705-
1706- if ( op_type == eOpType::PRE_INCREMENT )
1707- {
1708- return new PreIncrementOperation( op );
1709- }
1710- else if ( op_type == eOpType::PRE_DECREMENT )
1711- {
1712- return new PreDecrementOperation( op );
1713- }
1714- else if ( op_type == eOpType::POST_INCREMENT )
1715- {
1716- return new PostIncrementOperation( op );
1717- }
1718- else if ( op_type == eOpType::POST_DECREMENT )
1719- {
1720- return new PostDecrementOperation( op );
1721- }
1722-
1723- throw lexing_invalid_parameter_exception();
1724- }
1725-
1726- eOpType op_type = eOpType::UNDEFINED;
1727- };
1728- operation.GetLastStep()->setSelector <unary_operation_selector <char, COSNode, quickunamod_dispatcher, decltype(lexer)::RuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
1729- }
1730- assert( lexer.CompileInto( compiler, operation, "[<0,e>optype:'-~!*&', spaces] opitem:operation" ) != nullptr );
1731- {
1732- struct unary_negation_dispatcher
1733- {
1734- enum class eOpType
1735- {
1736- UNDEFINED,
1737- NUMERIC_NEGATION,
1738- BITWISE_NEGATION,
1739- LOGICAL_NEGATION,
1740- PTR_RESOLVE,
1741- ADDRESS_OF
1742- };
1743-
1744- inline void AssignAttribute( const eir::FixedString <char>& attrib, const eir::FixedString <char>& value )
1745- {
1746- if ( attrib == "optype" )
1747- {
1748- if ( value == "-" )
1749- {
1750- this->op_type = eOpType::NUMERIC_NEGATION;
1751- }
1752- else if ( value == "~" )
1753- {
1754- this->op_type = eOpType::BITWISE_NEGATION;
1755- }
1756- else if ( value == "!" )
1757- {
1758- this->op_type = eOpType::LOGICAL_NEGATION;
1759- }
1760- else if ( value == "*" )
1761- {
1762- this->op_type = eOpType::PTR_RESOLVE;
1763- }
1764- else if ( value == "&" )
1765- {
1766- this->op_type = eOpType::ADDRESS_OF;
1767- }
1768- }
1769- }
1770-
1771- inline COSNode* CreateOperation( COSNode *op )
1772- {
1773- eOpType op_type = this->op_type;
1774-
1775- if ( op_type == eOpType::NUMERIC_NEGATION )
1776- {
1777- return new NumericNegationOperation( op );
1778- }
1779- else if ( op_type == eOpType::BITWISE_NEGATION )
1780- {
1781- return new BitwiseNegationOperation( op );
1782- }
1783- else if ( op_type == eOpType::LOGICAL_NEGATION )
1784- {
1785- return new LogicalNegationOperation( op );
1786- }
1787- else if ( op_type == eOpType::PTR_RESOLVE )
1788- {
1789- return new PointerResolveOperation( op );
1790- }
1791- else if ( op_type == eOpType::ADDRESS_OF )
1792- {
1793- return new AddressOfOperation( op );
1794- }
1795-
1796- throw lexing_invalid_parameter_exception();
1797- }
1798-
1799- eOpType op_type = eOpType::UNDEFINED;
1800- };
1801- operation.GetLastStep()->setSelector <unary_operation_selector <char, COSNode, unary_negation_dispatcher, decltype(lexer)::RuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
1802- }
1803- assert( lexer.CompileInto( compiler, operation, "tocall:operation (spaces [begcall:'(' spaces [<0>param:procgate operation, spaces ',' spaces] spaces endcall:')', spaces])^0:1" ) != nullptr );
1804- {
1805- struct call_selector
1806- {
1807- inline call_selector( decltype(lexer)::RuntimeEnv *env ) noexcept : env( env )
1808- {
1809- return;
1810- }
1811- inline call_selector( const call_selector& right )
1812- : env( right.env ), root( right.root ), call_params( right.call_params ), is_call( right.is_call )
1813- {
1814- auto *env = this->env;
1815-
1816- if ( COSNode *root = this->root )
1817- {
1818- env->lifetimeMan.AddRef( root );
1819- }
1820-
1821- for ( COSNode *n : this->call_params )
1822- {
1823- env->lifetimeMan.AddRef( n );
1824- }
1825- }
1826- inline call_selector( call_selector&& right ) noexcept
1827- : env( right.env ), call_params( std::move( right.call_params ) ), is_call( right.is_call )
1828- {
1829- this->root = right.root;
1830-
1831- right.root = nullptr;
1832- }
1833- inline ~call_selector( void )
1834- {
1835- auto *env = this->env;
1836-
1837- if ( COSNode *root = this->root )
1838- {
1839- env->lifetimeMan.RemRef( root );
1840- }
1841-
1842- for ( COSNode *n : this->call_params )
1843- {
1844- env->lifetimeMan.RemRef( n );
1845- }
1846- }
1847-
1848- inline COSNode* DetachFinishedNode( void )
1849- {
1850- COSNode *result = this->root;
1851-
1852- if ( result )
1853- {
1854- this->env->lifetimeMan.RemRef( result );
1855- }
1856-
1857- this->root = nullptr;
1858-
1859- return result;
1860- }
1861-
1862- inline void AssignAttribute( const eir::FixedString <char>& attrib, const eir::FixedString <char>& value )
1863- {
1864- if ( attrib == "begcall" )
1865- {
1866- this->is_call = true;
1867- }
1868- else if ( attrib == "endcall" )
1869- {
1870- this->is_call = false;
1871-
1872- auto *env = this->env;
1873-
1874- COSNode *cur_node = this->root;
1875-
1876- if ( cur_node )
1877- {
1878- env->lifetimeMan.RemRef( cur_node );
1879- }
1880-
1881- cur_node = new FunctionCallOperation( cur_node, std::move( this->call_params ) );
1882-
1883- env->lifetimeMan.AddRef( cur_node );
1884-
1885- this->root = cur_node;
1886- }
1887- }
1888-
1889- inline bool AssignNode( const eir::FixedString <char>& attrib, COSNode *node )
1890- {
1891- if ( attrib == "param" )
1892- {
1893- this->call_params.AddToBack( node );
1894- goto success;
1895- }
1896- else if ( attrib == "tocall" )
1897- {
1898- this->root = node;
1899- goto success;
1900- }
1901-
1902- return false;
1903-
1904- success:
1905- this->env->lifetimeMan.AddRef( node );
1906- return true;
1907- }
1908-
1909- decltype(lexer)::RuntimeEnv *env;
1910- COSNode *root = nullptr;
1911- depVector <COSNode*> call_params;
1912- bool is_call = false;
1913- };
1914- operation.GetLastStep()->setSelector <call_selector> ( &lexer.GetRuntimeEnvironment() );
1915- }
1916- assert( lexer.CompileInto( compiler, operation, "base:operation (spaces ['[' spaces key:procgate operation spaces ']', spaces])^0:1" ) != nullptr );
1917- {
1918- struct key_dispatcher
1919- {
1920- inline void AssignAttribute( const eir::FixedString <char>& attrib, const eir::FixedString <char>& value )
1921- {
1922- return;
1923- }
1924-
1925- inline COSNode* CreateOperation( COSNode *left, COSNode *right )
1926- {
1927- return new EdgeBracketsOperation( left, right );
1928- }
1929- };
1930- operation.GetLastStep()->setSelector <left_associative_selector <char, COSNode, key_dispatcher, decltype(lexer)::RuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
1931- }
1932- assert( lexer.CompileInto( compiler, operation, "op:operation (spaces '{' spaces [<0> item:procgate operation, spaces ',' spaces] spaces endarrtok:'}')^0:1" ) != nullptr );
1933- {
1934- struct arrayinit_selector
1935- {
1936- inline void AssignAttribute( const eir::FixedString <char>& attrib, const eir::FixedString <char>& value )
1937- {
1938- if ( attrib == "endarrtok" )
1939- {
1940- this->root = new ArrayInitOperation( this->root, std::move( this->items ) );
1941- }
1942- }
1943-
1944- inline bool AssignNode( const eir::FixedString <char>& attrib, COSNode *node )
1945- {
1946- if ( attrib == "op" )
1947- {
1948- this->root = node;
1949- return true;
1950- }
1951- if ( attrib == "item" )
1952- {
1953- this->items.AddToBack( node );
1954- return true;
1955- }
1956-
1957- return false;
1958- }
1959-
1960- inline COSNode* DetachFinishedNode( void ) noexcept
1961- {
1962- COSNode *result = this->root;
1963-
1964- this->root = nullptr;
1965-
1966- return result;
1967- }
1968-
1969- COSNode *root = nullptr;
1970- depVector <COSNode*> items;
1971- };
1972- operation.GetLastStep()->setSelector <arrayinit_selector> ();
1973- }
1974- assert( lexer.CompileInto( compiler, operation, "&(npgate templinst_templ, itemtempl=operation)" ) != nullptr );
1975-
1976- auto tailop = lexer.MakeStep <decltype(lexer)::RuntimeEnv::StepAlternatives> ();
1977-
1978- assert( lexer.CompileInto( compiler, tailop, "\"new\" spaces type:spec spaces (curlypack)^0:1" ) != nullptr );
1979- {
1980- struct new_dispatcher
1981- {
1982- static inline bool AssignNodeTo( NewOperation *assign_to, const eir::FixedString <char>& attrib, COSNode *node )
1983- {
1984- if ( attrib == "type" )
1985- {
1986- assign_to->type = node;
1987- return true;
1988- }
1989- else if ( attrib == "param" )
1990- {
1991- assign_to->params.AddToBack( node );
1992- return true;
1993- }
1994-
1995- return false;
1996- }
1997- };
1998- tailop.GetLastStep()->setSelector <direct_obj_build_selector <char, NewOperation, COSNode, new_dispatcher, decltype(lexer)::RuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
1999- }
2000- assert( lexer.CompileInto( compiler, tailop, "\"cast\" spaces '<' spaces totype:type spaces '>' spaces '(' spaces castobj:procgate operation spaces ')'" ) != nullptr );
2001- {
2002- struct cast_dispatcher
2003- {
2004- static inline bool AssignNodeTo( CastOperation *assign_to, const eir::FixedString <char>& attrib, COSNode *node )
2005- {
2006- if ( attrib == "totype" )
2007- {
2008- assign_to->totype = node;
2009- return true;
2010- }
2011- if ( attrib == "castobj" )
2012- {
2013- assign_to->castobj = node;
2014- return true;
2015- }
2016-
2017- return false;
2018- }
2019- };
2020- tailop.GetLastStep()->setSelector <direct_obj_build_selector <char, CastOperation, COSNode, cast_dispatcher, decltype(lexer)::RuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
2021- }
2022- assert( lexer.CompileInto( compiler, tailop, "name" ) != nullptr );
2023- assert( lexer.CompileInto( compiler, tailop, "number" ) != nullptr );
2024- assert( lexer.CompileInto( compiler, tailop, "'{' spaces [item:procgate operation, spaces ',' spaces] spaces '}'" ) != nullptr );
2025- {
2026- struct array_dispatcher
2027- {
2028- static inline bool AssignNodeTo( ArrayDefinition *assign_to, const eir::FixedString <char>& attrib, COSNode *node )
2029- {
2030- if ( attrib == "item" )
2031- {
2032- assign_to->items.AddToBack( node );
2033- return true;
2034- }
2035- return false;
2036- }
2037- };
2038- tailop.GetLastStep()->setSelector <direct_obj_build_selector <char, ArrayDefinition, COSNode, array_dispatcher, decltype(lexer)::RuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
2039- }
2040- // Not ideal for again serializing into text, but we should be automatically detecting such a case anyway due to a fixed
2041- // operational binding strength.
2042- assert( lexer.CompileInto( compiler, tailop, "'(' spaces procgate operation spaces ')'" ) != nullptr );
2043-
2044- lexer.AddStepInto( operation, std::move( tailop ) );
2045-
2046- lexer.AddStep( "operation", std::move( operation ) );
2047-
2048- // We know that "operation" will never recurse infinitely, so make sure the runtime respects this.
2049- // This is important because the halting-problem cannot be efficiently solved in distinct space,
2050- // but we can create grammar rules that will always halt, if proven on paper.
2051- lexer.GetNamedProduction( "operation" ).disable_empty_recursion_protection = true;
2052- }
2053-
2054- lexer.AddProgrammableTokenStep( "name",
2055- []( decltype(lexer)::RuntimeEnv::LexingPoint& pt ) -> std::optional <eir::FixedString <char>>
2056- {
2057- const char *startdata = pt.GetCurrentData();
2058- size_t startoff = pt.GetOffset();
2059-
2060- bool first_char = true;
2061-
2062- while ( pt.GetRemainder() > 0 )
2063- {
2064- size_t oldoff = pt.GetOffset();
2065-
2066- auto ucp = pt.ReadCharacter();
2067-
2068- bool validchar;
2069-
2070- if ( first_char )
2071- {
2072- validchar = is_name_alpha( ucp );
2073- first_char = false;
2074- }
2075- else
2076- {
2077- validchar = is_name_char( ucp );
2078- }
2079-
2080- if ( validchar == false )
2081- {
2082- pt.SetOffset( oldoff );
2083- break;
2084- }
2085- }
2086-
2087- size_t cplen = ( pt.GetOffset() - startoff );
2088-
2089- if ( cplen == 0 )
2090- return std::nullopt;
2091-
2092- return eir::FixedString( startdata, cplen );
2093- }
2094- );
2095- {
2096- struct name_dispatcher
2097- {
2098- static inline void AssignAttributeTo( SpecifierString *assign_to, const eir::FixedString <char>& attrib, const eir::FixedString <char>& value )
2099- {
2100- if ( attrib == "str" )
2101- {
2102- assign_to->string = value;
2103- }
2104- }
2105- };
2106- auto& nameprod = lexer.GetNamedProduction( "name" );
2107- nameprod.attribute_key = "str";
2108- nameprod.setSelector <direct_obj_build_selector <char, SpecifierString, COSNode, name_dispatcher, decltype(lexer)::RuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
2109- }
2110- lexer.AddProgrammableTokenStep( "number",
2111- []( decltype(lexer)::RuntimeEnv::LexingPoint& pt ) -> std::optional <eir::FixedString <char>>
2112- {
2113- const char *startdata = pt.GetCurrentData();
2114- size_t startoff = pt.GetOffset();
2115-
2116- bool first_char = true;
2117-
2118- while ( pt.GetRemainder() > 0 )
2119- {
2120- size_t oldoff = pt.GetOffset();
2121-
2122- auto ucp = pt.ReadCharacter();
2123-
2124- bool validchar = is_num( ucp );
2125-
2126- if ( validchar == false )
2127- {
2128- pt.SetOffset( oldoff );
2129- break;
2130- }
2131- }
2132-
2133- size_t cplen = ( pt.GetOffset() - startoff );
2134-
2135- if ( cplen == 0 )
2136- return std::nullopt;
2137-
2138- return eir::FixedString( startdata, cplen );
2139- }
2140- );
2141- {
2142- struct numeric_dispatcher
2143- {
2144- static inline void AssignAttributeTo( NumberString *assign_to, const eir::FixedString <char>& attrib, const eir::FixedString <char>& value )
2145- {
2146- if ( attrib == "str" )
2147- {
2148- assign_to->numeric_string = value;
2149- }
2150- }
2151- };
2152- auto& numprod = lexer.GetNamedProduction( "number" );
2153- numprod.attribute_key = "str";
2154- numprod.setSelector <direct_obj_build_selector <char, NumberString, COSNode, numeric_dispatcher, decltype(lexer)::RuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
2155- }
2156- lexer.AddProgrammableTokenStep( "spaces",
2157- []( decltype(lexer)::RuntimeEnv::LexingPoint& pt )
2158- {
2159- size_t resetoff = pt.GetOffset();
2160-
2161- while ( pt.GetRemainder() > 0 )
2162- {
2163- char ucp = pt.ReadCharacter();
2164-
2165- if ( is_space_char( ucp ) == false )
2166- {
2167- pt.SetOffset( resetoff );
2168- break;
2169- }
2170-
2171- resetoff++;
2172- }
2173-
2174- return eir::FixedString <char> ();
2175- }
2176- );
2177-
2178- assert( lexer.CompileProduction( compiler, "whileloop", "\"while\" spaces '(' spaces cond:operation spaces ')' spaces body:loopbody" ) == true );
2179- {
2180- struct while_dispatcher
2181- {
2182- static inline bool AssignNodeTo( WhileLoopStatement *assign_to, const eir::FixedString <char>& attrib, COSNode *node )
2183- {
2184- if ( attrib == "cond" )
2185- {
2186- assign_to->condition = node;
2187- }
2188- else if ( attrib == "body" )
2189- {
2190- assign_to->exec = node;
2191- }
2192- return false;
2193- }
2194- };
2195- lexer.GetNamedProduction( "whileloop" ).setSelector <direct_obj_build_selector <char, WhileLoopStatement, COSNode, while_dispatcher, decltype(lexer)::RuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
2196- }
2197- assert( lexer.CompileProduction( compiler, "loopbody", "^(extended statement, <b> loopstatement)" ) == true );
2198- assert( lexer.CompileProduction( compiler, "loopstatement", "\"break\" spaces ';'" ) == true );
2199- {
2200- lexer.GetNamedProduction( "loopstatement" ).GetLastStep()->setConstructor(
2201- []
2202- {
2203- return new BreakStatement();
2204- }
2205- );
2206- }
2207- assert( lexer.CompileProduction( compiler, "loopstatement", "\"continue\" spaces ';'" ) == true );
2208- {
2209- lexer.GetNamedProduction( "loopstatement" ).GetLastStep()->setConstructor(
2210- []
2211- {
2212- return new ContinueStatement();
2213- }
2214- );
2215- }
2216- assert( lexer.CompileProduction( compiler, "if", "\"if\" spaces '(' spaces cond:operation spaces ')' spaces true_branch:extended statement (spaces \"else\" spaces false_branch:extended statement)^0:1" ) == true );
2217- {
2218- struct if_dispatcher
2219- {
2220- static inline bool AssignNodeTo( IfStatement *assign_to, const eir::FixedString <char>& attrib, COSNode *node )
2221- {
2222- if ( attrib == "cond" )
2223- {
2224- assign_to->condition = node;
2225- return true;
2226- }
2227- else if ( attrib == "true_branch" )
2228- {
2229- assign_to->true_branch = node;
2230- return true;
2231- }
2232- else if ( attrib == "false_branch" )
2233- {
2234- assign_to->false_branch = node;
2235- return true;
2236- }
2237-
2238- return false;
2239- }
2240- };
2241- lexer.GetNamedProduction( "if" ).setSelector <direct_obj_build_selector <char, IfStatement, COSNode, if_dispatcher, decltype(lexer)::RuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
2242- }
2243- assert( lexer.CompileProduction( compiler, "except", "\"throw\" spaces (op:operation spaces)^0:1 ';'" ) == true );
2244- {
2245- struct throw_dispatcher
2246- {
2247- static inline bool AssignNodeTo( ThrowStatement *assign_to, const eir::FixedString <char>& attrib, COSNode *node )
2248- {
2249- if ( attrib == "op" )
2250- {
2251- assign_to->op = node;
2252- return true;
2253- }
2254- return false;
2255- }
2256- };
2257- lexer.GetNamedProduction( "except" ).GetLastStep()->setSelector <direct_obj_build_selector <char, ThrowStatement, COSNode, throw_dispatcher, decltype(lexer)::RuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
2258- }
2259- assert( lexer.CompileProduction( compiler, "catch", "\"catch\" spaces '(' spaces (caught_decl:decl_optnoinit spaces)^0:1 ')' spaces catch_body:extended statement" ) == true );
2260- {
2261- struct catch_dispatcher
2262- {
2263- static inline bool AssignNodeTo( CatchStatement *assign_to, const eir::FixedString <char>& attrib, COSNode *node )
2264- {
2265- if ( attrib == "caught_decl" )
2266- {
2267- assign_to->caught_decl = node;
2268- return true;
2269- }
2270- else if ( attrib == "catch_body" )
2271- {
2272- assign_to->catch_body = node;
2273- return true;
2274- }
2275- return false;
2276- }
2277- };
2278- lexer.GetNamedProduction( "catch" ).setSelector <direct_obj_build_selector <char, CatchStatement, COSNode, catch_dispatcher, decltype(lexer)::RuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
2279- }
2280- assert( lexer.CompileProduction( compiler, "except", "\"try\" spaces try_body:extended statement spaces [error:catch, spaces]" ) == true );
2281- {
2282- struct try_dispatcher
2283- {
2284- static inline bool AssignNodeTo( TryStatement *assign_to, const eir::FixedString <char>& attrib, COSNode *node )
2285- {
2286- if ( attrib == "try_body" )
2287- {
2288- assign_to->try_body = node;
2289- return true;
2290- }
2291- else if ( attrib == "error" )
2292- {
2293- assign_to->errors.AddToBack( dynamic_cast <CatchStatement*> ( node ) );
2294- return true;
2295- }
2296- return false;
2297- }
2298- };
2299- lexer.GetNamedProduction( "except" ).GetLastStep()->setSelector <direct_obj_build_selector <char, TryStatement, COSNode, try_dispatcher, decltype(lexer)::RuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
2300- }
2301- assert( lexer.CompileProduction( compiler, "forloop", "\"for\" spaces '(' spaces loop_init:(declaration | operation) spaces ';' spaces loop_cond:operation spaces ';' spaces loop_iteration:operation spaces ')' spaces body:loopbody" ) == true );
2302- {
2303- struct for_dispatcher
2304- {
2305- static inline bool AssignNodeTo( ForLoopStatement *assign_to, const eir::FixedString <char>& attrib, COSNode *node )
2306- {
2307- if ( attrib == "loop_init" )
2308- {
2309- assign_to->init = node;
2310- return true;
2311- }
2312- else if ( attrib == "loop_cond" )
2313- {
2314- assign_to->condition = node;
2315- return true;
2316- }
2317- else if ( attrib == "loop_iteration" )
2318- {
2319- assign_to->iteration = node;
2320- return true;
2321- }
2322- else if ( attrib == "body" )
2323- {
2324- assign_to->exec = node;
2325- return true;
2326- }
2327- return false;
2328- }
2329- };
2330- lexer.GetNamedProduction( "forloop" ).setSelector <direct_obj_build_selector <char, ForLoopStatement, COSNode, for_dispatcher, decltype(lexer)::RuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
2331- }
2332- assert( lexer.CompileProduction( compiler, "loop", "whileloop | forloop" ) == true );
2333- assert( lexer.CompileProduction( compiler, "structdef", "\"struct\" spaces name:spec spaces ^!(body:block, <b> statement+typestatement) spaces ';'" ) == true );
2334- {
2335- struct struct_dispatcher
2336- {
2337- static inline bool AssignNodeTo( StructDefinition *assign_to, const eir::FixedString <char>& attrib, COSNode *node )
2338- {
2339- if ( attrib == "name" )
2340- {
2341- assign_to->name = node;
2342- return true;
2343- }
2344- else if ( attrib == "body" )
2345- {
2346- assign_to->body = node;
2347- return true;
2348- }
2349- return false;
2350- }
2351- };
2352- lexer.GetNamedProduction( "structdef" ).setSelector <direct_obj_build_selector <char, StructDefinition, COSNode, struct_dispatcher, decltype(lexer)::RuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
2353- }
2354- assert( lexer.CompileProduction( compiler, "typedef", "dtypedef | structdef" ) == true );
2355- assert( lexer.CompileProduction( compiler, "typestatement", "constructor | destructor" ) == true );
2356- assert( lexer.CompileProduction( compiler, "constructor", "\"constructor\" spaces '(' spaces paramlist_opt spaces ')' spaces body:funcbody" ) == true );
2357- {
2358- struct constructor_dispatcher
2359- {
2360- static inline bool AssignNodeTo( ConstructorDefinition *assign_to, const eir::FixedString <char>& attrib, COSNode *node )
2361- {
2362- if ( attrib == "param" )
2363- {
2364- assign_to->params.AddToBack( node );
2365- return true;
2366- }
2367- else if ( attrib == "body" )
2368- {
2369- assign_to->body = node;
2370- return true;
2371- }
2372- return false;
2373- }
2374- };
2375- lexer.GetNamedProduction( "constructor" ).setSelector <direct_obj_build_selector <char, ConstructorDefinition, COSNode, constructor_dispatcher, decltype(lexer)::RuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
2376- }
2377- assert( lexer.CompileProduction( compiler, "destructor", "\"destructor\" spaces body:funcbody" ) == true );
2378- {
2379- struct destructor_dispatcher
2380- {
2381- static inline bool AssignNodeTo( DestructorDefinition *assign_to, const eir::FixedString <char>& attrib, COSNode *node )
2382- {
2383- if ( attrib == "body" )
2384- {
2385- assign_to->body = node;
2386- return true;
2387- }
2388- return false;
2389- }
2390- };
2391- lexer.GetNamedProduction( "destructor" ).setSelector <direct_obj_build_selector <char, DestructorDefinition, COSNode, destructor_dispatcher, decltype(lexer)::RuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
2392- }
2393- assert( lexer.CompileProduction( compiler, "deleteop", "\"delete\" spaces op:operation spaces ';'" ) == true );
2394- {
2395- struct delete_dispatcher
2396- {
2397- static inline bool AssignNodeTo( DeleteOperation *assign_to, const eir::FixedString <char>& attrib, COSNode *node )
2398- {
2399- if ( attrib == "op" )
2400- {
2401- assign_to->op = node;
2402- return true;
2403- }
2404- return false;
2405- }
2406- };
2407- lexer.GetNamedProduction( "deleteop" ).setSelector <direct_obj_build_selector <char, DeleteOperation, COSNode, delete_dispatcher, decltype(lexer)::RuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
2408- }
2409- assert( lexer.CompileProduction( compiler, "replaceop", "\"replace\" spaces what:operation spaces \"with\" spaces with:operation spaces ';'" ) == true );
2410- {
2411- struct replace_dispatcher
2412- {
2413- static inline bool AssignNodeTo( ReplaceOperation *assign_to, const eir::FixedString <char>& attrib, COSNode *node )
2414- {
2415- if ( attrib == "what" )
2416- {
2417- assign_to->what = node;
2418- return true;
2419- }
2420- else if ( attrib == "with" )
2421- {
2422- assign_to->with = node;
2423- return true;
2424- }
2425- return false;
2426- }
2427- };
2428- lexer.GetNamedProduction( "replaceop" ).setSelector <direct_obj_build_selector <char, ReplaceOperation, COSNode, replace_dispatcher, decltype(lexer)::RuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
2429- }
2430- assert( lexer.CompileProduction( compiler, "objmod", "deleteop | replaceop" ) == true );
2431- assert( lexer.CompileProduction( compiler, "templinst_templ", "[\"template\" spaces dotitem:replaceable itemtempl spaces '<' spaces [<0> templarg:procgate type, spaces ',' spaces] spaces endtempl:'>' | dotitem:replaceable itemtempl, spaces optok:(\"->\"|'.') spaces]" ) == true );
2432- {
2433- struct dot_with_templ_selector
2434- {
2435- enum class eOpType
2436- {
2437- DOT,
2438- ARROW
2439- };
2440-
2441- inline void AddNodeAsRootDot( COSNode *node )
2442- {
2443- COSNode *prev_root = this->root;
2444-
2445- if ( prev_root == nullptr )
2446- {
2447- this->root = node;
2448- return;
2449- }
2450-
2451- eOpType op_type = this->op_type;
2452-
2453- if ( op_type == eOpType::ARROW )
2454- {
2455- this->root = new ArrowOperation( prev_root, node );
2456- }
2457- else if ( op_type == eOpType::DOT )
2458- {
2459- this->root = new DotOperation( prev_root, node );
2460- }
2461- }
2462-
2463- inline void AssignAttribute( const eir::FixedString <char>& attrib, const eir::FixedString <char>& value )
2464- {
2465- if ( attrib == "endtempl" )
2466- {
2467- this->root = new TemplateInstantiationOperation( this->root, std::move( this->templargs ) );
2468- }
2469- else if ( attrib == "optok" )
2470- {
2471- if ( value == "." )
2472- {
2473- this->op_type = eOpType::DOT;
2474- }
2475- else if ( value == "->" )
2476- {
2477- this->op_type = eOpType::ARROW;
2478- }
2479- }
2480- }
2481-
2482- inline bool AssignNode( const eir::FixedString <char>& attrib, COSNode *node )
2483- {
2484- if ( attrib == "dotitem" )
2485- {
2486- this->AddNodeAsRootDot( node );
2487- return true;
2488- }
2489- else if ( attrib == "templarg" )
2490- {
2491- this->templargs.AddToBack( node );
2492- return true;
2493- }
2494-
2495- return false;
2496- }
2497-
2498- inline COSNode* DetachFinishedNode( void ) noexcept
2499- {
2500- COSNode *result = this->root;
2501-
2502- this->root = nullptr;
2503-
2504- return result;
2505- }
2506-
2507- COSNode *root = nullptr;
2508- depVector <COSNode*> templargs;
2509- eOpType op_type = eOpType::DOT;
2510- };
2511- lexer.GetNamedProduction( "templinst_templ" ).setSelector <dot_with_templ_selector> ();
2512- }
2513- assert( lexer.CompileProduction( compiler, "npath", "&(templinst_templ, itemtempl=name)" ) == true );
2514- assert( lexer.CompileProduction( compiler, "curlypack", "'(' spaces [<0> param:operation, spaces ',' spaces] spaces ')'" ) == true );
2515- {
2516- struct curlypack_dispatcher
2517- {
2518- static inline bool AssignNodeTo( CurlyPack *assign_to, const eir::FixedString <char>& attrib, COSNode *node )
2519- {
2520- if ( attrib == "param" )
2521- {
2522- assign_to->params.AddToBack( node );
2523- return true;
2524- }
2525- return false;
2526- }
2527- };
2528- lexer.GetNamedProduction( "curlypack" ).setSelector <direct_obj_build_selector <char, CurlyPack, COSNode, curlypack_dispatcher, decltype(lexer)::RuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
2529- }
2530-
2531- struct declaratory_locator_builder
2532- {
2533- enum class eLocatorType
2534- {
2535- POINTER,
2536- REFERENCE
2537- };
2538-
2539- struct array_spec
2540- {
2541- inline array_spec( COSNode *size_op = nullptr ) noexcept : size_op( size_op )
2542- {}
2543- inline array_spec( const array_spec& ) = default;
2544- inline array_spec( array_spec&& right ) noexcept
2545- {
2546- this->size_op = right.size_op;
2547-
2548- right.size_op = nullptr;
2549- }
2550-
2551- COSNode *size_op;
2552- };
2553-
2554- inline void AssignAttribute( const eir::FixedString <char>& attrib, const eir::FixedString <char>& value )
2555- {
2556- if ( attrib == "loc" )
2557- {
2558- if ( value == "*" )
2559- {
2560- locators.AddToBack( eLocatorType::POINTER );
2561- }
2562- else if ( value == "&" )
2563- {
2564- locators.AddToBack( eLocatorType::REFERENCE );
2565- }
2566- }
2567- else if ( attrib == "arrspec.endtok" )
2568- {
2569- locators.AddToBack( std::move( _build_arrspec ) );
2570- }
2571- }
2572-
2573- inline bool AssignNode( const eir::FixedString <char>& attrib, COSNode *node )
2574- {
2575- if ( attrib == "arrspec.idx" )
2576- {
2577- _build_arrspec.size_op = node;
2578- return true;
2579- }
2580- return false;
2581- }
2582-
2583- inline COSNode* EncapsulateByTypeLocators( COSNode *node )
2584- {
2585- COSNode *return_node = node;
2586-
2587- for ( loc_variant_t& item : this->locators )
2588- {
2589- if ( std::holds_alternative <eLocatorType> ( item ) )
2590- {
2591- eLocatorType basic_loctype = std::get <eLocatorType> ( item );
2592-
2593- if ( basic_loctype == eLocatorType::POINTER )
2594- {
2595- return_node = new PointerTypeSpecifier( return_node );
2596- }
2597- else if ( basic_loctype == eLocatorType::REFERENCE )
2598- {
2599- return_node = new RefTypeSpecifier( return_node );
2600- }
2601- }
2602- else if ( std::holds_alternative <array_spec> ( item ) )
2603- {
2604- array_spec& arrspec = std::get <array_spec> ( item );
2605-
2606- return_node = new ArrayTypeSpecifier( return_node, arrspec.size_op );
2607- }
2608- }
2609-
2610- return return_node;
2611- }
2612-
2613- inline void Reset( void )
2614- {
2615- this->locators.Clear();
2616- this->_build_arrspec.size_op = nullptr;
2617- }
2618-
2619- typedef std::variant <eLocatorType, array_spec> loc_variant_t;
2620-
2621- depVector <loc_variant_t> locators;
2622-
2623- // Temporary build variables.
2624- array_spec _build_arrspec;
2625- };
2626-
2627- // Type system COS structures.
2628- assert( lexer.CompileProduction( compiler, "locator", "[<0>loc:'*',spaces] (spaces loc:'&')^0:1" ) == true ); // helper
2629- assert( lexer.CompileProduction( compiler, "tmultdecl", "&(mdecltempl, nameplacehold=spec, initplacehold=empty)" ) == true );
2630- {
2631- struct tmultdecl_selector
2632- {
2633- inline TypedefStatement* DetachTypedef( void )
2634- {
2635- COSNode *underlying_type = this->locbuild.EncapsulateByTypeLocators( this->utype );
2636-
2637- COSNode *srctype;
2638-
2639- if ( COSNode *func = this->func )
2640- {
2641- FuncsigDefinition *actual_func = dynamic_cast <FuncsigDefinition*> ( TypeSpecifier::ResolveUntilMostSpecialized( func ) );
2642-
2643- FuncsigDefinition *left_most_func = actual_func->GetDeepestReturnValueFunctionSignatureType();
2644-
2645- left_most_func->return_type = underlying_type;
2646-
2647- srctype = func;
2648- }
2649- else
2650- {
2651- srctype = underlying_type;
2652- }
2653-
2654- this->tdef.srctype = srctype;
2655-
2656- return new TypedefStatement( std::move( this->tdef ) );
2657- }
2658-
2659- inline void PushDefinition( void )
2660- {
2661- this->multidef.defs.AddToBack( this->DetachTypedef() );
2662-
2663- // Reset the typedef builder fields, but not utype.
2664- this->locbuild.Reset();
2665- this->func = nullptr;
2666- }
2667-
2668- inline void AssignAttribute( const eir::FixedString <char>& attrib, const eir::FixedString <char>& value )
2669- {
2670- if ( attrib == "nextdecl" )
2671- {
2672- this->PushDefinition();
2673- }
2674- else
2675- {
2676- locbuild.AssignAttribute( attrib, value );
2677- }
2678- }
2679-
2680- inline bool AssignNode( const eir::FixedString <char>& attrib, COSNode *node )
2681- {
2682- if ( attrib == "utype" )
2683- {
2684- this->utype = node;
2685- return true;
2686- }
2687- else if ( attrib == "func" )
2688- {
2689- this->func = node;
2690- return true;
2691- }
2692- else if ( LexingEnvUtils::GetLastAttributionItemInPathFixed( attrib ) == "name" )
2693- {
2694- this->tdef.dsttype = node;
2695- return true;
2696- }
2697- else if ( locbuild.AssignNode( attrib, node ) )
2698- {
2699- return true;
2700- }
2701-
2702- return false;
2703- }
2704-
2705- inline COSNode* DetachFinishedNode( void )
2706- {
2707- if ( this->multidef.defs.GetCount() == 0 )
2708- {
2709- // Just return the single typedef.
2710- return this->DetachTypedef();
2711- }
2712- else
2713- {
2714- this->PushDefinition();
2715-
2716- return new MultiTypedefStatement( std::move( this->multidef ) );
2717- }
2718- }
2719-
2720- COSNode *utype = nullptr;
2721- COSNode *func = nullptr;
2722- declaratory_locator_builder locbuild;
2723- TypedefStatement tdef;
2724- MultiTypedefStatement multidef;
2725- };
2726- lexer.GetNamedProduction( "tmultdecl" ).setSelector <tmultdecl_selector> ();
2727- }
2728- assert( lexer.CompileProduction( compiler, "funcsigtempl", "functag spaces ( '(' spaces locator spaces (subfunc:funcsigtempl|locnametempl) spaces ')' | name:replaceable nameplacehold ) spaces '(' spaces paramlist_opt spaces ')'" ) == true );
2729- {
2730- struct funcsig_selector
2731- {
2732- inline void AssignAttribute( const eir::FixedString <char>& attrib, const eir::FixedString <char>& value )
2733- {
2734- locbuild.AssignAttribute( attrib, value );
2735- }
2736-
2737- inline bool AssignNode( const eir::FixedString <char>& attrib, COSNode *node )
2738- {
2739- if ( attrib == "param" )
2740- {
2741- this->funcsig.params.AddToBack( node );
2742- return true;
2743- }
2744- else if ( attrib == "subfunc" )
2745- {
2746- this->subfunc = node;
2747- return true;
2748- }
2749- else if ( LexingEnvUtils::GetLastAttributionItemInPathFixed( attrib ) == "name" )
2750- {
2751- throw lexing_value_transgression_exception();
2752- }
2753- else if ( locbuild.AssignNode( attrib, node ) )
2754- {
2755- return true;
2756- }
2757- return false;
2758- }
2759-
2760- inline COSNode* DetachFinishedNode( void )
2761- {
2762- COSNode *return_node;
2763-
2764- COSNode *detached_func = this->locbuild.EncapsulateByTypeLocators( new FuncsigDefinition( std::move( this->funcsig ) ) );
2765-
2766- if ( COSNode *subfunc = this->subfunc )
2767- {
2768- FuncsigDefinition *actual_subfunc = dynamic_cast <FuncsigDefinition*> ( TypeSpecifier::ResolveUntilMostSpecialized( subfunc ) );
2769-
2770- FuncsigDefinition *left_most_sig = actual_subfunc->GetDeepestReturnValueFunctionSignatureType();
2771-
2772- left_most_sig->return_type = detached_func;
2773-
2774- return_node = subfunc;
2775- }
2776- else
2777- {
2778- return_node = detached_func;
2779- }
2780-
2781- return return_node;
2782- }
2783-
2784- declaratory_locator_builder locbuild;
2785- FuncsigDefinition funcsig;
2786- COSNode *subfunc = nullptr;
2787- };
2788- lexer.GetNamedProduction( "funcsigtempl" ).setSelector <funcsig_selector> ();
2789- }
2790- assert( lexer.CompileProduction( compiler, "funcsigdecl", "&(funcsigtempl, nameplacehold=spec)" ) == true );
2791- assert( lexer.CompileProduction( compiler, "locnametempl", "name:replaceable nameplacehold (spaces [arrspec:arrayspec, spaces])^0:1" ) == true ); // helper
2792- assert( lexer.CompileProduction( compiler, "arrayspec", "'[' spaces (idx:operation spaces)^0:1 endtok:']'" ) == true ); // helper
2793- // Set-up both of the following productions in one block.
2794- assert( lexer.CompileProduction( compiler, "decltemplate", "utype:spec spaces locator spaces (func:funcsigtempl|locnametempl) replaceable initplacehold" ) == true ); // helper
2795- assert( lexer.CompileProduction( compiler, "mdecltempl", "utype:spec spaces [locator spaces (func:funcsigtempl|locnametempl) replaceable initplacehold, spaces nextdecl:',' spaces]" ) == true );
2796- assert( lexer.CompileProduction( compiler, "declaration", "&(decltemplate, nameplacehold=spec, initplacehold=declinit)" ) == true );
2797- assert( lexer.CompileProduction( compiler, "decl_optnoinit", "&(decltemplate, nameplacehold=(spec)^0:1, initplacehold=empty)" ) == true );
2798- assert( lexer.CompileProduction( compiler, "decl_opt", "&(decltemplate, nameplacehold=(spec)^0:1, initplacehold=declinit)" ) == true );
2799- assert( lexer.CompileProduction( compiler, "multdecl", "&(mdecltempl, nameplacehold=spec, initplacehold=declinit) mdeclterm" ) == true );
2800- {
2801- struct declaration_selector
2802- {
2803- inline void AssignAttribute( const eir::FixedString <char>& attrib, const eir::FixedString <char>& value )
2804- {
2805- locbuild.AssignAttribute( attrib, value );
2806- }
2807-
2808- inline bool AssignNode( const eir::FixedString <char>& attrib, COSNode *node )
2809- {
2810- if ( attrib == "utype" )
2811- {
2812- this->utype = node;
2813- return true;
2814- }
2815- else if ( attrib == "func" )
2816- {
2817- this->func = node;
2818- return true;
2819- }
2820- else if ( attrib == "init" )
2821- {
2822- this->decl.initializer = node;
2823- return true;
2824- }
2825- else if ( attrib == "init_s" )
2826- {
2827- this->decl.initializer = node;
2828- this->special_init = true;
2829- return true;
2830- }
2831- else if ( LexingEnvUtils::GetLastAttributionItemInPathFixed( attrib ) == "name" )
2832- {
2833- this->decl.name = node;
2834- return true;
2835- }
2836- else if ( locbuild.AssignNode( attrib, node ) )
2837- {
2838- return true;
2839- }
2840- return false;
2841- }
2842-
2843- inline COSNode* GetBuiltType( void )
2844- {
2845- if ( COSNode *built_type = this->built_type )
2846- return built_type;
2847-
2848- // Build the underlying type completely.
2849- COSNode *underlying_type = locbuild.EncapsulateByTypeLocators( this->utype );
2850-
2851- COSNode *built_type;
2852-
2853- if ( COSNode *func = this->func )
2854- {
2855- FuncsigDefinition *actual_func = dynamic_cast <FuncsigDefinition*> ( TypeSpecifier::ResolveUntilMostSpecialized( func ) );
2856-
2857- FuncsigDefinition *left_most_sig = actual_func->GetDeepestReturnValueFunctionSignatureType();
2858-
2859- left_most_sig->return_type = underlying_type;
2860-
2861- built_type = func;
2862- }
2863- else
2864- {
2865- built_type = underlying_type;
2866- }
2867-
2868- this->built_type = built_type;
2869-
2870- return built_type;
2871- }
2872-
2873- inline DeclarationStatement* DetachFinishedNode( void )
2874- {
2875- this->decl.type = this->GetBuiltType();
2876-
2877- return new DeclarationStatement( std::move( this->decl ) );
2878- }
2879-
2880- inline void ResetForMulti( void )
2881- {
2882- // Do not reset utype field.
2883-
2884- this->func = nullptr;
2885- this->locbuild.Reset();
2886- this->decl.type = nullptr;
2887- this->decl.name = nullptr;
2888- this->decl.initializer = nullptr;
2889- this->built_type = nullptr;
2890- }
2891-
2892- COSNode *utype = nullptr;
2893- COSNode *func = nullptr;
2894- declaratory_locator_builder locbuild;
2895- DeclarationStatement decl;
2896- bool special_init = false;
2897- COSNode *built_type = nullptr;
2898- };
2899- lexer.GetNamedProduction( "declaration" ).setSelector <declaration_selector> ();
2900- lexer.GetNamedProduction( "decl_optnoinit" ).setSelector <declaration_selector> ();
2901- lexer.GetNamedProduction( "decl_opt" ).setSelector <declaration_selector> ();
2902-
2903- struct multdecl_selector
2904- {
2905- inline void PushDeclaration( void )
2906- {
2907- this->multdecl.decls.AddToBack( this->declsel.DetachFinishedNode() );
2908-
2909- // Clear type information other than the utype field.
2910- this->declsel.ResetForMulti();
2911- }
2912-
2913- inline void AssignAttribute( const eir::FixedString <char>& attrib, const eir::FixedString <char>& value )
2914- {
2915- if ( attrib == "nextdecl" )
2916- {
2917- this->PushDeclaration();
2918- }
2919- else
2920- {
2921- declsel.AssignAttribute( attrib, value );
2922- }
2923- }
2924-
2925- inline bool AssignNode( const eir::FixedString <char>& attrib, COSNode *node )
2926- {
2927- return declsel.AssignNode( attrib, node );
2928- }
2929-
2930- inline COSNode* DetachFinishedNode( void )
2931- {
2932- if ( this->multdecl.decls.GetCount() == 0 )
2933- {
2934- // Just return a single declaration.
2935- return this->declsel.DetachFinishedNode();
2936- }
2937- else
2938- {
2939- this->PushDeclaration();
2940-
2941- return new MultiDeclarationStatement( std::move( this->multdecl ) );
2942- }
2943- }
2944-
2945- MultiDeclarationStatement multdecl;
2946- declaration_selector declsel;
2947- };
2948- lexer.GetNamedProduction( "multdecl" ).setSelector <multdecl_selector> ();
2949-
2950- auto special_declinit = lexer.MakeStep <decltype(lexer)::RuntimeEnv::StepCustomIndirection> ();
2951-
2952- // INDEX 0: array enclosure.
2953- auto *step_arrenclose = lexer.CompileInto( compiler, special_declinit, "'{' spaces ([item:initexpr, spaces ',' spaces] spaces)^0:1 '}'" );
2954- {
2955- struct arrenclose_dispatcher
2956- {
2957- static inline bool AssignNodeTo( ArrayDefinition *assign_to, const eir::FixedString <char>& attrib, COSNode *node )
2958- {
2959- if ( attrib == "item" )
2960- {
2961- assign_to->items.AddToBack( node );
2962- return true;
2963- }
2964-
2965- return false;
2966- }
2967- };
2968- step_arrenclose->setSelector <direct_obj_build_selector <char, ArrayDefinition, COSNode, arrenclose_dispatcher, decltype(lexer)::RuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
2969- }
2970-
2971- // INDEX 1: outer value.
2972- auto *step_outerval = lexer.CompileInto( compiler, special_declinit, "'{' spaces operation spaces '}'" );
2973-
2974- // We also need the following productions which are already defined:
2975- // * operation
2976- // * funcbody
2977-
2978- special_declinit.callback = [&lexer, step_arrenclose, step_outerval]( decltype(lexer)::RuntimeEnv::ProductionMachine& machine ) -> decltype(lexer)::RuntimeEnv::Step*
2979- {
2980- auto& step_declaration = lexer.GetNamedProduction( "declaration" );
2981- auto& step_decl_opt = lexer.GetNamedProduction( "decl_opt" );
2982- auto& step_multdecl = lexer.GetNamedProduction( "multdecl" );
2983- auto& step_declinit = lexer.GetNamedProduction( "initexpr" );
2984-
2985- size_t cstack_cnt = machine.GetCurrentCalcStackSize();
2986-
2987- size_t cstack_idx = ( cstack_cnt - 2 ); // skip us.
2988-
2989- declaration_selector *decl_sel = nullptr;
2990- multdecl_selector *multdecl_sel = nullptr;
2991-
2992- size_t init_depth = 0;
2993-
2994- while ( cstack_idx > 0 )
2995- {
2996- cstack_idx--;
2997-
2998- auto *step = machine.GetCurrentExecutionStepByIndex( cstack_idx );
2999-
3000- if ( step == &step_declaration || step == &step_decl_opt )
3001- {
3002- decl_sel = (declaration_selector*)machine.GetCurrentExecutionSelectorDataByIndex( cstack_idx );
3003- break;
3004- }
3005- else if ( step == &step_multdecl )
3006- {
3007- multdecl_sel = (multdecl_selector*)machine.GetCurrentExecutionSelectorDataByIndex( cstack_idx );
3008- break;
3009- }
3010- else if ( step == &step_declinit )
3011- {
3012- init_depth++;
3013- }
3014- }
3015-
3016- COSNode *type = nullptr;
3017-
3018- if ( decl_sel )
3019- {
3020- type = decl_sel->GetBuiltType();
3021- }
3022- else if ( multdecl_sel )
3023- {
3024- type = multdecl_sel->declsel.GetBuiltType();
3025- }
3026-
3027- if ( type )
3028- {
3029- // Go as deep as required by init_depth to find the init-type.
3030- COSNode *init_type = type;
3031- {
3032- size_t init_iter = init_depth;
3033-
3034- while ( init_iter > 0 )
3035- {
3036- init_iter--;
3037-
3038- if ( TypeSpecifier *ptrspec = dynamic_cast <TypeSpecifier*> ( init_type ) )
3039- {
3040- init_type = ptrspec->spec;
3041- }
3042- else
3043- {
3044- // Unknown.
3045- return nullptr;
3046- }
3047- }
3048- }
3049-
3050- if ( dynamic_cast <ArrayTypeSpecifier*> ( init_type ) )
3051- {
3052- // We want to build an array.
3053- return step_arrenclose;
3054- }
3055- else if ( dynamic_cast <FuncsigDefinition*> ( init_type ) )
3056- {
3057- // Expect function body.
3058- return &lexer.GetNamedProduction( "funcbody" );
3059- }
3060- else if ( init_depth > 0 )
3061- {
3062- // Expect operation.
3063- return &lexer.GetNamedProduction( "operation" );
3064- }
3065- else
3066- {
3067- // Expect an outer-value.
3068- return step_outerval;
3069- }
3070- }
3071-
3072- return nullptr;
3073- };
3074-
3075- lexer.AddStep( "initexpr", std::move( special_declinit ) );
3076-
3077- // Implement the terminator after the multi-declaration.
3078- auto mdeclterm = lexer.MakeStep <decltype(lexer)::RuntimeEnv::StepCustomIndirection> ();
3079-
3080- auto *step_spaceterm = lexer.CompileInto( compiler, mdeclterm, "spaces ';'" );
3081-
3082- mdeclterm.callback = [&]( decltype(lexer)::RuntimeEnv::ProductionMachine& machine ) -> decltype(lexer)::RuntimeEnv::Step*
3083- {
3084- auto& step_multdecl = lexer.GetNamedProduction( "multdecl" );
3085-
3086- size_t cstack_size = machine.GetCurrentCalcStackSize() - 2;
3087-
3088- multdecl_selector *mdecl_sel = nullptr;
3089-
3090- while ( cstack_size > 0 )
3091- {
3092- cstack_size--;
3093-
3094- auto *cstep = machine.GetCurrentExecutionStepByIndex( cstack_size );
3095-
3096- if ( cstep == &step_multdecl )
3097- {
3098- mdecl_sel = (multdecl_selector*)machine.GetCurrentExecutionSelectorDataByIndex( cstack_size );
3099- break;
3100- }
3101- }
3102-
3103- if ( mdecl_sel )
3104- {
3105- if ( dynamic_cast <FuncsigDefinition*> ( mdecl_sel->declsel.GetBuiltType() ) != nullptr &&
3106- mdecl_sel->declsel.special_init == true )
3107- {
3108- // Empty and successful.
3109- return nullptr;
3110- }
3111- }
3112-
3113- // Just the regular terminator with the semi-colon.
3114- return step_spaceterm;
3115- };
3116-
3117- lexer.AddStep( "mdeclterm", std::move( mdeclterm ) );
3118- }
3119- assert( lexer.CompileProduction( compiler, "declinit", "( spaces init_s:initexpr | spaces '=' spaces init:operation | spaces init:curlypack )^0:1" ) == true );
3120- assert( lexer.CompileProduction( compiler, "functag", "\"func\" | \"proc\"" ) == true );
3121- assert( lexer.CompileProduction( compiler, "type", "&(decltemplate, nameplacehold=empty, initplacehold=empty)" ) == true );
3122- {
3123- struct type_selector
3124- {
3125- inline void AssignAttribute( const eir::FixedString <char>& attrib, const eir::FixedString <char>& value )
3126- {
3127- locbuild.AssignAttribute( attrib, value );
3128- }
3129-
3130- inline bool AssignNode( const eir::FixedString <char>& attrib, COSNode *node )
3131- {
3132- if ( attrib == "utype" )
3133- {
3134- this->utype = node;
3135- return true;
3136- }
3137- else if ( attrib == "func" )
3138- {
3139- this->func = node;
3140- return true;
3141- }
3142- return locbuild.AssignNode( attrib, node );
3143- }
3144-
3145- inline COSNode* DetachFinishedNode( void )
3146- {
3147- COSNode *underlying_type = this->locbuild.EncapsulateByTypeLocators( this->utype );
3148-
3149- if ( COSNode *func = this->func )
3150- {
3151- FuncsigDefinition *actual_func = dynamic_cast <FuncsigDefinition*> ( TypeSpecifier::ResolveUntilMostSpecialized( func ) );
3152-
3153- FuncsigDefinition *left_most_func = actual_func->GetDeepestReturnValueFunctionSignatureType();
3154-
3155- left_most_func->return_type = underlying_type;
3156-
3157- return func;
3158- }
3159- else
3160- {
3161- return underlying_type;
3162- }
3163- }
3164-
3165- COSNode *utype = nullptr;
3166- declaratory_locator_builder locbuild;
3167- COSNode *func = nullptr;
3168- };
3169- lexer.GetNamedProduction( "type" ).setSelector <type_selector> ();
3170- }
3171- assert( lexer.CompileProduction( compiler, "paramlist_opt", "[<0>param:decl_opt, spaces ',' spaces]" ) == true );
3172- assert( lexer.CompileProduction( compiler, "namespace", "\"namespace\" spaces name:spec spaces toinclude:nblock" ) == true );
3173- {
3174- struct ns_stmt_dispatcher
3175- {
3176- static inline bool AssignNodeTo( NamespaceStatement *assign_to, const eir::FixedString <char>& attrib, COSNode *node )
3177- {
3178- if ( attrib == "name" )
3179- {
3180- assign_to->name = node;
3181- return true;
3182- }
3183- if ( attrib == "toinclude" )
3184- {
3185- assign_to->toinclude = node;
3186- return true;
3187- }
3188-
3189- return false;
3190- }
3191- };
3192- lexer.GetNamedProduction( "namespace" ).GetLastStep()->setSelector <direct_obj_build_selector <char, NamespaceStatement, COSNode, ns_stmt_dispatcher, decltype(lexer)::RuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
3193- }
3194- assert( lexer.CompileProduction( compiler, "namespace", "\"using\" spaces \"namespace\" spaces nsname:spec spaces ';'" ) == true );
3195- {
3196- struct ns_using_dispatcher
3197- {
3198- static inline bool AssignNodeTo( UsingNamespaceStatement *assign_to, const eir::FixedString <char>& attrib, COSNode *node )
3199- {
3200- if ( attrib == "nsname" )
3201- {
3202- assign_to->nsname = node;
3203- return true;
3204- }
3205-
3206- return false;
3207- }
3208- };
3209- lexer.GetNamedProduction( "namespace" ).GetLastStep()->setSelector <direct_obj_build_selector <char, UsingNamespaceStatement, COSNode, ns_using_dispatcher, decltype(lexer)::RuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
3210- }
3211- assert( lexer.CompileProduction( compiler, "enum", "\"enum\" spaces name:spec spaces '{' spaces [item:name (spaces '=' spaces inum:number)^0:1, spaces ',' spaces] spaces '}' spaces ';'" ) == true );
3212- {
3213- struct enum_selector
3214- {
3215- inline void PushItem( COSNode *val_node )
3216- {
3217- EnumDefinition::item entry;
3218- entry.key = this->curKeyNode;
3219- entry.value = val_node;
3220-
3221- this->enumobj.items.AddToBack( std::move( entry ) );
3222-
3223- this->curKeyNode = nullptr;
3224- }
3225-
3226- inline bool AssignNode( const eir::FixedString <char>& attrib, COSNode *node )
3227- {
3228- if ( attrib == "name" )
3229- {
3230- this->enumobj.name = node;
3231- return true;
3232- }
3233- if ( attrib == "item" )
3234- {
3235- if ( this->curKeyNode != nullptr )
3236- {
3237- this->PushItem( nullptr );
3238- }
3239-
3240- this->curKeyNode = node;
3241- return true;
3242- }
3243- if ( attrib == "inum" )
3244- {
3245- this->PushItem( node );
3246- return true;
3247- }
3248-
3249- return false;
3250- }
3251-
3252- inline COSNode* DetachFinishedNode( void )
3253- {
3254- if ( this->curKeyNode != nullptr )
3255- {
3256- this->PushItem( nullptr );
3257- }
3258-
3259- return new EnumDefinition( std::move( this->enumobj ) );
3260- }
3261-
3262- EnumDefinition enumobj;
3263- COSNode *curKeyNode = nullptr;
3264- };
3265- lexer.GetNamedProduction( "enum" ).GetLastStep()->setSelector <enum_selector> ();
3266- }
3267-
326819 printf( "testing COS operations (non-deep)..." );
326920 {
3270- assert( lexer.TestProduction( "1 + 1;" ) == true );
3271- assert( lexer.TestProduction( "1 + 1 + 1;" ) == true );
3272- assert( lexer.TestProduction( "1 + 1 + 1 + 1;" ) == true );
3273- assert( lexer.TestProduction( "1 * 1;" ) == true );
3274- assert( lexer.TestProduction( "1 * (1 + 1);" ) == true );
3275- assert( lexer.TestProduction( "1 + 1 * 1 / 1;" ) == true );
3276- assert( lexer.TestProduction( "variable;" ) == true );
3277- assert( lexer.TestProduction( "function();" ) == true );
3278- assert( lexer.TestProduction( "getvar() + getvar();" ) == true );
3279- assert( lexer.TestProduction( "test(1,2,3);" ) == true );
3280- assert( lexer.TestProduction( "1 - 1;" ) == true );
3281- assert( lexer.TestProduction( "70 / 10;" ) == true );
3282- assert( lexer.TestProduction( "var() + var() + var();" ) == true );
21+ assert( cosEnv.TestCompilation( "1 + 1;" ) == true );
22+ assert( cosEnv.TestCompilation( "1 + 1 + 1;" ) == true );
23+ assert( cosEnv.TestCompilation( "1 + 1 + 1 + 1;" ) == true );
24+ assert( cosEnv.TestCompilation( "1 * 1;" ) == true );
25+ assert( cosEnv.TestCompilation( "1 * (1 + 1);" ) == true );
26+ assert( cosEnv.TestCompilation( "1 + 1 * 1 / 1;" ) == true );
27+ assert( cosEnv.TestCompilation( "variable;" ) == true );
28+ assert( cosEnv.TestCompilation( "function();" ) == true );
29+ assert( cosEnv.TestCompilation( "getvar() + getvar();" ) == true );
30+ assert( cosEnv.TestCompilation( "test(1,2,3);" ) == true );
31+ assert( cosEnv.TestCompilation( "1 - 1;" ) == true );
32+ assert( cosEnv.TestCompilation( "70 / 10;" ) == true );
33+ assert( cosEnv.TestCompilation( "var() + var() + var();" ) == true );
328334 }
328435 printf( "ok.\n" );
328536
@@ -3287,7 +38,7 @@
328738 {
328839 // 1)
328940 {
3290- COSNode *_root = lexer.StartProduction( "1+1-1*1/1;" );
41+ COSNode *_root = cosEnv.Compile( "1+1-1*1/1;" );
329142
329243 SubOperation *root = dynamic_cast <SubOperation*> ( _root );
329344
@@ -3350,7 +101,7 @@
3350101
3351102 // 2)
3352103 {
3353- COSNode *_root = lexer.StartProduction( "1+1*1+1;" );
104+ COSNode *_root = cosEnv.Compile( "1+1*1+1;" );
3354105
3355106 AddOperation *root = dynamic_cast <AddOperation*> ( _root );
3356107
@@ -3396,7 +147,7 @@
3396147
3397148 // 3)
3398149 {
3399- COSNode *_root = lexer.StartProduction( "1*(1+1*1);" );
150+ COSNode *_root = cosEnv.Compile( "1*(1+1*1);" );
3400151
3401152 MulOperation *root = dynamic_cast <MulOperation*> ( _root );
3402153
@@ -3442,7 +193,7 @@
3442193
3443194 // 4)
3444195 {
3445- COSNode *_root = lexer.StartProduction( "a=1+1;" );
196+ COSNode *_root = cosEnv.Compile( "a=1+1;" );
3446197
3447198 AssignmentOperation *root = dynamic_cast <AssignmentOperation*> ( _root );
3448199
@@ -3476,7 +227,7 @@
3476227
3477228 // 5)
3478229 {
3479- COSNode *_root = lexer.StartProduction( "1==2;" );
230+ COSNode *_root = cosEnv.Compile( "1==2;" );
3480231
3481232 CompareEqualityOperation *root = dynamic_cast <CompareEqualityOperation*> ( _root );
3482233
@@ -3500,7 +251,7 @@
3500251
3501252 // 6)
3502253 {
3503- COSNode *_root = lexer.StartProduction( "1+1==2-0;" );
254+ COSNode *_root = cosEnv.Compile( "1+1==2-0;" );
3504255
3505256 CompareEqualityOperation *root = dynamic_cast <CompareEqualityOperation*> ( _root );
3506257
@@ -3543,7 +294,7 @@
3543294
3544295 // 7)
3545296 {
3546- COSNode *_root = lexer.StartProduction( "1==1<=1;" );
297+ COSNode *_root = cosEnv.Compile( "1==1<=1;" );
3547298
3548299 CompareLessThanEqualOperation *root = dynamic_cast <CompareLessThanEqualOperation*> ( _root );
3549300
@@ -3577,7 +328,7 @@
3577328
3578329 // 8)
3579330 {
3580- COSNode *_root = lexer.StartProduction( "1<2;" );
331+ COSNode *_root = cosEnv.Compile( "1<2;" );
3581332
3582333 CompareLessThanOperation *root = dynamic_cast <CompareLessThanOperation*> ( _root );
3583334
@@ -3599,7 +350,7 @@
3599350
3600351 // 9)
3601352 {
3602- COSNode *_root = lexer.StartProduction( "3>1;" );
353+ COSNode *_root = cosEnv.Compile( "3>1;" );
3603354
3604355 CompareGreaterThanOperation *root = dynamic_cast <CompareGreaterThanOperation*> ( _root );
3605356
@@ -3624,7 +375,7 @@
3624375
3625376 // 10)
3626377 {
3627- COSNode *_root = lexer.StartProduction( "1>=0;" );
378+ COSNode *_root = cosEnv.Compile( "1>=0;" );
3628379
3629380 CompareGreaterThanEqualOperation *root = dynamic_cast <CompareGreaterThanEqualOperation*> ( _root );
3630381
@@ -3646,7 +397,7 @@
3646397
3647398 // 11)
3648399 {
3649- COSNode *_root = lexer.StartProduction( "20<11>19<=1>=2==3!=0;" );
400+ COSNode *_root = cosEnv.Compile( "20<11>19<=1>=2==3!=0;" );
3650401
3651402 CompareInequalityOperation *root = dynamic_cast <CompareInequalityOperation*> ( _root );
3652403
@@ -3728,7 +479,7 @@
3728479
3729480 // 12)
3730481 {
3731- COSNode *_root = lexer.StartProduction( "a(1)+b(1)=3;" );
482+ COSNode *_root = cosEnv.Compile( "a(1)+b(1)=3;" );
3732483
3733484 AssignmentOperation *root = dynamic_cast <AssignmentOperation*> ( _root );
3734485
@@ -3792,7 +543,7 @@
3792543
3793544 // 13)
3794545 {
3795- COSNode *_root = lexer.StartProduction( "a(b(1)+1,c(1))+3==0;" );
546+ COSNode *_root = cosEnv.Compile( "a(b(1)+1,c(1))+3==0;" );
3796547
3797548 CompareEqualityOperation *root = dynamic_cast <CompareEqualityOperation*> ( _root );
3798549
@@ -3885,7 +636,7 @@
3885636
3886637 // 14)
3887638 {
3888- COSNode *_root = lexer.StartProduction( "-(1+1)*3;" );
639+ COSNode *_root = cosEnv.Compile( "-(1+1)*3;" );
3889640
3890641 MulOperation *root = dynamic_cast <MulOperation*> ( _root );
3891642
@@ -3928,7 +679,7 @@
3928679
3929680 // 15)
3930681 {
3931- COSNode *_root = lexer.StartProduction( "-(-(1));" );
682+ COSNode *_root = cosEnv.Compile( "-(-(1));" );
3932683
3933684 NumericNegationOperation *root = dynamic_cast <NumericNegationOperation*> ( _root );
3934685
@@ -3951,7 +702,7 @@
3951702
3952703 // 16)
3953704 {
3954- COSNode *_root = lexer.StartProduction( "--a;" );
705+ COSNode *_root = cosEnv.Compile( "--a;" );
3955706
3956707 PreDecrementOperation *root = dynamic_cast <PreDecrementOperation*> ( _root );
3957708
@@ -3969,7 +720,7 @@
3969720
3970721 // 17)
3971722 {
3972- COSNode *_root = lexer.StartProduction( "a--=1;" );
723+ COSNode *_root = cosEnv.Compile( "a--=1;" );
3973724
3974725 AssignmentOperation *root = dynamic_cast <AssignmentOperation*> ( _root );
3975726
@@ -4000,7 +751,7 @@
4000751
4001752 // 18)
4002753 {
4003- COSNode *_root = lexer.StartProduction( "a++;" );
754+ COSNode *_root = cosEnv.Compile( "a++;" );
4004755
4005756 PostIncrementOperation *root = dynamic_cast <PostIncrementOperation*> ( _root );
4006757
@@ -4018,7 +769,7 @@
4018769
4019770 // 19)
4020771 {
4021- COSNode *_root = lexer.StartProduction( "++a;" );
772+ COSNode *_root = cosEnv.Compile( "++a;" );
4022773
4023774 PreIncrementOperation *root = dynamic_cast <PreIncrementOperation*> ( _root );
4024775
@@ -4035,7 +786,7 @@
4035786
4036787 // 20)
4037788 {
4038- COSNode *_root = lexer.StartProduction( "2 | 1 & 0 == 2;" );
789+ COSNode *_root = cosEnv.Compile( "2 | 1 & 0 == 2;" );
4039790
4040791 BitwiseOrOperation *root = dynamic_cast <BitwiseOrOperation*> ( _root );
4041792
@@ -4083,7 +834,7 @@
4083834
4084835 // 21)
4085836 {
4086- COSNode *_root = lexer.StartProduction( "10|~0==10;" );
837+ COSNode *_root = cosEnv.Compile( "10|~0==10;" );
4087838
4088839 BitwiseOrOperation *root = dynamic_cast <BitwiseOrOperation*> ( _root );
4089840
@@ -4124,7 +875,7 @@
4124875
4125876 // 22)
4126877 {
4127- COSNode *_root = lexer.StartProduction( "32==1&&false;" );
878+ COSNode *_root = cosEnv.Compile( "32==1&&false;" );
4128879
4129880 LogicalAndOperation *root = dynamic_cast <LogicalAndOperation*> ( _root );
4130881
@@ -4162,7 +913,7 @@
4162913
4163914 // 23)
4164915 {
4165- COSNode *_root = lexer.StartProduction( "2|1||7|8;" );
916+ COSNode *_root = cosEnv.Compile( "2|1||7|8;" );
4166917
4167918 LogicalOrOperation *root = dynamic_cast <LogicalOrOperation*> ( _root );
4168919
@@ -4213,7 +964,7 @@
4213964
4214965 // 24)
4215966 {
4216- COSNode *_root = lexer.StartProduction( "isdata==true||number==0&&domain>=0;" );
967+ COSNode *_root = cosEnv.Compile( "isdata==true||number==0&&domain>=0;" );
4217968
4218969 LogicalOrOperation *root = dynamic_cast <LogicalOrOperation*> ( _root );
4219970
@@ -4287,7 +1038,7 @@
42871038
42881039 // 25)
42891040 {
4290- COSNode *_root = lexer.StartProduction( "table.field.subfield=value;" );
1041+ COSNode *_root = cosEnv.Compile( "table.field.subfield=value;" );
42911042
42921043 AssignmentOperation *root = dynamic_cast <AssignmentOperation*> ( _root );
42931044
@@ -4338,7 +1089,7 @@
43381089
43391090 // 26)
43401091 {
4341- COSNode *_root = lexer.StartProduction( "replace tvalue with 0;" );
1092+ COSNode *_root = cosEnv.Compile( "replace tvalue with 0;" );
43421093
43431094 ReplaceOperation *root = dynamic_cast <ReplaceOperation*> ( _root );
43441095
@@ -4363,7 +1114,7 @@
43631114
43641115 // 27)
43651116 {
4366- COSNode *_root = lexer.StartProduction( "value=*ptr+1;" );
1117+ COSNode *_root = cosEnv.Compile( "value=*ptr+1;" );
43671118
43681119 AssignmentOperation *root = dynamic_cast <AssignmentOperation*> ( _root );
43691120
@@ -4403,7 +1154,7 @@
44031154
44041155 // 28)
44051156 {
4406- COSNode *_root = lexer.StartProduction( "delete object;" );
1157+ COSNode *_root = cosEnv.Compile( "delete object;" );
44071158
44081159 DeleteOperation *root = dynamic_cast <DeleteOperation*> ( _root );
44091160
@@ -4420,7 +1171,7 @@
44201171
44211172 // 29)
44221173 {
4423- COSNode *_root = lexer.StartProduction( "mydata *obj = new mydata;" );
1174+ COSNode *_root = cosEnv.Compile( "mydata *obj = new mydata;" );
44241175
44251176 DeclarationStatement *root = dynamic_cast <DeclarationStatement*> ( _root );
44261177
@@ -4463,7 +1214,7 @@
44631214
44641215 // 30)
44651216 {
4466- COSNode *_root = lexer.StartProduction( "(2 | 1 & 0) == 2;" );
1217+ COSNode *_root = cosEnv.Compile( "(2 | 1 & 0) == 2;" );
44671218
44681219 CompareEqualityOperation *root = dynamic_cast <CompareEqualityOperation*> ( _root );
44691220
@@ -4510,7 +1261,7 @@
45101261
45111262 // 31)
45121263 {
4513- COSNode *_root = lexer.StartProduction( "(10|~0)==10;" );
1264+ COSNode *_root = cosEnv.Compile( "(10|~0)==10;" );
45141265
45151266 CompareEqualityOperation *root = dynamic_cast <CompareEqualityOperation*> ( _root );
45161267
@@ -4557,7 +1308,7 @@
45571308 {
45581309 // 1)
45591310 {
4560- COSNode *_root = lexer.StartProduction( "if (1==1){ a=2; }else{ a = 4; }" );
1311+ COSNode *_root = cosEnv.Compile( "if (1==1){ a=2; }else{ a = 4; }" );
45611312
45621313 IfStatement *root = dynamic_cast <IfStatement*> ( _root );
45631314
@@ -4627,7 +1378,7 @@
46271378
46281379 // 2)
46291380 {
4630- COSNode *_root = lexer.StartProduction( "{a=2; {b=3;}} 2=1;" );
1381+ COSNode *_root = cosEnv.Compile( "{a=2; {b=3;}} 2=1;" );
46311382
46321383 Program *root = dynamic_cast <Program*> ( _root );
46331384
@@ -4703,7 +1454,7 @@
47031454
47041455 // 3)
47051456 {
4706- COSNode *_root = lexer.StartProduction( "while(true)0==0;" );
1457+ COSNode *_root = cosEnv.Compile( "while(true)0==0;" );
47071458
47081459 WhileLoopStatement *root = dynamic_cast <WhileLoopStatement*> ( _root );
47091460
@@ -4738,7 +1489,7 @@
47381489
47391490 // 4)
47401491 {
4741- COSNode *_root = lexer.StartProduction( "while(a<2){a++;if(a==2)break;}" );
1492+ COSNode *_root = cosEnv.Compile( "while(a<2){a++;if(a==2)break;}" );
47421493
47431494 WhileLoopStatement *root = dynamic_cast <WhileLoopStatement*> ( _root );
47441495
@@ -4816,7 +1567,7 @@
48161567
48171568 // 5)
48181569 {
4819- COSNode *_root = lexer.StartProduction( "if(false)t=0;" );
1570+ COSNode *_root = cosEnv.Compile( "if(false)t=0;" );
48201571
48211572 IfStatement *root = dynamic_cast <IfStatement*> ( _root );
48221573
@@ -4853,7 +1604,7 @@
48531604
48541605 // 6)
48551606 {
4856- COSNode *_root = lexer.StartProduction( "for(n=0;n<5;n++){output(n);continue;}" );
1607+ COSNode *_root = cosEnv.Compile( "for(n=0;n<5;n++){output(n);continue;}" );
48571608
48581609 ForLoopStatement *root = dynamic_cast <ForLoopStatement*> ( _root );
48591610
@@ -4950,7 +1701,7 @@
49501701
49511702 // 7)
49521703 {
4953- COSNode *_root = lexer.StartProduction( "while(true){i++;for(n=0;n<i;n++){print(n);if(doBreak())break;}continue;}" );
1704+ COSNode *_root = cosEnv.Compile( "while(true){i++;for(n=0;n<i;n++){print(n);if(doBreak())break;}continue;}" );
49541705
49551706 WhileLoopStatement *root = dynamic_cast <WhileLoopStatement*> ( _root );
49561707
@@ -5107,7 +1858,7 @@
51071858
51081859 // 8)
51091860 {
5110- COSNode *_root = lexer.StartProduction( "try{if(a=0)throw;}catch(){a=1;}" );
1861+ COSNode *_root = cosEnv.Compile( "try{if(a=0)throw;}catch(){a=1;}" );
51111862
51121863 TryStatement *root = dynamic_cast <TryStatement*> ( _root );
51131864
@@ -5190,7 +1941,7 @@
51901941
51911942 // 9)
51921943 {
5193- COSNode *_root = lexer.StartProduction( "try{int arg=3;dangerousFunc(arg,false);}catch(danger d){print(d.reason);}catch(fatal_error e){exit(e.code);}" );
1944+ COSNode *_root = cosEnv.Compile( "try{int arg=3;dangerousFunc(arg,false);}catch(danger d){print(d.reason);}catch(fatal_error e){exit(e.code);}" );
51941945
51951946 TryStatement *root = dynamic_cast <TryStatement*> ( _root );
51961947
@@ -5389,7 +2140,7 @@
53892140
53902141 // 10)
53912142 {
5392- COSNode *_root = lexer.StartProduction( "try{while(true)throw 1;}catch(int){}" );
2143+ COSNode *_root = cosEnv.Compile( "try{while(true)throw 1;}catch(int){}" );
53932144
53942145 TryStatement *root = dynamic_cast <TryStatement*> ( _root );
53952146
@@ -5459,7 +2210,7 @@
54592210
54602211 // 11)
54612212 {
5462- COSNode *_root = lexer.StartProduction( "try throw 0;catch(int)throw fatal;" );
2213+ COSNode *_root = cosEnv.Compile( "try throw 0;catch(int)throw fatal;" );
54632214
54642215 TryStatement *root = dynamic_cast <TryStatement*> ( _root );
54652216
@@ -5515,7 +2266,7 @@
55152266
55162267 // 12)
55172268 {
5518- COSNode *_root = lexer.StartProduction( "if(bound){unbind();}else if(is_binding){abortBinding();}" );
2269+ COSNode *_root = cosEnv.Compile( "if(bound){unbind();}else if(is_binding){abortBinding();}" );
55192270
55202271 IfStatement *root = dynamic_cast <IfStatement*> ( _root );
55212272
@@ -5588,7 +2339,7 @@
55882339 {
55892340 // 1)
55902341 {
5591- COSNode *_root = lexer.StartProduction( "int func test() { return 0; }" );
2342+ COSNode *_root = cosEnv.Compile( "int func test() { return 0; }" );
55922343
55932344 DeclarationStatement *root = dynamic_cast <DeclarationStatement*> ( _root );
55942345
@@ -5637,7 +2388,7 @@
56372388
56382389 // 2)
56392390 {
5640- COSNode *_root = lexer.StartProduction( "any func doit(any p1, any p2){p1+=p2;p1+=getvalue();return p1;}" );
2391+ COSNode *_root = cosEnv.Compile( "any func doit(any p1, any p2){p1+=p2;p1+=getvalue();return p1;}" );
56412392
56422393 DeclarationStatement *root = dynamic_cast <DeclarationStatement*> ( _root );
56432394
@@ -5769,7 +2520,7 @@
57692520
57702521 // 3)
57712522 {
5772- COSNode *_root = lexer.StartProduction( "any func get(int a) return a+1;" );
2523+ COSNode *_root = cosEnv.Compile( "any func get(int a) return a+1;" );
57732524
57742525 DeclarationStatement *root = dynamic_cast <DeclarationStatement*> ( _root );
57752526
@@ -5843,7 +2594,7 @@
58432594
58442595 // 4)
58452596 {
5846- COSNode *_root = lexer.StartProduction( "any func set(any key, any value=2){ map[key] = value; }" );
2597+ COSNode *_root = cosEnv.Compile( "any func set(any key, any value=2){ map[key] = value; }" );
58472598
58482599 DeclarationStatement *root = dynamic_cast <DeclarationStatement*> ( _root );
58492600
@@ -5956,7 +2707,7 @@
59562707
59572708 // 5)
59582709 {
5959- COSNode *_root = lexer.StartProduction( "any func operator + (any left, any right) {if(type(left)==int&&type(right)==int)return builtin_add(left,right);}" );
2710+ COSNode *_root = cosEnv.Compile( "any func operator + (any left, any right) {if(type(left)==int&&type(right)==int)return builtin_add(left,right);}" );
59602711
59612712 DeclarationStatement *root = dynamic_cast <DeclarationStatement*> ( _root );
59622713
@@ -6132,7 +2883,7 @@
61322883
61332884 // 6)
61342885 {
6135- COSNode *_root = lexer.StartProduction( "int func main(int argc, char*argv[]){while(true){if(runtime==false)return -1;}return 0;}" );
2886+ COSNode *_root = cosEnv.Compile( "int func main(int argc, char*argv[]){while(true){if(runtime==false)return -1;}return 0;}" );
61362887
61372888 DeclarationStatement *root = dynamic_cast <DeclarationStatement*> ( _root );
61382889
@@ -6295,7 +3046,7 @@
62953046 {
62963047 // 1)
62973048 {
6298- COSNode *_root = lexer.StartProduction( "int a=1;" );
3049+ COSNode *_root = cosEnv.Compile( "int a=1;" );
62993050
63003051 DeclarationStatement *root = dynamic_cast <DeclarationStatement*> ( _root );
63013052
@@ -6326,7 +3077,7 @@
63263077
63273078 // 2)
63283079 {
6329- COSNode *_root = lexer.StartProduction( "int *a = &b;" );
3080+ COSNode *_root = cosEnv.Compile( "int *a = &b;" );
63303081
63313082 DeclarationStatement *root = dynamic_cast <DeclarationStatement*> ( _root );
63323083
@@ -6367,7 +3118,7 @@
63673118
63683119 // 3)
63693120 {
6370- COSNode *_root = lexer.StartProduction( "int **a;" );
3121+ COSNode *_root = cosEnv.Compile( "int **a;" );
63713122
63723123 DeclarationStatement *root = dynamic_cast <DeclarationStatement*> ( _root );
63733124
@@ -6402,7 +3153,7 @@
64023153
64033154 // 4)
64043155 {
6405- COSNode *_root = lexer.StartProduction( "int arr[]={1, 2, 3};" );
3156+ COSNode *_root = cosEnv.Compile( "int arr[]={1, 2, 3};" );
64063157
64073158 DeclarationStatement *root = dynamic_cast <DeclarationStatement*> ( _root );
64083159
@@ -6459,7 +3210,7 @@
64593210
64603211 // 5)
64613212 {
6462- COSNode *_root = lexer.StartProduction( "int arr[][] = {{1,2,3},{4,5,6}};" );
3213+ COSNode *_root = cosEnv.Compile( "int arr[][] = {{1,2,3},{4,5,6}};" );
64633214
64643215 DeclarationStatement *root = dynamic_cast <DeclarationStatement*> ( _root );
64653216
@@ -6555,7 +3306,7 @@
65553306
65563307 // 6)
65573308 {
6558- COSNode *_root = lexer.StartProduction( "int value(42);" );
3309+ COSNode *_root = cosEnv.Compile( "int value(42);" );
65593310
65603311 DeclarationStatement *root = dynamic_cast <DeclarationStatement*> ( _root );
65613312
@@ -6592,7 +3343,7 @@
65923343
65933344 // 7)
65943345 {
6595- COSNode *_root = lexer.StartProduction( "namespace lang{int impl = 0;}" );
3346+ COSNode *_root = cosEnv.Compile( "namespace lang{int impl = 0;}" );
65963347
65973348 NamespaceStatement *root = dynamic_cast <NamespaceStatement*> ( _root );
65983349
@@ -6643,7 +3394,7 @@
66433394
66443395 // 9)
66453396 {
6646- COSNode *_root = lexer.StartProduction( "using namespace ruby;" );
3397+ COSNode *_root = cosEnv.Compile( "using namespace ruby;" );
66473398
66483399 UsingNamespaceStatement *root = dynamic_cast <UsingNamespaceStatement*> ( _root );
66493400
@@ -6660,7 +3411,7 @@
66603411
66613412 // 10)
66623413 {
6663- COSNode *_root = lexer.StartProduction( "float3 vec3(12,-7,3);" );
3414+ COSNode *_root = cosEnv.Compile( "float3 vec3(12,-7,3);" );
66643415
66653416 DeclarationStatement *root = dynamic_cast <DeclarationStatement*> ( _root );
66663417
@@ -6718,7 +3469,7 @@
67183469 {
67193470 // 1)
67203471 {
6721- COSNode *_root = lexer.StartProduction( "struct mydata{int field;};" );
3472+ COSNode *_root = cosEnv.Compile( "struct mydata{int field;};" );
67223473
67233474 StructDefinition *root = dynamic_cast <StructDefinition*> ( _root );
67243475
@@ -6761,7 +3512,7 @@
67613512
67623513 // 2)
67633514 {
6764- COSNode *_root = lexer.StartProduction( R"RAW(
3515+ COSNode *_root = cosEnv.Compile( R"RAW(
67653516 struct test {
67663517 constructor() {
67673518 value = 1;
@@ -6948,9 +3699,7 @@
69483699
69493700 // 3)
69503701 {
6951- // TODO: add the -> operator to COS.
6952-
6953- COSNode *_root = lexer.StartProduction( R"RAW(
3702+ COSNode *_root = cosEnv.Compile( R"RAW(
69543703 struct logger {
69553704 void func print( string msg ) {
69563705 buffer.append(msg);
@@ -7165,7 +3914,7 @@
71653914
71663915 // 4)
71673916 {
7168- COSNode *_root = lexer.StartProduction( "typedef int number;" );
3917+ COSNode *_root = cosEnv.Compile( "typedef int number;" );
71693918
71703919 TypedefStatement *root = dynamic_cast <TypedefStatement*> ( _root );
71713920
@@ -7189,7 +3938,7 @@
71893938
71903939 // 5)
71913940 {
7192- COSNode *_root = lexer.StartProduction( "struct anyT;" );
3941+ COSNode *_root = cosEnv.Compile( "struct anyT;" );
71933942
71943943 DeclarationStatement *root = dynamic_cast <DeclarationStatement*> ( _root );
71953944
@@ -7214,7 +3963,7 @@
72143963
72153964 // 6)
72163965 {
7217- COSNode *_root = lexer.StartProduction( "$[getnumbertype()] value = 0;" );
3966+ COSNode *_root = cosEnv.Compile( "$[getnumbertype()] value = 0;" );
72183967
72193968 DeclarationStatement *root = dynamic_cast <DeclarationStatement*> ( _root );
72203969
@@ -7256,7 +4005,7 @@
72564005
72574006 // 7)
72584007 {
7259- COSNode *_root = lexer.StartProduction( "$[1]$[0] = int;" );
4008+ COSNode *_root = cosEnv.Compile( "$[1]$[0] = int;" );
72604009
72614010 DeclarationStatement *root = dynamic_cast <DeclarationStatement*> ( _root );
72624011
@@ -7297,7 +4046,7 @@
72974046
72984047 // 8)
72994048 {
7300- COSNode *_root = lexer.StartProduction( "test obj();" );
4049+ COSNode *_root = cosEnv.Compile( "test obj();" );
73014050
73024051 DeclarationStatement *root = dynamic_cast <DeclarationStatement*> ( _root );
73034052
@@ -7328,7 +4077,7 @@
73284077
73294078 // 9)
73304079 {
7331- COSNode *_root = lexer.StartProduction( "test[obj()]();" );
4080+ COSNode *_root = cosEnv.Compile( "test[obj()]();" );
73324081
73334082 FunctionCallOperation *root = dynamic_cast <FunctionCallOperation*> ( _root );
73344083
@@ -7364,7 +4113,7 @@
73644113
73654114 // 10)
73664115 {
7367- COSNode *_root = lexer.StartProduction( "int mydata.newfield = 0;" );
4116+ COSNode *_root = cosEnv.Compile( "int mydata.newfield = 0;" );
73684117
73694118 DeclarationStatement *root = dynamic_cast <DeclarationStatement*> ( _root );
73704119
@@ -7407,7 +4156,7 @@
74074156
74084157 // 11)
74094158 {
7410- COSNode *_root = lexer.StartProduction( "int a = 0; int& b = a;" );
4159+ COSNode *_root = cosEnv.Compile( "int a = 0; int& b = a;" );
74114160
74124161 Program *root = dynamic_cast <Program*> ( _root );
74134162
@@ -7475,7 +4224,7 @@
74754224
74764225 // 12)
74774226 {
7478- COSNode *_root = lexer.StartProduction( "typedef int *a, b, &c;" );
4227+ COSNode *_root = cosEnv.Compile( "typedef int *a, b, &c;" );
74794228
74804229 MultiTypedefStatement *root = dynamic_cast <MultiTypedefStatement*> ( _root );
74814230
@@ -7543,7 +4292,7 @@
75434292
75444293 // 13)
75454294 {
7546- COSNode *_root = lexer.StartProduction( "typedef void func (*myproto)(int);" );
4295+ COSNode *_root = cosEnv.Compile( "typedef void func (*myproto)(int);" );
75474296
75484297 TypedefStatement *root = dynamic_cast <TypedefStatement*> ( _root );
75494298
@@ -7592,7 +4341,7 @@
75924341
75934342 // 14)
75944343 {
7595- COSNode *_root = lexer.StartProduction( "typedef int func (&rcodef)(), *func (*pushcode)(int);" );
4344+ COSNode *_root = cosEnv.Compile( "typedef int func (&rcodef)(), *func (*pushcode)(int);" );
75964345
75974346 MultiTypedefStatement *root = dynamic_cast <MultiTypedefStatement*> ( _root );
75984347
@@ -7676,7 +4425,7 @@
76764425
76774426 // 15)
76784427 {
7679- COSNode *_root = lexer.StartProduction( "typedef int func (*func (*getmethodf)())();" );
4428+ COSNode *_root = cosEnv.Compile( "typedef int func (*func (*getmethodf)())();" );
76804429
76814430 TypedefStatement *root = dynamic_cast <TypedefStatement*> ( _root );
76824431
@@ -7726,7 +4475,7 @@
77264475 {
77274476 // 1)
77284477 {
7729- COSNode *_root = lexer.StartProduction( "template variation <int> var;" );
4478+ COSNode *_root = cosEnv.Compile( "template variation <int> var;" );
77304479
77314480 DeclarationStatement *root = dynamic_cast <DeclarationStatement*> ( _root );
77324481
@@ -7764,7 +4513,7 @@
77644513
77654514 // 2)
77664515 {
7767- COSNode *_root = lexer.StartProduction( "container.template memb <float>.value;" );
4516+ COSNode *_root = cosEnv.Compile( "container.template memb <float>.value;" );
77684517
77694518 DotOperation *root = dynamic_cast <DotOperation*> ( _root );
77704519
@@ -7813,7 +4562,7 @@
78134562
78144563 // 3)
78154564 {
7816- COSNode *_root = lexer.StartProduction( "template (template meta <void>) <int>;" );
4565+ COSNode *_root = cosEnv.Compile( "template (template meta <void>) <int>;" );
78174566
78184567 TemplateInstantiationOperation *root = dynamic_cast <TemplateInstantiationOperation*> ( _root );
78194568
@@ -7851,7 +4600,7 @@
78514600
78524601 // 4)
78534602 {
7854- COSNode *_root = lexer.StartProduction( "template first <int>.template second <long>;" );
4603+ COSNode *_root = cosEnv.Compile( "template first <int>.template second <long>;" );
78554604
78564605 TemplateInstantiationOperation *root = dynamic_cast <TemplateInstantiationOperation*> ( _root );
78574606
@@ -7901,7 +4650,7 @@
79014650
79024651 // 5)
79034652 {
7904- COSNode *_root = lexer.StartProduction( "template (template first <int>.second) <long>;" );
4653+ COSNode *_root = cosEnv.Compile( "template (template first <int>.second) <long>;" );
79054654
79064655 TemplateInstantiationOperation *root = dynamic_cast <TemplateInstantiationOperation*> ( _root );
79074656
@@ -7955,7 +4704,7 @@
79554704 {
79564705 // 1)
79574706 {
7958- COSNode *_root = lexer.StartProduction( "int a = 0;" );
4707+ COSNode *_root = cosEnv.Compile( "int a = 0;" );
79594708
79604709 DeclarationStatement *root = dynamic_cast <DeclarationStatement*> ( _root );
79614710
@@ -7986,7 +4735,7 @@
79864735
79874736 // 2)
79884737 {
7989- COSNode *_root = lexer.StartProduction( "void func myway(bool b){ b = false; }" );
4738+ COSNode *_root = cosEnv.Compile( "void func myway(bool b){ b = false; }" );
79904739
79914740 DeclarationStatement *root = dynamic_cast <DeclarationStatement*> ( _root );
79924741
@@ -8036,7 +4785,7 @@
80364785
80374786 // 3)
80384787 {
8039- COSNode *_root = lexer.StartProduction( "float *p = nullptr;" );
4788+ COSNode *_root = cosEnv.Compile( "float *p = nullptr;" );
80404789
80414790 DeclarationStatement *root = dynamic_cast <DeclarationStatement*> ( _root );
80424791
@@ -8072,7 +4821,7 @@
80724821
80734822 // 4)
80744823 {
8075- COSNode *_root = lexer.StartProduction( "int func (interrupts[]) ( int code ) {{return -1;},{g_var=code;return 1;}};" );
4824+ COSNode *_root = cosEnv.Compile( "int func (interrupts[]) ( int code ) {{return -1;},{g_var=code;return 1;}};" );
80764825
80774826 DeclarationStatement *root = dynamic_cast <DeclarationStatement*> ( _root );
80784827
@@ -8194,7 +4943,7 @@
81944943
81954944 // 5)
81964945 {
8197- COSNode *_root = lexer.StartProduction( "void func (*protos[])(int) = {nullptr};" );
4946+ COSNode *_root = cosEnv.Compile( "void func (*protos[])(int) = {nullptr};" );
81984947
81994948 DeclarationStatement *root = dynamic_cast <DeclarationStatement*> ( _root );
82004949
@@ -8267,7 +5016,7 @@
82675016
82685017 // 7)
82695018 {
8270- COSNode *_root = lexer.StartProduction( "float vector[] = {0,1,2};" );
5019+ COSNode *_root = cosEnv.Compile( "float vector[] = {0,1,2};" );
82715020
82725021 DeclarationStatement *root = dynamic_cast <DeclarationStatement*> ( _root );
82735022
@@ -8324,7 +5073,7 @@
83245073
83255074 // 8)
83265075 {
8327- COSNode *_root = lexer.StartProduction( "double matrix[][] = {{7,3},{5,8}};" );
5076+ COSNode *_root = cosEnv.Compile( "double matrix[][] = {{7,3},{5,8}};" );
83285077
83295078 DeclarationStatement *root = dynamic_cast <DeclarationStatement*> ( _root );
83305079
@@ -8406,7 +5155,7 @@
84065155
84075156 // 9)
84085157 {
8409- COSNode *_root = lexer.StartProduction( "int tab[]{42,9001};" );
5158+ COSNode *_root = cosEnv.Compile( "int tab[]{42,9001};" );
84105159
84115160 DeclarationStatement *root = dynamic_cast <DeclarationStatement*> ( _root );
84125161
@@ -8461,7 +5210,7 @@
84615210
84625211 // 11)
84635212 {
8464- COSNode *_root = lexer.StartProduction( "int imat[][]{{21,37},{80,28}};" );
5213+ COSNode *_root = cosEnv.Compile( "int imat[][]{{21,37},{80,28}};" );
84655214
84665215 DeclarationStatement *root = dynamic_cast <DeclarationStatement*> ( _root );
84675216
@@ -8547,7 +5296,7 @@
85475296 {
85485297 // 1)
85495298 {
8550- COSNode *_root = lexer.StartProduction( "int a;" );
5299+ COSNode *_root = cosEnv.Compile( "int a;" );
85515300
85525301 DeclarationStatement *root = dynamic_cast <DeclarationStatement*> ( _root );
85535302
@@ -8572,7 +5321,7 @@
85725321
85735322 // 2)
85745323 {
8575- COSNode *_root = lexer.StartProduction( "int *a;" );
5324+ COSNode *_root = cosEnv.Compile( "int *a;" );
85765325
85775326 DeclarationStatement *root = dynamic_cast <DeclarationStatement*> ( _root );
85785327
@@ -8602,7 +5351,7 @@
86025351
86035352 // 3)
86045353 {
8605- COSNode *_root = lexer.StartProduction( "int **b;" );
5354+ COSNode *_root = cosEnv.Compile( "int **b;" );
86065355
86075356 DeclarationStatement *root = dynamic_cast <DeclarationStatement*> ( _root );
86085357
@@ -8637,7 +5386,7 @@
86375386
86385387 // 4)
86395388 {
8640- COSNode *_root = lexer.StartProduction( "bool& a;" );
5389+ COSNode *_root = cosEnv.Compile( "bool& a;" );
86415390
86425391 DeclarationStatement *root = dynamic_cast <DeclarationStatement*> ( _root );
86435392
@@ -8667,7 +5416,7 @@
86675416
86685417 // 5)
86695418 {
8670- COSNode *_root = lexer.StartProduction( "bool*& c;" );
5419+ COSNode *_root = cosEnv.Compile( "bool*& c;" );
86715420
86725421 DeclarationStatement *root = dynamic_cast <DeclarationStatement*> ( _root );
86735422
@@ -8702,7 +5451,7 @@
87025451
87035452 // 6)
87045453 {
8705- COSNode *_root = lexer.StartProduction( "void func (*proto)(int p1, int p2);" );
5454+ COSNode *_root = cosEnv.Compile( "void func (*proto)(int p1, int p2);" );
87065455
87075456 DeclarationStatement *root = dynamic_cast <DeclarationStatement*> ( _root );
87085457
@@ -8776,7 +5525,7 @@
87765525
87775526 // 7)
87785527 {
8779- COSNode *_root = lexer.StartProduction( "int func (**pproto)();" );
5528+ COSNode *_root = cosEnv.Compile( "int func (**pproto)();" );
87805529
87815530 DeclarationStatement *root = dynamic_cast <DeclarationStatement*> ( _root );
87825531
@@ -8817,7 +5566,7 @@
88175566
88185567 // 8)
88195568 {
8820- COSNode *_root = lexer.StartProduction( "void *unk[];" );
5569+ COSNode *_root = cosEnv.Compile( "void *unk[];" );
88215570
88225571 DeclarationStatement *root = dynamic_cast <DeclarationStatement*> ( _root );
88235572
@@ -8852,7 +5601,7 @@
88525601
88535602 // 9)
88545603 {
8855- COSNode *_root = lexer.StartProduction( "any var;" );
5604+ COSNode *_root = cosEnv.Compile( "any var;" );
88565605
88575606 DeclarationStatement *root = dynamic_cast <DeclarationStatement*> ( _root );
88585607
@@ -8877,7 +5626,7 @@
88775626
88785627 // 10)
88795628 {
8880- COSNode *_root = lexer.StartProduction( "template variant <int, void*> tvar;" );
5629+ COSNode *_root = cosEnv.Compile( "template variant <int, void*> tvar;" );
88815630
88825631 DeclarationStatement *root = dynamic_cast <DeclarationStatement*> ( _root );
88835632
@@ -8927,7 +5676,7 @@
89275676
89285677 // 11)
89295678 {
8930- COSNode *_root = lexer.StartProduction( "template variant <bool,int> func (*proto)(bool);" );
5679+ COSNode *_root = cosEnv.Compile( "template variant <bool,int> func (*proto)(bool);" );
89315680
89325681 DeclarationStatement *root = dynamic_cast <DeclarationStatement*> ( _root );
89335682
@@ -8998,7 +5747,7 @@
89985747 // 12)
89995748 {
90005749 #if 0
9001- COSNode *_root = lexer.StartProduction( "template (template templ <a>) <b> notimpl;" );
5750+ COSNode *_root = cosEnv.Compile( "template (template templ <a>) <b> notimpl;" );
90025751
90035752 DeclarationStatement *root = dynamic_cast <DeclarationStatement*> ( _root );
90045753
@@ -9050,7 +5799,7 @@
90505799
90515800 // 13)
90525801 {
9053- COSNode *_root = lexer.StartProduction( "void func (&refproto)();" );
5802+ COSNode *_root = cosEnv.Compile( "void func (&refproto)();" );
90545803
90555804 DeclarationStatement *root = dynamic_cast <DeclarationStatement*> ( _root );
90565805
@@ -9086,7 +5835,7 @@
90865835
90875836 // 14)
90885837 {
9089- COSNode *_root = lexer.StartProduction( "int* func (*f)();" );
5838+ COSNode *_root = cosEnv.Compile( "int* func (*f)();" );
90905839
90915840 DeclarationStatement *root = dynamic_cast <DeclarationStatement*> ( _root );
90925841
@@ -9127,7 +5876,7 @@
91275876
91285877 // 15)
91295878 {
9130- COSNode *_root = lexer.StartProduction( "void proc (*proto)(float);" );
5879+ COSNode *_root = cosEnv.Compile( "void proc (*proto)(float);" );
91315880
91325881 DeclarationStatement *root = dynamic_cast <DeclarationStatement*> ( _root );
91335882
@@ -9177,7 +5926,7 @@
91775926
91785927 // 16)
91795928 {
9180- COSNode *_root = lexer.StartProduction( "int a, b;" );
5929+ COSNode *_root = cosEnv.Compile( "int a, b;" );
91815930
91825931 MultiDeclarationStatement *root = dynamic_cast <MultiDeclarationStatement*> ( _root );
91835932
@@ -9224,7 +5973,7 @@
92245973
92255974 // 17)
92265975 {
9227- COSNode *_root = lexer.StartProduction( "void func (*p)(int), *unk;" );
5976+ COSNode *_root = cosEnv.Compile( "void func (*p)(int), *unk;" );
92285977
92295978 MultiDeclarationStatement *root = dynamic_cast <MultiDeclarationStatement*> ( _root );
92305979
@@ -9300,7 +6049,7 @@
93006049
93016050 // 18)
93026051 {
9303- COSNode *_root = lexer.StartProduction( "bool func (*p1)(), func (*p2)();" );
6052+ COSNode *_root = cosEnv.Compile( "bool func (*p1)(), func (*p2)();" );
93046053
93056054 MultiDeclarationStatement *root = dynamic_cast <MultiDeclarationStatement*> ( _root );
93066055
@@ -9368,7 +6117,7 @@
93686117
93696118 // 19)
93706119 {
9371- COSNode *_root = lexer.StartProduction( "int *arr[2];" );
6120+ COSNode *_root = cosEnv.Compile( "int *arr[2];" );
93726121
93736122 DeclarationStatement *root = dynamic_cast <DeclarationStatement*> ( _root );
93746123
@@ -9410,7 +6159,7 @@
94106159
94116160 // 20)
94126161 {
9413- COSNode *_root = lexer.StartProduction( "int func (*func (*getprotop)(int))(bool);" );
6162+ COSNode *_root = cosEnv.Compile( "int func (*func (*getprotop)(int))(bool);" );
94146163
94156164 DeclarationStatement *root = dynamic_cast <DeclarationStatement*> ( _root );
94166165
@@ -9484,7 +6233,7 @@
94846233
94856234 // 21)
94866235 {
9487- COSNode *_root = lexer.StartProduction( "float myvar, func (*func(*getp)())(float);" );
6236+ COSNode *_root = cosEnv.Compile( "float myvar, func (*func(*getp)())(float);" );
94886237
94896238 MultiDeclarationStatement *root = dynamic_cast <MultiDeclarationStatement*> ( _root );
94906239
Show on old repository browser