Last active
April 21, 2020 23:08
-
-
Save AbePralle/43ca8f8a74a4ef5a5fd001ad0e62f1d2 to your computer and use it in GitHub Desktop.
Cmd node example using new Node<<...>> convenience class
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # More Complex Cmd node example with multimethod-style visitor | |
| uses Utility/Node | |
| class Cmd : Node<<Cmd>> | |
| METHODS | |
| method is_literal->Logical | |
| return false | |
| endClass | |
| class CmdStatement : Cmd | |
| METHODS | |
| method init( operand:Cmd ) | |
| add( operand ) | |
| endClass | |
| class CmdPrint : CmdStatement | |
| METHODS | |
| method name->String: return "Print" | |
| endClass | |
| class CmdBinary : Cmd | |
| METHODS | |
| method init( left:Cmd, right:Cmd ) | |
| add( left ) | |
| add( right ) | |
| method symbol->String | |
| return "(undefined)" | |
| endClass | |
| class CmdBinary<<$name,$symbol>> : CmdBinary | |
| METHODS | |
| method name->String: return $name | |
| method symbol->String: return $symbol | |
| endClass | |
| class CmdAdd : CmdBinary<<"Add","+">>; | |
| class CmdSubtract : CmdBinary<<"Subtract","-">>; | |
| class CmdInt32( value:Int32 ) : Cmd | |
| METHODS | |
| method is_literal->Logical | |
| return true | |
| method name->String | |
| return value->String | |
| endClass | |
| class CPPWriter : NodeVisitor<<Cmd>> | |
| PROPERTIES | |
| builder = StringBuilder() | |
| code : String | |
| METHODS | |
| method init | |
| builder.println @|#include <cstdio> | |
| |using namespace std; | |
| | | |
| |int main() | |
| |{ | |
| builder.indent += 2 | |
| method handle( node:CmdPrint )->Cmd | |
| builder.print @|printf( "%d\n", | |
| visit( node.first ) | |
| builder.println " );" | |
| return node | |
| method handle( node:CmdBinary )->Cmd | |
| builder.print '(' | |
| visit( node.first ) | |
| builder.print node.symbol | |
| visit( node.last ) | |
| builder.print ')' | |
| return node | |
| method on( node:CmdInt32 ) | |
| builder.print node.value | |
| method to->String | |
| if (code is null) | |
| builder.indent -= 2 | |
| builder.println " return 0;" | |
| builder.println "}" | |
| code = builder->String | |
| endIf | |
| return code | |
| endClass | |
| local op = CmdPrint( CmdAdd(CmdInt32(3),CmdSubtract(CmdInt32(6),CmdInt32(2))) ) | |
| @trace op | |
| # op:Print(Add(3,Subtract(6,2))) | |
| # ConstantFolder().visit( op ) # another example of possibilities | |
| local writer = CPPWriter() | |
| writer.visit( op ) | |
| println writer | |
| # OUTPUT: | |
| # #include <cstdio> | |
| # using namespace std; | |
| # | |
| # int main() | |
| # { | |
| # printf( "%d\n",(3+(6-2)) ); | |
| # return 0; | |
| # } | |
| # class ConstantFolder : NodeVisitor<<Cmd>> | |
| # METHODS | |
| # method handle( cmd:CmdAdd )->Cmd | |
| # visit_children( cmd ) | |
| # if (cmd.first.is_literal and cmd.last.is_literal) | |
| # if (cmd.first instanceOf CmdInt32 and cmd.last instanceOf CmdInt32) | |
| # return visit( CmdInt32( (cmd.first as CmdInt32).value + (cmd.last as CmdInt32).value ) ) | |
| # endIf | |
| # endIf | |
| # return cmd | |
| # | |
| # method handle( cmd:CmdSubtract )->Cmd | |
| # visit_children( cmd ) | |
| # if (cmd.first.is_literal and cmd.last.is_literal) | |
| # if (cmd.first instanceOf CmdInt32 and cmd.last instanceOf CmdInt32) | |
| # return visit( CmdInt32( (cmd.first as CmdInt32).value - (cmd.last as CmdInt32).value ) ) | |
| # endIf | |
| # endIf | |
| # return cmd | |
| # endClass |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment