pulumi/pkg/encoding/decode_statements.go

173 lines
4.5 KiB
Go
Raw Normal View History

2017-01-16 16:47:41 +01:00
// Copyright 2016 Marapongo, Inc. All rights reserved.
package encoding
import (
"reflect"
Begin overhauling semantic phases This change further merges the new AST and MuPack/MuIL formats and abstractions into the core of the compiler. A good amount of the old code is gone now; I decided against ripping it all out in one fell swoop so that I can methodically check that we are preserving all relevant decisions and/or functionality we had in the old model. The changes are too numerous to outline in this commit message, however, here are the noteworthy ones: * Split up the notion of symbols and tokens, resulting in: - pkg/symbols for true compiler symbols (bound nodes) - pkg/tokens for name-based tokens, identifiers, constants * Several packages move underneath pkg/compiler: - pkg/ast becomes pkg/compiler/ast - pkg/errors becomes pkg/compiler/errors - pkg/symbols becomes pkg/compiler/symbols * pkg/ast/... becomes pkg/compiler/legacy/ast/... * pkg/pack/ast becomes pkg/compiler/ast. * pkg/options goes away, merged back into pkg/compiler. * All binding functionality moves underneath a dedicated package, pkg/compiler/binder. The legacy.go file contains cruft that will eventually go away, while the other files represent a halfway point between new and old, but are expected to stay roughly in the current shape. * All parsing functionality is moved underneath a new pkg/compiler/metadata namespace, and we adopt new terminology "metadata reading" since real parsing happens in the MetaMu compilers. Hence, Parser has become metadata.Reader. * In general phases of the compiler no longer share access to the actual compiler.Compiler object. Instead, shared state is moved to the core.Context object underneath pkg/compiler/core. * Dependency resolution during binding has been rewritten to the new model, including stashing bound package symbols in the context object, and detecting import cycles. * Compiler construction does not take a workspace object. Instead, creation of a workspace is entirely hidden inside of the compiler's constructor logic. * There are three Compile* functions on the Compiler interface, to support different styles of invoking compilation: Compile() auto- detects a Mu package, based on the workspace; CompilePath(string) loads the target as a Mu package and compiles it, regardless of the workspace settings; and, CompilePackage(*pack.Package) will compile a pre-loaded package AST, again regardless of workspace. * Delete the _fe, _sema, and parsetree phases. They are no longer relevant and the functionality is largely subsumed by the above. ...and so very much more. I'm surprised I ever got this to compile again!
2017-01-18 21:18:37 +01:00
"github.com/marapongo/mu/pkg/compiler/ast"
2017-01-16 16:47:41 +01:00
"github.com/marapongo/mu/pkg/util/contract"
"github.com/marapongo/mu/pkg/util/mapper"
2017-01-16 16:47:41 +01:00
)
func decodeStatement(m mapper.Mapper, tree mapper.Object) (ast.Statement, error) {
k, err := mapper.FieldString(tree, reflect.TypeOf((*ast.Statement)(nil)).Elem(), "kind", true)
2017-01-16 16:47:41 +01:00
if err != nil {
return nil, err
}
if k != nil {
kind := ast.NodeKind(*k)
switch kind {
// Blocks
case ast.BlockKind:
return decodeBlock(m, tree)
2017-01-16 16:47:41 +01:00
// Local variables
case ast.LocalVariableDeclarationKind:
return decodeLocalVariableDeclaration(m, tree)
2017-01-16 16:47:41 +01:00
// Try/catch/finally
case ast.TryCatchFinallyKind:
return decodeTryCatchFinally(m, tree)
2017-01-16 16:47:41 +01:00
// Branches
case ast.BreakStatementKind:
return decodeBreakStatement(m, tree)
2017-01-16 16:47:41 +01:00
case ast.ContinueStatementKind:
return decodeContinueStatement(m, tree)
2017-01-16 16:47:41 +01:00
case ast.IfStatementKind:
return decodeIfStatement(m, tree)
case ast.SwitchStatementKind:
return decodeSwitchStatement(m, tree)
2017-01-16 16:47:41 +01:00
case ast.LabeledStatementKind:
return decodeLabeledStatement(m, tree)
2017-01-16 16:47:41 +01:00
case ast.ReturnStatementKind:
return decodeReturnStatement(m, tree)
2017-01-16 16:47:41 +01:00
case ast.ThrowStatementKind:
return decodeThrowStatement(m, tree)
2017-01-16 16:47:41 +01:00
case ast.WhileStatementKind:
return decodeWhileStatement(m, tree)
2017-01-16 16:47:41 +01:00
// Miscellaneous
case ast.EmptyStatementKind:
return decodeEmptyStatement(m, tree)
2017-01-16 16:47:41 +01:00
case ast.MultiStatementKind:
return decodeMultiStatement(m, tree)
2017-01-16 16:47:41 +01:00
case ast.ExpressionStatementKind:
return decodeExpressionStatement(m, tree)
2017-01-16 16:47:41 +01:00
default:
contract.Failf("Unrecognized Statement kind: %v\n", kind)
2017-01-16 16:47:41 +01:00
}
}
return nil, nil
}
func decodeBlock(m mapper.Mapper, tree mapper.Object) (*ast.Block, error) {
2017-01-16 16:47:41 +01:00
var block ast.Block
if err := m.Decode(tree, &block); err != nil {
2017-01-16 16:47:41 +01:00
return nil, err
}
return &block, nil
}
func decodeLocalVariableDeclaration(m mapper.Mapper, tree mapper.Object) (*ast.LocalVariableDeclaration, error) {
2017-01-16 16:47:41 +01:00
var local ast.LocalVariableDeclaration
if err := m.Decode(tree, &local); err != nil {
2017-01-16 16:47:41 +01:00
return nil, err
}
return &local, nil
}
func decodeTryCatchFinally(m mapper.Mapper, tree mapper.Object) (*ast.TryCatchFinally, error) {
2017-01-16 16:47:41 +01:00
return nil, nil
}
func decodeBreakStatement(m mapper.Mapper, tree mapper.Object) (*ast.BreakStatement, error) {
2017-01-16 16:47:41 +01:00
var stmt ast.BreakStatement
if err := m.Decode(tree, &stmt); err != nil {
2017-01-16 16:47:41 +01:00
return nil, err
}
return &stmt, nil
}
func decodeContinueStatement(m mapper.Mapper, tree mapper.Object) (*ast.ContinueStatement, error) {
2017-01-16 16:47:41 +01:00
var stmt ast.ContinueStatement
if err := m.Decode(tree, &stmt); err != nil {
2017-01-16 16:47:41 +01:00
return nil, err
}
return &stmt, nil
}
func decodeIfStatement(m mapper.Mapper, tree mapper.Object) (*ast.IfStatement, error) {
var stmt ast.IfStatement
if err := m.Decode(tree, &stmt); err != nil {
return nil, err
}
return &stmt, nil
2017-01-16 16:47:41 +01:00
}
func decodeSwitchStatement(m mapper.Mapper, tree mapper.Object) (*ast.SwitchStatement, error) {
var stmt ast.SwitchStatement
if err := m.Decode(tree, &stmt); err != nil {
return nil, err
}
return &stmt, nil
}
func decodeLabeledStatement(m mapper.Mapper, tree mapper.Object) (*ast.LabeledStatement, error) {
var stmt ast.LabeledStatement
if err := m.Decode(tree, &stmt); err != nil {
return nil, err
}
return &stmt, nil
2017-01-16 16:47:41 +01:00
}
func decodeReturnStatement(m mapper.Mapper, tree mapper.Object) (*ast.ReturnStatement, error) {
var stmt ast.ReturnStatement
if err := m.Decode(tree, &stmt); err != nil {
return nil, err
}
return &stmt, nil
2017-01-16 16:47:41 +01:00
}
func decodeThrowStatement(m mapper.Mapper, tree mapper.Object) (*ast.ThrowStatement, error) {
var stmt ast.ThrowStatement
if err := m.Decode(tree, &stmt); err != nil {
return nil, err
}
return &stmt, nil
2017-01-16 16:47:41 +01:00
}
func decodeWhileStatement(m mapper.Mapper, tree mapper.Object) (*ast.WhileStatement, error) {
var stmt ast.WhileStatement
if err := m.Decode(tree, &stmt); err != nil {
return nil, err
}
return &stmt, nil
2017-01-16 16:47:41 +01:00
}
func decodeEmptyStatement(m mapper.Mapper, tree mapper.Object) (*ast.EmptyStatement, error) {
var stmt ast.EmptyStatement
if err := m.Decode(tree, &stmt); err != nil {
return nil, err
}
return &stmt, nil
2017-01-16 16:47:41 +01:00
}
func decodeMultiStatement(m mapper.Mapper, tree mapper.Object) (*ast.MultiStatement, error) {
var stmt ast.MultiStatement
if err := m.Decode(tree, &stmt); err != nil {
return nil, err
}
return &stmt, nil
2017-01-16 16:47:41 +01:00
}
func decodeExpressionStatement(m mapper.Mapper, tree mapper.Object) (*ast.ExpressionStatement, error) {
var stmt ast.ExpressionStatement
if err := m.Decode(tree, &stmt); err != nil {
return nil, err
}
return &stmt, nil
2017-01-16 16:47:41 +01:00
}