Skip to content

Instantly share code, notes, and snippets.

@AbePralle
Last active April 21, 2020 23:08
Show Gist options
  • Select an option

  • Save AbePralle/43ca8f8a74a4ef5a5fd001ad0e62f1d2 to your computer and use it in GitHub Desktop.

Select an option

Save AbePralle/43ca8f8a74a4ef5a5fd001ad0e62f1d2 to your computer and use it in GitHub Desktop.
Cmd node example using new Node<<...>> convenience class
# 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