32

GGX 2015 London, AST Transforms: Building a Simple Game Engine DSL For Kids

Embed Size (px)

Citation preview

Page 1: GGX 2015 London, AST Transforms: Building a Simple Game Engine DSL For Kids
Page 2: GGX 2015 London, AST Transforms: Building a Simple Game Engine DSL For Kids

Session Outline

•  Introduction – What we do at CoderDojo – Groovy as a first language – The Game Engine DSL

•  AST Transformations – Groovy Compilation Process – Building a simple State DSL

Page 3: GGX 2015 London, AST Transforms: Building a Simple Game Engine DSL For Kids
Page 4: GGX 2015 London, AST Transforms: Building a Simple Game Engine DSL For Kids

Photo Credit - Grace Hall Photography - Wexford

Page 5: GGX 2015 London, AST Transforms: Building a Simple Game Engine DSL For Kids

Why Groovy As A First Language?

What we are trying to do Computational thinking

Basic programming principles

What we don’t need to be able to do that Difficult syntax

Methods (initially) Classes (initially)

What we do need to be able to do that Simple commands

Keep the subject interesting Success straight away

Constant feedback

Page 6: GGX 2015 London, AST Transforms: Building a Simple Game Engine DSL For Kids

Simple things we did with Groovy for the Kids

Built a launcher script- contains helper methods to simplify the learning experience for the kids. Launcher for NetBeans Built a simple Groovy Editor IDE – based on GriffonConsole. Cloud 9 Integration

Page 7: GGX 2015 London, AST Transforms: Building a Simple Game Engine DSL For Kids

A Game DSL ?

Page 8: GGX 2015 London, AST Transforms: Building a Simple Game Engine DSL For Kids

Game Engine DSL page: "welcome" page: "players" page: "roundX" page: "roundO" page: "gameover" state: String playerX String playerO List players String winner def grid = [ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' ] event: "game_start" players = getPlayers() page = "players“ event: "select_players"

playerX = event.playerX playerO = event.playerO page = "roundX" event: "play_round" def player = getPlayer(event.player) player.playRound(grid) if (Grid.isSolved(grid)) { winner = event.player page = "gameover" } else { if (event.player == 'X') { page = "roundO" } else { page = "roundX" } } event: "game_end" page = "welcome"

Page 9: GGX 2015 London, AST Transforms: Building a Simple Game Engine DSL For Kids

The Game Server

Spring Boot Groovy Server Game Engine DSL is loaded and parsed at runtime Kids automated player Bot classes are loaded at runtime Game Controller handles events from the UI and dispatches them to the compiled Game Engine Session state in Mongo UI is a Mobile app built with jQuery mobile.

Page 10: GGX 2015 London, AST Transforms: Building a Simple Game Engine DSL For Kids

DEMO

Page 11: GGX 2015 London, AST Transforms: Building a Simple Game Engine DSL For Kids

What is an AST Transformation

Happens at Compile Time. Part of the compilation process. AST Abstract Syntax Tree. A data structure built by the compiler that represents your code. Transformation. Changing the nature of the code by creating or modifying it.

Page 12: GGX 2015 London, AST Transforms: Building a Simple Game Engine DSL For Kids

Compilers

•  Turn program code into executable code •  Compiler Frontend

Converts text into data structures that represent the Grammar of a language

•  Compiler Backend Converts those data structures into bytecode.

Page 13: GGX 2015 London, AST Transforms: Building a Simple Game Engine DSL For Kids

Elements of a Grammar

Lexical Elements. Words and Symbols. String, def, for, ; { + etc. Syntax. Words and Symbols together make phrases. Expressions and Statements Semantics. Context and Meaning AST is a representation of Syntax

Page 14: GGX 2015 London, AST Transforms: Building a Simple Game Engine DSL For Kids

Syntax vs Semantics

A Declaration Expression. def foo = [1, 2, 3]

An Assert Statement

assert foo == [1, 2, 3] Assert foo is only semantically correct in the context of the previous declaration.

Page 15: GGX 2015 London, AST Transforms: Building a Simple Game Engine DSL For Kids

When is the AST created 9 Groovy Compiler Phases Initialisation Opening files, configuring environment. Parsing Tokenisation of the Lexical Elements. Conversion Tokens are converted to a syntax representation, the AST. Semantic Analysis Consistency and validity checks. Canonicalisation Completes the generation of the AST. Instruction Selection Select which JDK bytecode set to use Class generation Enhancement of classes with Groovy metaClass etc Output Writes the .class file Finalisation Closes files, cleans up the environment.

Page 16: GGX 2015 London, AST Transforms: Building a Simple Game Engine DSL For Kids

What AST Transforms are NOT

•  Wouldn’t this be Cool? def json = {

"playerId": "1234567890", "name": "Nathan", "playerClass": "NathanPlayer”

}

•  Don’t have Token Tree transforms •  Groovy is not a Language toolkit •  Must work within the Syntax of the

Language

Page 17: GGX 2015 London, AST Transforms: Building a Simple Game Engine DSL For Kids

AST Structure

•  org.codehaus.groovy.ast.ASTNode – Every Node in the AST is one of these

– ModuleNode •  ClassNode •  MethodNode

–  BlockStatement

•  FieldNode •  PropertyNode

Page 18: GGX 2015 London, AST Transforms: Building a Simple Game Engine DSL For Kids

Statements and Expressions

•  Statement – AssertStatement – BlockStatement – CaseStatement

•  Expression – BinaryExpression – ClosureExpression – ConstantExpression

Page 19: GGX 2015 London, AST Transforms: Building a Simple Game Engine DSL For Kids

State Machine DSL

state:  "OFF"    state:  "ON"    event:  "toggle"    

 when:  "ON"        next  =  "OFF"      when:  "OFF"        next  =  "ON"  

Page 20: GGX 2015 London, AST Transforms: Building a Simple Game Engine DSL For Kids

DSL Syntax

•  state: "OFF” ConstantExpression Value is a String Has a label state

•  next = "ON” BinaryExpression leftExpression : VariableExpression rightExpression : ConstantExpression operator : equals

Page 21: GGX 2015 London, AST Transforms: Building a Simple Game Engine DSL For Kids

groovyConsole AST Viewer

•  demo

Page 22: GGX 2015 London, AST Transforms: Building a Simple Game Engine DSL For Kids

State Machine Pattern  

 

State  

StateContext()  

ConcreteStateA  

OnState()  

ConcreteStateB  

OffState()  

State  -­‐>  StateContext  ()  

LEDToggle()  

Context  

Page 23: GGX 2015 London, AST Transforms: Building a Simple Game Engine DSL For Kids

Transform DSL to Pattern

•  Hook our AST transformation into the compilation process

•  Analyze the DSL AST by walking the tree •  Transform the AST by

– Modifying nodes – Adding nodes – Removing nodes

Page 24: GGX 2015 London, AST Transforms: Building a Simple Game Engine DSL For Kids

Compile time integration

•  Write some tests. –  Exploits dependency configurations

•  Build a DSL jar –  META-INF/services/

org.codehaus.groovy.transform.ASTTransformation –  Include DSL jar as a dependency

•  Provide an ASTTransformation class

@GroovyASTTransformation (phase = CompilePhase.SEMANTIC_ANALYSIS) class StateMachineASTTransformation implements ASTTransformation { void visit(ASTNode[] nodes, SourceUnit source) { }}

Page 25: GGX 2015 London, AST Transforms: Building a Simple Game Engine DSL For Kids

Walking the AST

•  Visitor Pattern : GOF •  Local Transformation visits the adjacent

ASTNode •  Global Transformations visit the module •  GroovyClassVisitor visits classes •  GroovyCodeVisitor visits statements

– Event Statement implements visit(visitor)

Page 26: GGX 2015 London, AST Transforms: Building a Simple Game Engine DSL For Kids

Transforming the AST

•  Construct new Nodes and add them to the tree – classNode.addNode(methodNode)

•  Use ASTBuilder – buildFromCode() Literally – buildFromSpec() Builder style closures – buildFromString()

Page 27: GGX 2015 London, AST Transforms: Building a Simple Game Engine DSL For Kids

Structuring the AST

•  How do I know what to add and where!! •  Refer to the ASTBuilder Unit tests •  AST Inspector can help

– Structure the target code and inspect in groovyConsole in the ASTViewer

Page 28: GGX 2015 London, AST Transforms: Building a Simple Game Engine DSL For Kids

Lets Look at Code

•  Demo

Page 29: GGX 2015 London, AST Transforms: Building a Simple Game Engine DSL For Kids

Summary The art of the possible: What we can and cannot achieve with AST transforms Visitors : How to walk the AST tree Creating and Modifying the AST with Groovy AST api’s and ASTBuilder Consider mentoring at your own CoderDojo. And consider teaching Groovy.

Page 30: GGX 2015 London, AST Transforms: Building a Simple Game Engine DSL For Kids

Further Reading Groovy in Action. Chapter 9, 19 Appendix G GGX 2014 : Groovy AST Transformations and Type Checking Extensions. Jeff Brown GGX 2012 : Type Checking your DSLs. Cedric Champeau Cedrics Blog on Compiler Customizers. http://www.jroller.com/melix/entry/customizing_groovy_compilation_process The AST JavaDoc http://docs.groovy-lang.org/latest/html/api/org/codehaus/ groovy/ast/package-summary.html ASTBuilder Unit tests https://github.com/groovy/groovy-core/blob/master/src/test/org/codehaus/groovy/ast/builder/AstBuilderFromSpecificationTest.groovy My Book :-)

Page 31: GGX 2015 London, AST Transforms: Building a Simple Game Engine DSL For Kids

Groovy for Domain-specific Languages

Discount Codes for GGX Attendees

GGX2015 ebook 50% OFF

GGX2015 print 30% OFF

Offer Valid From

13 December 2015 to 31 December 2015

http://bit.ly/1XVgZnC @fdearle

Page 32: GGX 2015 London, AST Transforms: Building a Simple Game Engine DSL For Kids

tonyxrmdavidson

@TonyDavids0n

Tony Davidson

@fdearle

Fergal Dearle

fdearle