mirror of
https://github.com/johnkerl/miller.git
synced 2026-07-28 10:13:59 +00:00
for/while loops
This commit is contained in:
parent
775e9bbaa2
commit
2caed6c01c
26 changed files with 309590 additions and 292678 deletions
2
go/.gitignore
vendored
2
go/.gitignore
vendored
|
|
@ -4,3 +4,5 @@ bin/
|
|||
*.ast
|
||||
mkv.ast
|
||||
s
|
||||
mlrgo
|
||||
gg
|
||||
|
|
|
|||
|
|
@ -47,11 +47,14 @@ const (
|
|||
NodeTypeOperator = "Operator"
|
||||
NodeTypeFunctionCallsite = "FunctionCallsite"
|
||||
|
||||
NodeTypeBeginBlock = "BeginBlock"
|
||||
NodeTypeEndBlock = "EndBlock"
|
||||
NodeTypeIfChain = "IfChain"
|
||||
NodeTypeIfItem = "IfItem"
|
||||
NodeTypeForLoopKeyOnly = "ForLoopKeyOnly"
|
||||
NodeTypeBeginBlock = "BeginBlock"
|
||||
NodeTypeEndBlock = "EndBlock"
|
||||
NodeTypeIfChain = "IfChain"
|
||||
NodeTypeIfItem = "IfItem"
|
||||
NodeTypeWhileLoop = "WhileLoop"
|
||||
NodeTypeDoWhileLoop = "DoWhileLoop"
|
||||
NodeTypeForLoopKeyOnly = "ForLoopKeyOnly"
|
||||
NodeTypeForLoopKeyValue = "ForLoopKeyValue"
|
||||
|
||||
// A special token which causes a panic when evaluated. This is for
|
||||
// testing that AND/OR short-circuiting is implemented correctly: output =
|
||||
|
|
@ -240,7 +243,9 @@ func NewASTNodeBinaryNestable(itok, childA, childB interface{}, nodeType TNodeTy
|
|||
}
|
||||
|
||||
// Signature: Token Node Node Type
|
||||
func NewASTNodeBinary(itok, childA, childB interface{}, nodeType TNodeType) (*ASTNode, error) {
|
||||
func NewASTNodeBinary(
|
||||
itok, childA, childB interface{}, nodeType TNodeType,
|
||||
) (*ASTNode, error) {
|
||||
return NewASTNodeBinaryNestable(itok, childA, childB, nodeType), nil
|
||||
}
|
||||
|
||||
|
|
@ -250,6 +255,14 @@ func NewASTNodeTernary(itok, childA, childB, childC interface{}, nodeType TNodeT
|
|||
return parent, nil
|
||||
}
|
||||
|
||||
func NewASTNodeQuaternary(
|
||||
itok, childA, childB, childC, childD interface{}, nodeType TNodeType,
|
||||
) (*ASTNode, error) {
|
||||
parent := NewASTNodeNestable(itok, nodeType)
|
||||
convertToQuaternary(parent, childA, childB, childC, childD)
|
||||
return parent, nil
|
||||
}
|
||||
|
||||
// Pass-through expressions in the grammar sometimes need to be turned from
|
||||
// (ASTNode) to (ASTNode, error)
|
||||
func Nestable(iparent interface{}) (*ASTNode, error) {
|
||||
|
|
@ -287,6 +300,16 @@ func convertToTernary(iparent interface{}, childA, childB, childC interface{}) {
|
|||
parent.Children = children
|
||||
}
|
||||
|
||||
func convertToQuaternary(iparent interface{}, childA, childB, childC, childD interface{}) {
|
||||
parent := iparent.(*ASTNode)
|
||||
children := make([]*ASTNode, 4)
|
||||
children[0] = childA.(*ASTNode)
|
||||
children[1] = childB.(*ASTNode)
|
||||
children[2] = childC.(*ASTNode)
|
||||
children[3] = childD.(*ASTNode)
|
||||
parent.Children = children
|
||||
}
|
||||
|
||||
func PrependChild(iparent interface{}, ichild interface{}) (*ASTNode, error) {
|
||||
parent := iparent.(*ASTNode)
|
||||
child := ichild.(*ASTNode)
|
||||
|
|
@ -316,6 +339,12 @@ func AdoptChildren(iparent interface{}, ichild interface{}) (*ASTNode, error) {
|
|||
return parent, nil
|
||||
}
|
||||
|
||||
// TODO: comment
|
||||
func Wrap(inode interface{}) (*ASTNode, error) {
|
||||
node := inode.(*ASTNode)
|
||||
return node, nil
|
||||
}
|
||||
|
||||
func (this *ASTNode) CheckArity(
|
||||
arity int,
|
||||
) error {
|
||||
|
|
|
|||
|
|
@ -89,6 +89,8 @@ func BuildStatementBlockNode(astNode *dsl.ASTNode) (*StatementBlockNode, error)
|
|||
|
||||
// ----------------------------------------------------------------
|
||||
func (this *StatementBlockNode) Execute(state *State) error {
|
||||
state.stack.PushStackFrame()
|
||||
defer state.stack.PopStackFrame()
|
||||
|
||||
for _, statement := range this.executables {
|
||||
err := statement.Execute(state)
|
||||
|
|
|
|||
|
|
@ -1,31 +1,40 @@
|
|||
package cst
|
||||
|
||||
import (
|
||||
//"errors"
|
||||
"errors"
|
||||
|
||||
"miller/dsl"
|
||||
"miller/lib"
|
||||
//"miller/types"
|
||||
"miller/types"
|
||||
)
|
||||
|
||||
// ================================================================
|
||||
// This is for various flavors of for-loop
|
||||
// ================================================================
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
// ================================================================
|
||||
type ForLoopKeyOnlyNode struct {
|
||||
keyVariableName string
|
||||
mapNode IEvaluable
|
||||
statementBlockNode *StatementBlockNode
|
||||
}
|
||||
|
||||
func NewForLoopKeyOnlyNode(
|
||||
keyVariableName string,
|
||||
mapNode IEvaluable,
|
||||
statementBlockNode *StatementBlockNode,
|
||||
) *ForLoopKeyOnlyNode {
|
||||
return &ForLoopKeyOnlyNode{
|
||||
keyVariableName,
|
||||
mapNode,
|
||||
statementBlockNode,
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
// Sample AST:
|
||||
|
||||
// mlr -n put -v for (k in $*) { emit { k : k} }
|
||||
// mlr -n put -v 'for (k in $*) { emit { k : k } }'
|
||||
// DSL EXPRESSION:
|
||||
// for (k in $*) { emit { k : k} }
|
||||
// RAW AST:
|
||||
|
|
@ -42,11 +51,190 @@ func NewForLoopKeyOnlyNode(
|
|||
|
||||
func BuildForLoopKeyOnlyNode(astNode *dsl.ASTNode) (*ForLoopKeyOnlyNode, error) {
|
||||
lib.InternalCodingErrorIf(astNode.Type != dsl.NodeTypeForLoopKeyOnly)
|
||||
lib.InternalCodingErrorIf(len(astNode.Children) != 3)
|
||||
|
||||
return NewForLoopKeyOnlyNode(), nil
|
||||
keyVariableASTNode := astNode.Children[0]
|
||||
mapASTNode := astNode.Children[1]
|
||||
blockASTNode := astNode.Children[2]
|
||||
|
||||
lib.InternalCodingErrorIf(keyVariableASTNode.Type != dsl.NodeTypeLocalVariable)
|
||||
lib.InternalCodingErrorIf(keyVariableASTNode.Token == nil)
|
||||
keyVariableName := string(keyVariableASTNode.Token.Lit)
|
||||
|
||||
// TODO: error if loop-over node isn't Mappable (inasmuch as can be
|
||||
// detected at CST-build time)
|
||||
mapNode, err := BuildEvaluableNode(mapASTNode)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
statementBlockNode, err := BuildStatementBlockNode(blockASTNode)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewForLoopKeyOnlyNode(
|
||||
keyVariableName,
|
||||
mapNode,
|
||||
statementBlockNode,
|
||||
), nil
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
func (this *ForLoopKeyOnlyNode) Execute(state *State) error {
|
||||
|
||||
mlrval := this.mapNode.Evaluate(state)
|
||||
if !mlrval.IsMap() {
|
||||
// TODO: more
|
||||
return errors.New("Miller: looped-over item is not a map.")
|
||||
}
|
||||
mapval := mlrval.GetMap()
|
||||
|
||||
state.stack.PushStackFrame()
|
||||
defer state.stack.PopStackFrame()
|
||||
for pe := mapval.Head; pe != nil; pe = pe.Next {
|
||||
mapkey := types.MlrvalFromString(*pe.Key)
|
||||
|
||||
// Note: The statement-block has its own push/pop for its localvars.
|
||||
// Meanwhile we need to restrict scope of the bindvar to the for-loop.
|
||||
//
|
||||
// So we have:
|
||||
//
|
||||
// mlr put '
|
||||
// x = 1; <--- frame #1 main
|
||||
// for (k in $*) { <--- frame #2 for for-loop bindvars (right here)
|
||||
// x = 2 <--- frame #3 for for-loop locals
|
||||
// }
|
||||
// x = 3; <--- back in frame #1 main
|
||||
// '
|
||||
//
|
||||
|
||||
state.stack.BindVariable(this.keyVariableName, &mapkey)
|
||||
//state.stack.Dump()
|
||||
err := this.statementBlockNode.Execute(state)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
type ForLoopKeyValueNode struct {
|
||||
keyVariableName string
|
||||
valueVariableName string
|
||||
mapNode IEvaluable
|
||||
statementBlockNode *StatementBlockNode
|
||||
}
|
||||
|
||||
func NewForLoopKeyValueNode(
|
||||
keyVariableName string,
|
||||
valueVariableName string,
|
||||
mapNode IEvaluable,
|
||||
statementBlockNode *StatementBlockNode,
|
||||
) *ForLoopKeyValueNode {
|
||||
return &ForLoopKeyValueNode{
|
||||
keyVariableName,
|
||||
valueVariableName,
|
||||
mapNode,
|
||||
statementBlockNode,
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
// Sample AST:
|
||||
|
||||
// mlr -n put -v 'for (k, v in $*) { emit { k : v } }'
|
||||
// DSL EXPRESSION:
|
||||
// for (k, v in $*) { emit { k : v } }
|
||||
// RAW AST:
|
||||
// * StatementBlock
|
||||
// * ForLoopKeyValue "for"
|
||||
// * LocalVariable "k"
|
||||
// * LocalVariable "v"
|
||||
// * FullSrec "$*"
|
||||
// * StatementBlock
|
||||
// * EmitStatement "emit"
|
||||
// * MapLiteral "{}"
|
||||
// * MapLiteralKeyValuePair ":"
|
||||
// * LocalVariable "k"
|
||||
// * LocalVariable "v"
|
||||
|
||||
func BuildForLoopKeyValueNode(astNode *dsl.ASTNode) (*ForLoopKeyValueNode, error) {
|
||||
lib.InternalCodingErrorIf(astNode.Type != dsl.NodeTypeForLoopKeyValue)
|
||||
lib.InternalCodingErrorIf(len(astNode.Children) != 4)
|
||||
|
||||
keyVariableASTNode := astNode.Children[0]
|
||||
valueVariableASTNode := astNode.Children[1]
|
||||
mapASTNode := astNode.Children[2]
|
||||
blockASTNode := astNode.Children[3]
|
||||
|
||||
lib.InternalCodingErrorIf(keyVariableASTNode.Type != dsl.NodeTypeLocalVariable)
|
||||
lib.InternalCodingErrorIf(keyVariableASTNode.Token == nil)
|
||||
keyVariableName := string(keyVariableASTNode.Token.Lit)
|
||||
|
||||
lib.InternalCodingErrorIf(valueVariableASTNode.Type != dsl.NodeTypeLocalVariable)
|
||||
lib.InternalCodingErrorIf(valueVariableASTNode.Token == nil)
|
||||
valueVariableName := string(valueVariableASTNode.Token.Lit)
|
||||
|
||||
// TODO: error if loop-over node isn't Mappable (inasmuch as can be
|
||||
// detected at CST-build time)
|
||||
mapNode, err := BuildEvaluableNode(mapASTNode)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
statementBlockNode, err := BuildStatementBlockNode(blockASTNode)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewForLoopKeyValueNode(
|
||||
keyVariableName,
|
||||
valueVariableName,
|
||||
mapNode,
|
||||
statementBlockNode,
|
||||
), nil
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
func (this *ForLoopKeyValueNode) Execute(state *State) error {
|
||||
|
||||
mlrval := this.mapNode.Evaluate(state)
|
||||
if !mlrval.IsMap() {
|
||||
// TODO: more
|
||||
return errors.New("Miller: looped-over item is not a map.")
|
||||
}
|
||||
mapval := mlrval.GetMap()
|
||||
|
||||
state.stack.PushStackFrame()
|
||||
defer state.stack.PopStackFrame()
|
||||
for pe := mapval.Head; pe != nil; pe = pe.Next {
|
||||
mapkey := types.MlrvalFromString(*pe.Key)
|
||||
|
||||
// Note: The statement-block has its own push/pop for its localvars.
|
||||
// Meanwhile we need to restrict scope of the bindvar to the for-loop.
|
||||
//
|
||||
// So we have:
|
||||
//
|
||||
// mlr put '
|
||||
// x = 1; <--- frame #1 main
|
||||
// for (k in $*) { <--- frame #2 for for-loop bindvars (right here)
|
||||
// x = 2 <--- frame #3 for for-loop locals
|
||||
// }
|
||||
// x = 3; <--- back in frame #1 main
|
||||
// '
|
||||
//
|
||||
|
||||
state.stack.BindVariable(this.keyVariableName, &mapkey)
|
||||
state.stack.BindVariable(this.valueVariableName, pe.Value)
|
||||
//state.stack.Dump()
|
||||
err := this.statementBlockNode.Execute(state)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -325,7 +325,7 @@ var BUILTIN_FUNCTION_LOOKUP_TABLE = []FunctionInfo{
|
|||
name: "urandrange",
|
||||
},
|
||||
{
|
||||
name: "truncate",
|
||||
name: "truncate",
|
||||
binaryFunc: types.MlrvalTruncate,
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -36,6 +36,10 @@ func BuildLeafNode(
|
|||
return BuildFullOosvarRvalueNode(sval), nil
|
||||
break
|
||||
|
||||
case dsl.NodeTypeLocalVariable:
|
||||
return BuildLocalVariableNode(sval), nil
|
||||
break
|
||||
|
||||
case dsl.NodeTypeStringLiteral:
|
||||
return BuildStringLiteralNode(sval), nil
|
||||
break
|
||||
|
|
@ -125,6 +129,26 @@ func (this *FullOosvarRvalueNode) Evaluate(state *State) types.Mlrval {
|
|||
return types.MlrvalFromMap(state.Oosvars)
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
type LocalVariableNode struct {
|
||||
variableName string
|
||||
}
|
||||
|
||||
func BuildLocalVariableNode(variableName string) *LocalVariableNode {
|
||||
return &LocalVariableNode{
|
||||
variableName: variableName,
|
||||
}
|
||||
}
|
||||
func (this *LocalVariableNode) Evaluate(state *State) types.Mlrval {
|
||||
value := state.stack.ReadVariable(this.variableName)
|
||||
//state.stack.Dump()
|
||||
if value == nil {
|
||||
return types.MlrvalFromAbsent()
|
||||
} else {
|
||||
return *value
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
type StringLiteralNode struct {
|
||||
literal types.Mlrval
|
||||
|
|
|
|||
88
go/src/miller/dsl/cst/stack.go
Normal file
88
go/src/miller/dsl/cst/stack.go
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
package cst
|
||||
|
||||
import (
|
||||
"container/list"
|
||||
"fmt"
|
||||
|
||||
"miller/types"
|
||||
)
|
||||
|
||||
// ================================================================
|
||||
// Stack frames for begin/end/if/for/function blocks
|
||||
// ================================================================
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
type Stack struct {
|
||||
stackFrames *list.List // list of *StackFrame
|
||||
}
|
||||
|
||||
func NewStack() *Stack {
|
||||
return &Stack {
|
||||
stackFrames: list.New(),
|
||||
}
|
||||
}
|
||||
|
||||
func (this *Stack) PushStackFrame() {
|
||||
this.stackFrames.PushFront(NewStackFrame())
|
||||
}
|
||||
|
||||
func (this *Stack) PopStackFrame() {
|
||||
this.stackFrames.Remove(this.stackFrames.Front())
|
||||
}
|
||||
|
||||
func (this *Stack) BindVariable(name string, mlrval *types.Mlrval) {
|
||||
this.stackFrames.Front().Value.(*StackFrame).Bind(name, mlrval)
|
||||
}
|
||||
|
||||
// Returns nil on no-such
|
||||
func (this *Stack) ReadVariable(name string) *types.Mlrval {
|
||||
|
||||
// Scope-walk
|
||||
for entry := this.stackFrames.Front(); entry != nil; entry = entry.Next() {
|
||||
stackFrame := entry.Value.(*StackFrame)
|
||||
mlrval := stackFrame.ReadVariable(name)
|
||||
if mlrval != nil {
|
||||
return mlrval
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Returns nil on no-such
|
||||
func (this *Stack) Dump() {
|
||||
fmt.Printf("STACK FRAMES (count %d):\n", this.stackFrames.Len())
|
||||
for entry := this.stackFrames.Front(); entry != nil; entry = entry.Next() {
|
||||
stackFrame := entry.Value.(*StackFrame)
|
||||
fmt.Printf(" VARIABLES (count %d):\n", len(stackFrame.vars))
|
||||
for k, v := range(stackFrame.vars) {
|
||||
fmt.Printf(" %-16s %s\n", k, v.String())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
type StackFrame struct {
|
||||
// TODO: just a map for now. In the C impl, pre-computation of
|
||||
// name-to-array-slot indices was an important optimization, especially for
|
||||
// compute-intensive scenarios.
|
||||
vars map[string]*types.Mlrval
|
||||
}
|
||||
|
||||
func NewStackFrame() *StackFrame {
|
||||
return &StackFrame{
|
||||
vars: make(map[string]*types.Mlrval),
|
||||
}
|
||||
}
|
||||
|
||||
func (this *StackFrame) Clear() {
|
||||
this.vars = make(map[string]*types.Mlrval)
|
||||
}
|
||||
|
||||
func (this *StackFrame) Bind(name string, mlrval *types.Mlrval) {
|
||||
this.vars[name] = mlrval.Copy()
|
||||
}
|
||||
|
||||
// Returns nil on no such
|
||||
func (this *StackFrame) ReadVariable(name string) *types.Mlrval {
|
||||
return this.vars[name]
|
||||
}
|
||||
25
go/src/miller/dsl/cst/state.go
Normal file
25
go/src/miller/dsl/cst/state.go
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
package cst
|
||||
|
||||
import (
|
||||
"miller/types"
|
||||
)
|
||||
|
||||
func NewEmptyState() *State {
|
||||
oosvars := types.NewMlrmap()
|
||||
return &State{
|
||||
Inrec: nil,
|
||||
Context: nil,
|
||||
Oosvars: oosvars,
|
||||
FilterResult: true,
|
||||
// OutputChannel is assigned after construction
|
||||
stack: NewStack(),
|
||||
}
|
||||
}
|
||||
|
||||
func (this *State) Update(
|
||||
inrec *types.Mlrmap,
|
||||
context *types.Context,
|
||||
) {
|
||||
this.Inrec = inrec
|
||||
this.Context = context
|
||||
}
|
||||
|
|
@ -46,8 +46,14 @@ func BuildStatementNode(
|
|||
|
||||
case dsl.NodeTypeIfChain:
|
||||
return BuildIfChainNode(astNode)
|
||||
case dsl.NodeTypeWhileLoop:
|
||||
return BuildWhileLoopNode(astNode)
|
||||
case dsl.NodeTypeDoWhileLoop:
|
||||
return BuildDoWhileLoopNode(astNode)
|
||||
case dsl.NodeTypeForLoopKeyOnly:
|
||||
return BuildForLoopKeyOnlyNode(astNode)
|
||||
case dsl.NodeTypeForLoopKeyValue:
|
||||
return BuildForLoopKeyValueNode(astNode)
|
||||
|
||||
default:
|
||||
return nil, errors.New(
|
||||
|
|
|
|||
|
|
@ -32,33 +32,11 @@ type State struct {
|
|||
Oosvars *types.Mlrmap
|
||||
FilterResult bool
|
||||
OutputChannel chan<- *types.RecordAndContext
|
||||
// TODO: stack frames will go into individual statement-block nodes or here?
|
||||
// Needs to be here, for scope-resolution walks
|
||||
}
|
||||
|
||||
func NewEmptyState() *State {
|
||||
oosvars := types.NewMlrmap()
|
||||
return &State{
|
||||
Inrec: nil,
|
||||
Context: nil,
|
||||
Oosvars: oosvars,
|
||||
FilterResult: true,
|
||||
}
|
||||
}
|
||||
|
||||
func (this *State) Update(
|
||||
inrec *types.Mlrmap,
|
||||
context *types.Context,
|
||||
) {
|
||||
this.Inrec = inrec
|
||||
this.Context = context
|
||||
stack *Stack
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
type RootNode struct {
|
||||
// TODO: Statements/blocks
|
||||
//executables []IExecutable
|
||||
|
||||
beginBlocks []*StatementBlockNode
|
||||
mainBlock *StatementBlockNode
|
||||
endBlocks []*StatementBlockNode
|
||||
|
|
@ -79,7 +57,6 @@ type IExecutable interface {
|
|||
// Also implements IExecutable
|
||||
type StatementBlockNode struct {
|
||||
executables []IExecutable
|
||||
// TODO: localvars -- here or in State's stack-frame
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
|
|
|
|||
123
go/src/miller/dsl/cst/while.go
Normal file
123
go/src/miller/dsl/cst/while.go
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
package cst
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"miller/dsl"
|
||||
"miller/lib"
|
||||
)
|
||||
|
||||
// ================================================================
|
||||
// This is for while/do-while loops
|
||||
// ================================================================
|
||||
|
||||
// ================================================================
|
||||
type WhileLoopNode struct {
|
||||
conditionNode IEvaluable
|
||||
statementBlockNode *StatementBlockNode
|
||||
}
|
||||
|
||||
func NewWhileLoopNode(
|
||||
conditionNode IEvaluable,
|
||||
statementBlockNode *StatementBlockNode,
|
||||
) *WhileLoopNode {
|
||||
return &WhileLoopNode{
|
||||
conditionNode: conditionNode,
|
||||
statementBlockNode: statementBlockNode,
|
||||
}
|
||||
}
|
||||
|
||||
func BuildWhileLoopNode(astNode *dsl.ASTNode) (*WhileLoopNode, error) {
|
||||
lib.InternalCodingErrorIf(astNode.Type != dsl.NodeTypeWhileLoop)
|
||||
lib.InternalCodingErrorIf(len(astNode.Children) != 2)
|
||||
|
||||
conditionNode, err := BuildEvaluableNode(astNode.Children[0])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
statementBlockNode, err := BuildStatementBlockNode(astNode.Children[1])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewWhileLoopNode(
|
||||
conditionNode,
|
||||
statementBlockNode,
|
||||
), nil
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
func (this *WhileLoopNode) Execute(state *State) error {
|
||||
for {
|
||||
condition := this.conditionNode.Evaluate(state)
|
||||
boolValue, isBool := condition.GetBoolValue()
|
||||
if !isBool {
|
||||
// TODO: line-number/token info for the DSL expression.
|
||||
return errors.New("Miller: conditional expression did not evaluate to boolean.")
|
||||
}
|
||||
if boolValue != true {
|
||||
break
|
||||
}
|
||||
err := this.statementBlockNode.Execute(state)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
type DoWhileLoopNode struct {
|
||||
statementBlockNode *StatementBlockNode
|
||||
conditionNode IEvaluable
|
||||
}
|
||||
|
||||
func NewDoWhileLoopNode(
|
||||
statementBlockNode *StatementBlockNode,
|
||||
conditionNode IEvaluable,
|
||||
) *DoWhileLoopNode {
|
||||
return &DoWhileLoopNode{
|
||||
statementBlockNode: statementBlockNode,
|
||||
conditionNode: conditionNode,
|
||||
}
|
||||
}
|
||||
|
||||
func BuildDoWhileLoopNode(astNode *dsl.ASTNode) (*DoWhileLoopNode, error) {
|
||||
lib.InternalCodingErrorIf(astNode.Type != dsl.NodeTypeDoWhileLoop)
|
||||
lib.InternalCodingErrorIf(len(astNode.Children) != 2)
|
||||
|
||||
statementBlockNode, err := BuildStatementBlockNode(astNode.Children[0])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
conditionNode, err := BuildEvaluableNode(astNode.Children[1])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewDoWhileLoopNode(
|
||||
statementBlockNode,
|
||||
conditionNode,
|
||||
), nil
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
func (this *DoWhileLoopNode) Execute(state *State) error {
|
||||
for {
|
||||
err := this.statementBlockNode.Execute(state)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
condition := this.conditionNode.Evaluate(state)
|
||||
boolValue, isBool := condition.GetBoolValue()
|
||||
if !isBool {
|
||||
// TODO: line-number/token info for the DSL expression.
|
||||
return errors.New("Miller: conditional expression did not evaluate to boolean.")
|
||||
}
|
||||
if boolValue == false {
|
||||
break
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -88,9 +88,9 @@ being 'b=3,c=4', then the output is the two records 'a=1,b=2,c=' and
|
|||
|
||||
// ----------------------------------------------------------------
|
||||
type MapperUnsparsify struct {
|
||||
fillerString string
|
||||
fillerString string
|
||||
recordsAndContexts *list.List
|
||||
fieldNamesSeen *lib.OrderedMap
|
||||
fieldNamesSeen *lib.OrderedMap
|
||||
}
|
||||
|
||||
func NewMapperUnsparsify(
|
||||
|
|
@ -98,9 +98,9 @@ func NewMapperUnsparsify(
|
|||
) (*MapperUnsparsify, error) {
|
||||
|
||||
this := &MapperUnsparsify{
|
||||
fillerString: fillerString,
|
||||
fillerString: fillerString,
|
||||
recordsAndContexts: list.New(),
|
||||
fieldNamesSeen: lib.NewOrderedMap(),
|
||||
fieldNamesSeen: lib.NewOrderedMap(),
|
||||
}
|
||||
|
||||
return this, nil
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -11,8 +11,8 @@ import (
|
|||
|
||||
const (
|
||||
NoState = -1
|
||||
NumStates = 211
|
||||
NumSymbols = 344
|
||||
NumStates = 217
|
||||
NumSymbols = 351
|
||||
)
|
||||
|
||||
type Lexer struct {
|
||||
|
|
@ -179,282 +179,289 @@ Lexer symbols:
|
|||
63: 'g'
|
||||
64: 'i'
|
||||
65: 'n'
|
||||
66: 'e'
|
||||
67: 'n'
|
||||
66: 'd'
|
||||
67: 'o'
|
||||
68: 'd'
|
||||
69: 'f'
|
||||
70: 'i'
|
||||
71: 'l'
|
||||
72: 't'
|
||||
73: 'e'
|
||||
74: 'r'
|
||||
75: 'e'
|
||||
76: 'm'
|
||||
77: 'i'
|
||||
78: 't'
|
||||
79: 'd'
|
||||
80: 'u'
|
||||
81: 'm'
|
||||
82: 'p'
|
||||
83: 'e'
|
||||
84: 'd'
|
||||
85: 'u'
|
||||
69: 'u'
|
||||
70: 'm'
|
||||
71: 'p'
|
||||
72: 'e'
|
||||
73: 'd'
|
||||
74: 'u'
|
||||
75: 'm'
|
||||
76: 'p'
|
||||
77: 'e'
|
||||
78: 'l'
|
||||
79: 'i'
|
||||
80: 'f'
|
||||
81: 'e'
|
||||
82: 'l'
|
||||
83: 's'
|
||||
84: 'e'
|
||||
85: 'e'
|
||||
86: 'm'
|
||||
87: 'p'
|
||||
88: 'i'
|
||||
89: 'f'
|
||||
90: 'e'
|
||||
91: 'l'
|
||||
92: 'i'
|
||||
93: 'f'
|
||||
94: 'e'
|
||||
95: 'l'
|
||||
96: 's'
|
||||
97: 'e'
|
||||
87: 'i'
|
||||
88: 't'
|
||||
89: 'e'
|
||||
90: 'n'
|
||||
91: 'd'
|
||||
92: 'f'
|
||||
93: 'i'
|
||||
94: 'l'
|
||||
95: 't'
|
||||
96: 'e'
|
||||
97: 'r'
|
||||
98: 'f'
|
||||
99: 'o'
|
||||
100: 'r'
|
||||
101: 'i'
|
||||
102: 'n'
|
||||
102: 'f'
|
||||
103: 'i'
|
||||
104: 'n'
|
||||
105: 't'
|
||||
106: 'f'
|
||||
107: 'l'
|
||||
108: 'o'
|
||||
109: 'a'
|
||||
110: 't'
|
||||
111: '$'
|
||||
112: '$'
|
||||
113: '{'
|
||||
114: '}'
|
||||
115: '$'
|
||||
116: '*'
|
||||
117: '@'
|
||||
118: '@'
|
||||
119: '{'
|
||||
120: '}'
|
||||
121: '@'
|
||||
122: '*'
|
||||
123: '%'
|
||||
124: '%'
|
||||
125: '%'
|
||||
126: 'p'
|
||||
127: 'a'
|
||||
128: 'n'
|
||||
129: 'i'
|
||||
130: 'c'
|
||||
105: 'w'
|
||||
106: 'h'
|
||||
107: 'i'
|
||||
108: 'l'
|
||||
109: 'e'
|
||||
110: 'i'
|
||||
111: 'n'
|
||||
112: 't'
|
||||
113: 'f'
|
||||
114: 'l'
|
||||
115: 'o'
|
||||
116: 'a'
|
||||
117: 't'
|
||||
118: '$'
|
||||
119: '$'
|
||||
120: '{'
|
||||
121: '}'
|
||||
122: '$'
|
||||
123: '*'
|
||||
124: '@'
|
||||
125: '@'
|
||||
126: '{'
|
||||
127: '}'
|
||||
128: '@'
|
||||
129: '*'
|
||||
130: '%'
|
||||
131: '%'
|
||||
132: '%'
|
||||
133: '%'
|
||||
134: ';'
|
||||
135: '='
|
||||
136: '$'
|
||||
137: '['
|
||||
138: ']'
|
||||
139: '@'
|
||||
140: '['
|
||||
141: '|'
|
||||
142: '|'
|
||||
143: '='
|
||||
144: '^'
|
||||
145: '^'
|
||||
146: '='
|
||||
147: '&'
|
||||
148: '&'
|
||||
149: '='
|
||||
133: 'p'
|
||||
134: 'a'
|
||||
135: 'n'
|
||||
136: 'i'
|
||||
137: 'c'
|
||||
138: '%'
|
||||
139: '%'
|
||||
140: '%'
|
||||
141: ';'
|
||||
142: '{'
|
||||
143: '}'
|
||||
144: '='
|
||||
145: '$'
|
||||
146: '['
|
||||
147: ']'
|
||||
148: '@'
|
||||
149: '['
|
||||
150: '|'
|
||||
151: '='
|
||||
152: '^'
|
||||
153: '='
|
||||
154: '<'
|
||||
155: '<'
|
||||
156: '='
|
||||
157: '>'
|
||||
158: '>'
|
||||
159: '='
|
||||
160: '>'
|
||||
161: '>'
|
||||
162: '>'
|
||||
163: '='
|
||||
164: '+'
|
||||
151: '|'
|
||||
152: '='
|
||||
153: '^'
|
||||
154: '^'
|
||||
155: '='
|
||||
156: '&'
|
||||
157: '&'
|
||||
158: '='
|
||||
159: '|'
|
||||
160: '='
|
||||
161: '^'
|
||||
162: '='
|
||||
163: '<'
|
||||
164: '<'
|
||||
165: '='
|
||||
166: '.'
|
||||
167: '='
|
||||
168: '-'
|
||||
169: '='
|
||||
170: '*'
|
||||
171: '='
|
||||
172: '/'
|
||||
173: '='
|
||||
174: '/'
|
||||
175: '/'
|
||||
166: '>'
|
||||
167: '>'
|
||||
168: '='
|
||||
169: '>'
|
||||
170: '>'
|
||||
171: '>'
|
||||
172: '='
|
||||
173: '+'
|
||||
174: '='
|
||||
175: '.'
|
||||
176: '='
|
||||
177: '%'
|
||||
177: '-'
|
||||
178: '='
|
||||
179: '*'
|
||||
180: '*'
|
||||
181: '='
|
||||
182: '?'
|
||||
183: ':'
|
||||
184: '|'
|
||||
185: '|'
|
||||
186: '^'
|
||||
187: '^'
|
||||
188: '&'
|
||||
189: '&'
|
||||
180: '='
|
||||
181: '/'
|
||||
182: '='
|
||||
183: '/'
|
||||
184: '/'
|
||||
185: '='
|
||||
186: '%'
|
||||
187: '='
|
||||
188: '*'
|
||||
189: '*'
|
||||
190: '='
|
||||
191: '~'
|
||||
192: '!'
|
||||
193: '='
|
||||
194: '~'
|
||||
195: '='
|
||||
196: '='
|
||||
197: '!'
|
||||
198: '='
|
||||
199: '>'
|
||||
200: '>'
|
||||
201: '='
|
||||
202: '<'
|
||||
203: '<'
|
||||
191: '?'
|
||||
192: ':'
|
||||
193: '|'
|
||||
194: '|'
|
||||
195: '^'
|
||||
196: '^'
|
||||
197: '&'
|
||||
198: '&'
|
||||
199: '='
|
||||
200: '~'
|
||||
201: '!'
|
||||
202: '='
|
||||
203: '~'
|
||||
204: '='
|
||||
205: '|'
|
||||
206: '^'
|
||||
207: '&'
|
||||
208: '<'
|
||||
209: '<'
|
||||
210: '>'
|
||||
211: '>'
|
||||
212: '>'
|
||||
213: '>'
|
||||
214: '>'
|
||||
215: '+'
|
||||
216: '-'
|
||||
217: '.'
|
||||
218: '+'
|
||||
219: '.'
|
||||
220: '-'
|
||||
221: '.'
|
||||
222: '*'
|
||||
223: '/'
|
||||
224: '/'
|
||||
225: '/'
|
||||
226: '%'
|
||||
227: '.'
|
||||
228: '*'
|
||||
229: '.'
|
||||
230: '/'
|
||||
231: '.'
|
||||
205: '='
|
||||
206: '!'
|
||||
207: '='
|
||||
208: '>'
|
||||
209: '>'
|
||||
210: '='
|
||||
211: '<'
|
||||
212: '<'
|
||||
213: '='
|
||||
214: '|'
|
||||
215: '^'
|
||||
216: '&'
|
||||
217: '<'
|
||||
218: '<'
|
||||
219: '>'
|
||||
220: '>'
|
||||
221: '>'
|
||||
222: '>'
|
||||
223: '>'
|
||||
224: '+'
|
||||
225: '-'
|
||||
226: '.'
|
||||
227: '+'
|
||||
228: '.'
|
||||
229: '-'
|
||||
230: '.'
|
||||
231: '*'
|
||||
232: '/'
|
||||
233: '/'
|
||||
234: '!'
|
||||
235: '~'
|
||||
236: '*'
|
||||
234: '/'
|
||||
235: '%'
|
||||
236: '.'
|
||||
237: '*'
|
||||
238: '('
|
||||
239: ')'
|
||||
240: '['
|
||||
241: ','
|
||||
242: '{'
|
||||
243: '}'
|
||||
244: '_'
|
||||
245: ' '
|
||||
246: '!'
|
||||
247: '#'
|
||||
248: '$'
|
||||
249: '%'
|
||||
250: '&'
|
||||
251: '''
|
||||
252: '\'
|
||||
253: '('
|
||||
254: ')'
|
||||
255: '*'
|
||||
256: '+'
|
||||
257: ','
|
||||
258: '-'
|
||||
259: '.'
|
||||
260: '/'
|
||||
261: ':'
|
||||
262: ';'
|
||||
263: '<'
|
||||
264: '='
|
||||
265: '>'
|
||||
266: '?'
|
||||
267: '@'
|
||||
268: '['
|
||||
269: ']'
|
||||
270: '^'
|
||||
271: '_'
|
||||
272: '`'
|
||||
273: '{'
|
||||
274: '|'
|
||||
275: '}'
|
||||
276: '~'
|
||||
277: '\'
|
||||
278: '"'
|
||||
279: 'e'
|
||||
280: 'E'
|
||||
281: 't'
|
||||
282: 'r'
|
||||
283: 'u'
|
||||
284: 'e'
|
||||
285: 'f'
|
||||
286: 'a'
|
||||
287: 'l'
|
||||
288: 's'
|
||||
289: 'e'
|
||||
290: ' '
|
||||
291: '!'
|
||||
292: '#'
|
||||
293: '$'
|
||||
294: '%'
|
||||
295: '&'
|
||||
296: '''
|
||||
297: '\'
|
||||
298: '('
|
||||
299: ')'
|
||||
300: '*'
|
||||
301: '+'
|
||||
302: ','
|
||||
303: '-'
|
||||
304: '.'
|
||||
305: '/'
|
||||
306: ':'
|
||||
307: ';'
|
||||
308: '<'
|
||||
309: '='
|
||||
310: '>'
|
||||
311: '?'
|
||||
312: '@'
|
||||
313: '['
|
||||
314: ']'
|
||||
315: '^'
|
||||
316: '_'
|
||||
317: '`'
|
||||
318: '|'
|
||||
319: '~'
|
||||
320: '\'
|
||||
321: '{'
|
||||
322: '\'
|
||||
323: '}'
|
||||
324: ' '
|
||||
325: '\t'
|
||||
326: '\n'
|
||||
327: '\r'
|
||||
328: 'a'-'z'
|
||||
329: 'A'-'Z'
|
||||
330: '0'-'9'
|
||||
331: '0'-'9'
|
||||
332: 'a'-'f'
|
||||
333: 'A'-'F'
|
||||
334: '0'-'1'
|
||||
335: 'A'-'Z'
|
||||
336: 'a'-'z'
|
||||
238: '.'
|
||||
239: '/'
|
||||
240: '.'
|
||||
241: '/'
|
||||
242: '/'
|
||||
243: '!'
|
||||
244: '~'
|
||||
245: '*'
|
||||
246: '*'
|
||||
247: '('
|
||||
248: ')'
|
||||
249: '['
|
||||
250: ','
|
||||
251: '_'
|
||||
252: ' '
|
||||
253: '!'
|
||||
254: '#'
|
||||
255: '$'
|
||||
256: '%'
|
||||
257: '&'
|
||||
258: '''
|
||||
259: '\'
|
||||
260: '('
|
||||
261: ')'
|
||||
262: '*'
|
||||
263: '+'
|
||||
264: ','
|
||||
265: '-'
|
||||
266: '.'
|
||||
267: '/'
|
||||
268: ':'
|
||||
269: ';'
|
||||
270: '<'
|
||||
271: '='
|
||||
272: '>'
|
||||
273: '?'
|
||||
274: '@'
|
||||
275: '['
|
||||
276: ']'
|
||||
277: '^'
|
||||
278: '_'
|
||||
279: '`'
|
||||
280: '{'
|
||||
281: '|'
|
||||
282: '}'
|
||||
283: '~'
|
||||
284: '\'
|
||||
285: '"'
|
||||
286: 'e'
|
||||
287: 'E'
|
||||
288: 't'
|
||||
289: 'r'
|
||||
290: 'u'
|
||||
291: 'e'
|
||||
292: 'f'
|
||||
293: 'a'
|
||||
294: 'l'
|
||||
295: 's'
|
||||
296: 'e'
|
||||
297: ' '
|
||||
298: '!'
|
||||
299: '#'
|
||||
300: '$'
|
||||
301: '%'
|
||||
302: '&'
|
||||
303: '''
|
||||
304: '\'
|
||||
305: '('
|
||||
306: ')'
|
||||
307: '*'
|
||||
308: '+'
|
||||
309: ','
|
||||
310: '-'
|
||||
311: '.'
|
||||
312: '/'
|
||||
313: ':'
|
||||
314: ';'
|
||||
315: '<'
|
||||
316: '='
|
||||
317: '>'
|
||||
318: '?'
|
||||
319: '@'
|
||||
320: '['
|
||||
321: ']'
|
||||
322: '^'
|
||||
323: '_'
|
||||
324: '`'
|
||||
325: '|'
|
||||
326: '~'
|
||||
327: '\'
|
||||
328: '{'
|
||||
329: '\'
|
||||
330: '}'
|
||||
331: ' '
|
||||
332: '\t'
|
||||
333: '\n'
|
||||
334: '\r'
|
||||
335: 'a'-'z'
|
||||
336: 'A'-'Z'
|
||||
337: '0'-'9'
|
||||
338: \u0100-\U0010ffff
|
||||
339: 'A'-'Z'
|
||||
340: 'a'-'z'
|
||||
341: '0'-'9'
|
||||
342: \u0100-\U0010ffff
|
||||
343: .
|
||||
338: '0'-'9'
|
||||
339: 'a'-'f'
|
||||
340: 'A'-'F'
|
||||
341: '0'-'1'
|
||||
342: 'A'-'Z'
|
||||
343: 'a'-'z'
|
||||
344: '0'-'9'
|
||||
345: \u0100-\U0010ffff
|
||||
346: 'A'-'Z'
|
||||
347: 'a'-'z'
|
||||
348: '0'-'9'
|
||||
349: \u0100-\U0010ffff
|
||||
350: .
|
||||
*/
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -150,22 +150,23 @@ md_token_FILENUM : 'F' 'I' 'L' 'E' 'N' 'U' 'M' ;
|
|||
// * true and false (boolean literals) are also keywords, defined above.
|
||||
|
||||
md_token_begin : 'b' 'e' 'g' 'i' 'n' ;
|
||||
md_token_end : 'e' 'n' 'd' ;
|
||||
md_token_filter : 'f' 'i' 'l' 't' 'e' 'r' ;
|
||||
md_token_emit : 'e' 'm' 'i' 't' ;
|
||||
md_token_do : 'd' 'o' ;
|
||||
md_token_dump : 'd' 'u' 'm' 'p' ;
|
||||
md_token_edump : 'e' 'd' 'u' 'm' 'p' ;
|
||||
md_token_if : 'i' 'f' ;
|
||||
md_token_elif : 'e' 'l' 'i' 'f' ;
|
||||
md_token_else : 'e' 'l' 's' 'e' ;
|
||||
md_token_emit : 'e' 'm' 'i' 't' ;
|
||||
md_token_end : 'e' 'n' 'd' ;
|
||||
md_token_filter : 'f' 'i' 'l' 't' 'e' 'r' ;
|
||||
md_token_for : 'f' 'o' 'r' ;
|
||||
md_token_if : 'i' 'f' ;
|
||||
md_token_in : 'i' 'n' ;
|
||||
md_token_while : 'w' 'h' 'i' 'l' 'e' ;
|
||||
|
||||
//md_token_all : 'a' 'l' 'l' ;
|
||||
//md_token_break : 'b' 'r' 'e' 'a' 'k' ;
|
||||
//md_token_call : 'c' 'a' 'l' 'l' ;
|
||||
//md_token_continue : 'c' 'o' 'n' 't' 'i' 'n' 'u' 'e' ;
|
||||
//md_token_do : 'd' 'o' ;
|
||||
//md_token_eprint : 'e' 'p' 'r' 'i' 'n' 't' ;
|
||||
//md_token_eprintn : 'e' 'p' 'r' 'i' 'n' 't' 'n' ;
|
||||
//md_token_func : 'f' 'u' 'n' 'c' ;
|
||||
|
|
@ -177,7 +178,6 @@ md_token_in : 'i' 'n' ;
|
|||
//md_token_subr : 's' 'u' 'b' 'r' ;
|
||||
//md_token_tee : 't' 'e' 'e' ;
|
||||
//md_token_unset : 'u' 'n' 's' 'e' 't' ;
|
||||
//md_token_while : 'w' 'h' 'i' 'l' 'e' ;
|
||||
|
||||
//md_token_map_type : 'm' 'a' 'p' ;
|
||||
//md_token_num_type : 'n' 'u' 'm' ;
|
||||
|
|
@ -319,6 +319,16 @@ StatementBlock
|
|||
|
||||
;
|
||||
|
||||
StatementBlockInBraces
|
||||
// Defining StatementBlock to be emptyable would have been more elegant ...
|
||||
// I got LR-1 conflicts though. :^/
|
||||
: "{" "}"
|
||||
<< dsl.NewASTNodeZary(nil, dsl.NodeTypeStatementBlock) >>
|
||||
|
||||
| "{" StatementBlock "}"
|
||||
<< dsl.Wrap($1) >>
|
||||
;
|
||||
|
||||
// ================================================================
|
||||
// ASSIGMENT STATEMENTS
|
||||
|
||||
|
|
@ -329,6 +339,9 @@ BracelessStatement
|
|||
| EmitStatement
|
||||
| DumpStatement
|
||||
| EdumpStatement
|
||||
// Has braces but does not *end* in braces -- so it requires semicolon after.
|
||||
| DoWhileLoop
|
||||
|
||||
;
|
||||
|
||||
Assignment
|
||||
|
|
@ -1153,22 +1166,17 @@ BracefulStatement
|
|||
: BeginBlock
|
||||
| EndBlock
|
||||
| IfChain
|
||||
| WhileLoop
|
||||
| ForLoop
|
||||
;
|
||||
|
||||
BeginBlock
|
||||
: md_token_begin "{" "}"
|
||||
<< dsl.NewASTNodeZary(nil, dsl.NodeTypeBeginBlock) >>
|
||||
| md_token_begin "{" StatementBlock "}"
|
||||
<< dsl.NewASTNodeUnary(nil, $2, dsl.NodeTypeBeginBlock) >>
|
||||
: md_token_begin StatementBlockInBraces
|
||||
<< dsl.NewASTNodeUnary(nil, $1, dsl.NodeTypeBeginBlock) >>
|
||||
;
|
||||
EndBlock
|
||||
: md_token_end "{" "}"
|
||||
<< dsl.NewASTNodeZary(nil, dsl.NodeTypeEndBlock) >>
|
||||
| md_token_end "{" StatementBlock "}"
|
||||
<< dsl.NewASTNodeUnary(nil, $2, dsl.NodeTypeEndBlock) >>
|
||||
| md_token_end "{" StatementBlock "}"
|
||||
<< dsl.NewASTNodeUnary(nil, $2, dsl.NodeTypeEndBlock) >>
|
||||
: md_token_end StatementBlockInBraces
|
||||
<< dsl.NewASTNodeUnary(nil, $1, dsl.NodeTypeEndBlock) >>
|
||||
;
|
||||
|
||||
// ================================================================
|
||||
|
|
@ -1192,18 +1200,31 @@ IfElifStar
|
|||
;
|
||||
|
||||
IfBlock
|
||||
: md_token_if "(" Rvalue ")" "{" StatementBlock "}"
|
||||
<< dsl.NewASTNodeBinary($0, $2, $5, dsl.NodeTypeIfItem) >>
|
||||
: md_token_if "(" Rvalue ")" StatementBlockInBraces
|
||||
<< dsl.NewASTNodeBinary($0, $2, $4, dsl.NodeTypeIfItem) >>
|
||||
;
|
||||
|
||||
ElifBlock
|
||||
: md_token_elif "(" Rvalue ")" "{" StatementBlock "}"
|
||||
<< dsl.NewASTNodeBinary($0, $2, $5, dsl.NodeTypeIfItem) >>
|
||||
: md_token_elif "(" Rvalue ")" StatementBlockInBraces
|
||||
<< dsl.NewASTNodeBinary($0, $2, $4, dsl.NodeTypeIfItem) >>
|
||||
;
|
||||
|
||||
ElseBlock
|
||||
: md_token_else "{" StatementBlock "}"
|
||||
<< dsl.NewASTNodeUnary($0, $2, dsl.NodeTypeIfItem) >>
|
||||
: md_token_else StatementBlockInBraces
|
||||
<< dsl.NewASTNodeUnary($0, $1, dsl.NodeTypeIfItem) >>
|
||||
;
|
||||
|
||||
// ================================================================
|
||||
// WHILE AND DO-WHILE -LOOPS
|
||||
|
||||
WhileLoop
|
||||
: md_token_while "(" Rvalue ")" StatementBlockInBraces
|
||||
<< dsl.NewASTNodeBinary($0, $2, $4, dsl.NodeTypeWhileLoop) >>
|
||||
;
|
||||
|
||||
DoWhileLoop
|
||||
: md_token_do StatementBlockInBraces md_token_while "(" Rvalue ")"
|
||||
<< dsl.NewASTNodeBinary($0, $1, $4, dsl.NodeTypeDoWhileLoop) >>
|
||||
;
|
||||
|
||||
// ================================================================
|
||||
|
|
@ -1238,14 +1259,12 @@ ElseBlock
|
|||
// ================================================================
|
||||
// FOR-LOOPS
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
ForLoopIndex
|
||||
: LocalVariable
|
||||
;
|
||||
// TODO: typedefs on localvars
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
ForLoop
|
||||
: ForLoopKeyOnly
|
||||
// | ForLoopKeyValue
|
||||
| ForLoopKeyValue
|
||||
// | ForLoopMultipleKeysValue
|
||||
// | TripleForLoop
|
||||
;
|
||||
|
|
@ -1255,56 +1274,53 @@ ForLoop
|
|||
ForLoopKeyOnly
|
||||
: md_token_for
|
||||
"("
|
||||
ForLoopIndex
|
||||
md_token_in
|
||||
Rvalue
|
||||
// TODO:... Mappable (function call, srec, oosvar ... -- or check at CST?)
|
||||
LocalVariable
|
||||
md_token_in
|
||||
Rvalue
|
||||
")"
|
||||
"{"
|
||||
StatementBlock
|
||||
"}"
|
||||
StatementBlockInBraces
|
||||
<<
|
||||
dsl.NewASTNodeTernary(
|
||||
$0, // "for"
|
||||
$2, // k, etc.
|
||||
$4, // $*, etc.
|
||||
$7, // { ... }
|
||||
$6, // { ... }
|
||||
dsl.NodeTypeForLoopKeyOnly,
|
||||
);
|
||||
>>
|
||||
;
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
//// for(k, v in $*) { ... }
|
||||
// for(k, v in $*) { ... }
|
||||
ForLoopKeyValue
|
||||
: md_token_for
|
||||
"("
|
||||
LocalVariable
|
||||
","
|
||||
LocalVariable
|
||||
md_token_in
|
||||
Rvalue
|
||||
")"
|
||||
StatementBlockInBraces
|
||||
<<
|
||||
dsl.NewASTNodeQuaternary(
|
||||
$0, // "for"
|
||||
$2, // k, etc.
|
||||
$4, // v, etc.
|
||||
$6, // $*, etc.
|
||||
$8, // { ... }
|
||||
dsl.NodeTypeForLoopKeyValue,
|
||||
);
|
||||
>>
|
||||
;
|
||||
|
||||
//ForLoopKeyValue(A) ::=
|
||||
// md_token_for(F) "("
|
||||
// ForLoopIndex(K) "," ForLoopIndex(V)
|
||||
// md_token_in md_token_full_srec
|
||||
// ")"
|
||||
// "{"
|
||||
// StatementBlock(S)
|
||||
// "}".
|
||||
//{
|
||||
// mlr_dsl_ast_node_replace_text(S, "for_full_srec_block");
|
||||
// A = mlr_dsl_ast_node_alloc_binary(
|
||||
// F->text,
|
||||
// MD_AST_NODE_TYPE_FOR_SREC,
|
||||
// mlr_dsl_ast_node_alloc_binary(
|
||||
// "variables",
|
||||
// MD_AST_NODE_TYPE_FOR_VARIABLES,
|
||||
// K,
|
||||
// V
|
||||
// ),
|
||||
// S
|
||||
// );
|
||||
//}
|
||||
// ForLoopMultipleKeysValue
|
||||
|
||||
//// for((k1, k2), v in @*) { ... }
|
||||
//// for((k1, k2, k3), v in @*) { ... }
|
||||
//ForLoopMultipleKeysValue(A) ::=
|
||||
// md_token_for(F) "("
|
||||
// "(" ForMapKeylist(L) ")" "," ForLoopIndex(V)
|
||||
// "(" ForMapKeylist(L) ")" "," LocalVariable(V)
|
||||
// md_token_in md_token_full_oosvar
|
||||
// ")"
|
||||
// "{"
|
||||
|
|
@ -1326,25 +1342,6 @@ ForLoopKeyOnly
|
|||
// );
|
||||
//}
|
||||
|
||||
//ForLoopIndex(A) ::= md_token_non_sigil_name(B). {
|
||||
// A = mlr_dsl_ast_node_alloc(B->text, MD_AST_NODE_TYPE_UNTYPED_LOCAL_DEFINITION);
|
||||
//}
|
||||
//ForLoopIndex(A) ::= md_token_numeric md_token_non_sigil_name(B). {
|
||||
// A = mlr_dsl_ast_node_alloc(B->text, MD_AST_NODE_TYPE_NUMERIC_LOCAL_DEFINITION);
|
||||
//}
|
||||
//ForLoopIndex(A) ::= md_token_int md_token_non_sigil_name(B). {
|
||||
// A = mlr_dsl_ast_node_alloc(B->text, MD_AST_NODE_TYPE_INT_LOCAL_DEFINITION);
|
||||
//}
|
||||
//ForLoopIndex(A) ::= md_token_float md_token_non_sigil_name(B). {
|
||||
// A = mlr_dsl_ast_node_alloc(B->text, MD_AST_NODE_TYPE_FLOAT_LOCAL_DEFINITION);
|
||||
//}
|
||||
//ForLoopIndex(A) ::= md_token_string_literal md_token_non_sigil_name(B). {
|
||||
// A = mlr_dsl_ast_node_alloc(B->text, MD_AST_NODE_TYPE_STRING_LOCAL_DEFINITION);
|
||||
//}
|
||||
//ForLoopIndex(A) ::= md_token_boolean md_token_non_sigil_name(B). {
|
||||
// A = mlr_dsl_ast_node_alloc(B->text, MD_AST_NODE_TYPE_BOOLEAN_LOCAL_DEFINITION);
|
||||
//}
|
||||
|
||||
//ForMapKeylist(A) ::= ForLoopIndex(K). {
|
||||
// A = mlr_dsl_ast_node_alloc_unary("key_variables", MD_AST_NODE_TYPE_FOR_VARIABLES, K);
|
||||
//}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -11,9 +11,9 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
numProductions = 180
|
||||
numStates = 2065
|
||||
numSymbols = 164
|
||||
numProductions = 184
|
||||
numStates = 2097
|
||||
numSymbols = 169
|
||||
)
|
||||
|
||||
// Stack
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -123,6 +123,8 @@ var TokMap = TokenMap{
|
|||
"$",
|
||||
"empty",
|
||||
";",
|
||||
"{",
|
||||
"}",
|
||||
"=",
|
||||
"md_token_filter",
|
||||
"md_token_emit",
|
||||
|
|
@ -199,8 +201,6 @@ var TokMap = TokenMap{
|
|||
"md_token_panic",
|
||||
"[",
|
||||
",",
|
||||
"{",
|
||||
"}",
|
||||
"md_token_IPS",
|
||||
"md_token_IFS",
|
||||
"md_token_IRS",
|
||||
|
|
@ -219,6 +219,8 @@ var TokMap = TokenMap{
|
|||
"md_token_if",
|
||||
"md_token_elif",
|
||||
"md_token_else",
|
||||
"md_token_while",
|
||||
"md_token_do",
|
||||
"md_token_for",
|
||||
"md_token_in",
|
||||
},
|
||||
|
|
@ -228,84 +230,84 @@ var TokMap = TokenMap{
|
|||
"$": 1,
|
||||
"empty": 2,
|
||||
";": 3,
|
||||
"=": 4,
|
||||
"md_token_filter": 5,
|
||||
"md_token_emit": 6,
|
||||
"md_token_dump": 7,
|
||||
"md_token_edump": 8,
|
||||
"md_token_field_name": 9,
|
||||
"$[": 10,
|
||||
"]": 11,
|
||||
"md_token_braced_field_name": 12,
|
||||
"md_token_full_srec": 13,
|
||||
"md_token_oosvar_name": 14,
|
||||
"@[": 15,
|
||||
"md_token_braced_oosvar_name": 16,
|
||||
"md_token_full_oosvar": 17,
|
||||
"md_token_non_sigil_name": 18,
|
||||
"||=": 19,
|
||||
"^^=": 20,
|
||||
"&&=": 21,
|
||||
"|=": 22,
|
||||
"^=": 23,
|
||||
"<<=": 24,
|
||||
">>=": 25,
|
||||
">>>=": 26,
|
||||
"+=": 27,
|
||||
".=": 28,
|
||||
"-=": 29,
|
||||
"*=": 30,
|
||||
"/=": 31,
|
||||
"//=": 32,
|
||||
"%=": 33,
|
||||
"**=": 34,
|
||||
"?": 35,
|
||||
":": 36,
|
||||
"||": 37,
|
||||
"^^": 38,
|
||||
"&&": 39,
|
||||
"=~": 40,
|
||||
"!=~": 41,
|
||||
"==": 42,
|
||||
"!=": 43,
|
||||
">": 44,
|
||||
">=": 45,
|
||||
"<": 46,
|
||||
"<=": 47,
|
||||
"|": 48,
|
||||
"^": 49,
|
||||
"&": 50,
|
||||
"<<": 51,
|
||||
">>": 52,
|
||||
">>>": 53,
|
||||
"+": 54,
|
||||
"-": 55,
|
||||
".+": 56,
|
||||
".-": 57,
|
||||
".": 58,
|
||||
"*": 59,
|
||||
"/": 60,
|
||||
"//": 61,
|
||||
"%": 62,
|
||||
".*": 63,
|
||||
"./": 64,
|
||||
".//": 65,
|
||||
"!": 66,
|
||||
"~": 67,
|
||||
"**": 68,
|
||||
"(": 69,
|
||||
")": 70,
|
||||
"md_token_string_literal": 71,
|
||||
"md_token_int_literal": 72,
|
||||
"md_token_float_literal": 73,
|
||||
"md_token_boolean_literal": 74,
|
||||
"md_token_M_PI": 75,
|
||||
"md_token_M_E": 76,
|
||||
"md_token_panic": 77,
|
||||
"[": 78,
|
||||
",": 79,
|
||||
"{": 80,
|
||||
"}": 81,
|
||||
"{": 4,
|
||||
"}": 5,
|
||||
"=": 6,
|
||||
"md_token_filter": 7,
|
||||
"md_token_emit": 8,
|
||||
"md_token_dump": 9,
|
||||
"md_token_edump": 10,
|
||||
"md_token_field_name": 11,
|
||||
"$[": 12,
|
||||
"]": 13,
|
||||
"md_token_braced_field_name": 14,
|
||||
"md_token_full_srec": 15,
|
||||
"md_token_oosvar_name": 16,
|
||||
"@[": 17,
|
||||
"md_token_braced_oosvar_name": 18,
|
||||
"md_token_full_oosvar": 19,
|
||||
"md_token_non_sigil_name": 20,
|
||||
"||=": 21,
|
||||
"^^=": 22,
|
||||
"&&=": 23,
|
||||
"|=": 24,
|
||||
"^=": 25,
|
||||
"<<=": 26,
|
||||
">>=": 27,
|
||||
">>>=": 28,
|
||||
"+=": 29,
|
||||
".=": 30,
|
||||
"-=": 31,
|
||||
"*=": 32,
|
||||
"/=": 33,
|
||||
"//=": 34,
|
||||
"%=": 35,
|
||||
"**=": 36,
|
||||
"?": 37,
|
||||
":": 38,
|
||||
"||": 39,
|
||||
"^^": 40,
|
||||
"&&": 41,
|
||||
"=~": 42,
|
||||
"!=~": 43,
|
||||
"==": 44,
|
||||
"!=": 45,
|
||||
">": 46,
|
||||
">=": 47,
|
||||
"<": 48,
|
||||
"<=": 49,
|
||||
"|": 50,
|
||||
"^": 51,
|
||||
"&": 52,
|
||||
"<<": 53,
|
||||
">>": 54,
|
||||
">>>": 55,
|
||||
"+": 56,
|
||||
"-": 57,
|
||||
".+": 58,
|
||||
".-": 59,
|
||||
".": 60,
|
||||
"*": 61,
|
||||
"/": 62,
|
||||
"//": 63,
|
||||
"%": 64,
|
||||
".*": 65,
|
||||
"./": 66,
|
||||
".//": 67,
|
||||
"!": 68,
|
||||
"~": 69,
|
||||
"**": 70,
|
||||
"(": 71,
|
||||
")": 72,
|
||||
"md_token_string_literal": 73,
|
||||
"md_token_int_literal": 74,
|
||||
"md_token_float_literal": 75,
|
||||
"md_token_boolean_literal": 76,
|
||||
"md_token_M_PI": 77,
|
||||
"md_token_M_E": 78,
|
||||
"md_token_panic": 79,
|
||||
"[": 80,
|
||||
",": 81,
|
||||
"md_token_IPS": 82,
|
||||
"md_token_IFS": 83,
|
||||
"md_token_IRS": 84,
|
||||
|
|
@ -324,7 +326,9 @@ var TokMap = TokenMap{
|
|||
"md_token_if": 97,
|
||||
"md_token_elif": 98,
|
||||
"md_token_else": 99,
|
||||
"md_token_for": 100,
|
||||
"md_token_in": 101,
|
||||
"md_token_while": 100,
|
||||
"md_token_do": 101,
|
||||
"md_token_for": 102,
|
||||
"md_token_in": 103,
|
||||
},
|
||||
}
|
||||
|
|
|
|||
13
go/todo.txt
13
go/todo.txt
|
|
@ -2,18 +2,12 @@
|
|||
TOP OF LIST:
|
||||
|
||||
! JSON null needs to be passed through as-is ... somehow ... new mlrval type??
|
||||
o note json types: string, number, boolean, null, object, array.
|
||||
|
||||
* while and do-while statements -- not urgent
|
||||
|
||||
~ for-loops -- require localvars as prereq
|
||||
> for-k, for-kv, for-knv sooner -- stack-frame special cases
|
||||
> defer triple-for until later
|
||||
|
||||
* stack frames
|
||||
o at cst.State: list.List of StackFrame
|
||||
o for now: StackFrame containing only hash-map from name to mlrval.
|
||||
- default to absent (no hoisting)
|
||||
- no scope-walks needed for for-loops
|
||||
* for-knv
|
||||
o defer triple-for until later
|
||||
|
||||
! quoted NIDX
|
||||
- how with whitespace regex -- ?
|
||||
|
|
@ -161,3 +155,4 @@ NITS/NON-IMMEDIATE:
|
|||
! systime printing out in scientific notation :(
|
||||
! head early-out -- cite the relevant issue & fix the right way ...
|
||||
* relnotes: label b,i,x vs x,i,b change
|
||||
* put -- multiple -f? as in C impl?
|
||||
|
|
|
|||
15
go/u/try-cst
15
go/u/try-cst
|
|
@ -239,3 +239,18 @@ echo; run_mlr --opprint --from u/s.dkvp put '$z = truncate($a, 1)'
|
|||
echo; run_mlr --opprint --from u/s.dkvp put '$z = truncate($a, 2)'
|
||||
echo; run_mlr --opprint --from u/s.dkvp put '$z = truncate($a, 3)'
|
||||
echo; run_mlr --opprint --from u/s.dkvp put '$z = truncate($a, 4)'
|
||||
|
||||
echo; run_mlr --from u/s.dkvp head -n 2 then put -q 'for (k in $*) { emit { "foo" : "bar" } }'
|
||||
echo; run_mlr --from u/s.dkvp head -n 2 then put -q 'for (k in $*) { emit { "foo" : k } }'
|
||||
echo; run_mlr --from u/s.dkvp head -n 2 then put -q 'for (k in $*) { emit { k: "bar" } }'
|
||||
echo; run_mlr --from u/s.dkvp head -n 2 then put -q 'for (k in $*) { emit { k : k } }'
|
||||
|
||||
echo; run_mlr --from u/s.dkvp head -n 2 then put -q 'for (k,v in $*) { emit { "foo" : "bar" } }'
|
||||
echo; run_mlr --from u/s.dkvp head -n 2 then put -q 'for (k,v in $*) { emit { "foo" : v } }'
|
||||
echo; run_mlr --from u/s.dkvp head -n 2 then put -q 'for (k,v in $*) { emit { k: "bar" } }'
|
||||
echo; run_mlr --from u/s.dkvp head -n 2 then put -q 'for (k,v in $*) { emit { k : v } }'
|
||||
|
||||
echo; run_mlr --from u/s.dkvp put '$z = 0; while ($z < $i) {$z += 1}'
|
||||
echo; run_mlr --from u/s.dkvp put '$z = 0; do {$z += 1} while ($z < $i)'
|
||||
echo; run_mlr --from u/s.dkvp put '$z = 10; while ($z < $i) {$z += 1}'
|
||||
echo; run_mlr --from u/s.dkvp put '$z = 10; do {$z += 1} while ($z < $i)'
|
||||
|
|
|
|||
144
go/u/try-cst.out
144
go/u/try-cst.out
|
|
@ -2478,3 +2478,147 @@ pan pan 1 0.3467901443380824 0.7268028627434533 pan
|
|||
eks pan 2 0.7586799647899636 0.5221511083334797 eks
|
||||
wye wye 3 0.20460330576630303 0.33831852551664776 wye
|
||||
eks wye 4 0.38139939387114097 0.13418874328430463 eks
|
||||
|
||||
|
||||
----------------------------------------------------------------
|
||||
mlr --from u/s.dkvp head -n 2 then put -q for (k in $*) { emit { "foo" : "bar" } }
|
||||
foo=bar
|
||||
foo=bar
|
||||
foo=bar
|
||||
foo=bar
|
||||
foo=bar
|
||||
foo=bar
|
||||
foo=bar
|
||||
foo=bar
|
||||
foo=bar
|
||||
foo=bar
|
||||
|
||||
|
||||
----------------------------------------------------------------
|
||||
mlr --from u/s.dkvp head -n 2 then put -q for (k in $*) { emit { "foo" : k } }
|
||||
foo=a
|
||||
foo=b
|
||||
foo=i
|
||||
foo=x
|
||||
foo=y
|
||||
foo=a
|
||||
foo=b
|
||||
foo=i
|
||||
foo=x
|
||||
foo=y
|
||||
|
||||
|
||||
----------------------------------------------------------------
|
||||
mlr --from u/s.dkvp head -n 2 then put -q for (k in $*) { emit { k: "bar" } }
|
||||
a=bar
|
||||
b=bar
|
||||
i=bar
|
||||
x=bar
|
||||
y=bar
|
||||
a=bar
|
||||
b=bar
|
||||
i=bar
|
||||
x=bar
|
||||
y=bar
|
||||
|
||||
|
||||
----------------------------------------------------------------
|
||||
mlr --from u/s.dkvp head -n 2 then put -q for (k in $*) { emit { k : k } }
|
||||
a=a
|
||||
b=b
|
||||
i=i
|
||||
x=x
|
||||
y=y
|
||||
a=a
|
||||
b=b
|
||||
i=i
|
||||
x=x
|
||||
y=y
|
||||
|
||||
|
||||
----------------------------------------------------------------
|
||||
mlr --from u/s.dkvp head -n 2 then put -q for (k,v in $*) { emit { "foo" : "bar" } }
|
||||
foo=bar
|
||||
foo=bar
|
||||
foo=bar
|
||||
foo=bar
|
||||
foo=bar
|
||||
foo=bar
|
||||
foo=bar
|
||||
foo=bar
|
||||
foo=bar
|
||||
foo=bar
|
||||
|
||||
|
||||
----------------------------------------------------------------
|
||||
mlr --from u/s.dkvp head -n 2 then put -q for (k,v in $*) { emit { "foo" : v } }
|
||||
foo=pan
|
||||
foo=pan
|
||||
foo=1
|
||||
foo=0.3467901443380824
|
||||
foo=0.7268028627434533
|
||||
foo=eks
|
||||
foo=pan
|
||||
foo=2
|
||||
foo=0.7586799647899636
|
||||
foo=0.5221511083334797
|
||||
|
||||
|
||||
----------------------------------------------------------------
|
||||
mlr --from u/s.dkvp head -n 2 then put -q for (k,v in $*) { emit { k: "bar" } }
|
||||
a=bar
|
||||
b=bar
|
||||
i=bar
|
||||
x=bar
|
||||
y=bar
|
||||
a=bar
|
||||
b=bar
|
||||
i=bar
|
||||
x=bar
|
||||
y=bar
|
||||
|
||||
|
||||
----------------------------------------------------------------
|
||||
mlr --from u/s.dkvp head -n 2 then put -q for (k,v in $*) { emit { k : v } }
|
||||
a=pan
|
||||
b=pan
|
||||
i=1
|
||||
x=0.3467901443380824
|
||||
y=0.7268028627434533
|
||||
a=eks
|
||||
b=pan
|
||||
i=2
|
||||
x=0.7586799647899636
|
||||
y=0.5221511083334797
|
||||
|
||||
|
||||
----------------------------------------------------------------
|
||||
mlr --from u/s.dkvp put $z = 0; while ($z < $i) {$z += 1}
|
||||
a=pan,b=pan,i=1,x=0.3467901443380824,y=0.7268028627434533,z=1
|
||||
a=eks,b=pan,i=2,x=0.7586799647899636,y=0.5221511083334797,z=2
|
||||
a=wye,b=wye,i=3,x=0.20460330576630303,y=0.33831852551664776,z=3
|
||||
a=eks,b=wye,i=4,x=0.38139939387114097,y=0.13418874328430463,z=4
|
||||
|
||||
|
||||
----------------------------------------------------------------
|
||||
mlr --from u/s.dkvp put $z = 0; do {$z += 1} while ($z < $i)
|
||||
a=pan,b=pan,i=1,x=0.3467901443380824,y=0.7268028627434533,z=1
|
||||
a=eks,b=pan,i=2,x=0.7586799647899636,y=0.5221511083334797,z=2
|
||||
a=wye,b=wye,i=3,x=0.20460330576630303,y=0.33831852551664776,z=3
|
||||
a=eks,b=wye,i=4,x=0.38139939387114097,y=0.13418874328430463,z=4
|
||||
|
||||
|
||||
----------------------------------------------------------------
|
||||
mlr --from u/s.dkvp put $z = 10; while ($z < $i) {$z += 1}
|
||||
a=pan,b=pan,i=1,x=0.3467901443380824,y=0.7268028627434533,z=10
|
||||
a=eks,b=pan,i=2,x=0.7586799647899636,y=0.5221511083334797,z=10
|
||||
a=wye,b=wye,i=3,x=0.20460330576630303,y=0.33831852551664776,z=10
|
||||
a=eks,b=wye,i=4,x=0.38139939387114097,y=0.13418874328430463,z=10
|
||||
|
||||
|
||||
----------------------------------------------------------------
|
||||
mlr --from u/s.dkvp put $z = 10; do {$z += 1} while ($z < $i)
|
||||
a=pan,b=pan,i=1,x=0.3467901443380824,y=0.7268028627434533,z=11
|
||||
a=eks,b=pan,i=2,x=0.7586799647899636,y=0.5221511083334797,z=11
|
||||
a=wye,b=wye,i=3,x=0.20460330576630303,y=0.33831852551664776,z=11
|
||||
a=eks,b=wye,i=4,x=0.38139939387114097,y=0.13418874328430463,z=11
|
||||
|
|
|
|||
|
|
@ -88,4 +88,15 @@ echo; run_mlr -n put -v 'if (NR == 1) { $z = 100 } elif (NR == 2) { $z = 200 }'
|
|||
echo; run_mlr -n put -v 'if (NR == 1) { $z = 100 } elif (NR == 2) { $z = 200 } else { $z = 900 }'
|
||||
echo; run_mlr -n put -v 'if (NR == 1) { $z = 100 } elif (NR == 2) { $z = 200 } elif (NR == 3) { $z = 300 } else { $z = 900 }'
|
||||
|
||||
echo; run_mlr -n put -v 'for (k in $*) { emit { k : k} }'
|
||||
echo; run_mlr -n put -v 'for (k in $*) { emit { k : k } }'
|
||||
|
||||
echo; run_mlr -n put -v 'begin {}'
|
||||
echo; run_mlr -n put -v 'begin {1}'
|
||||
echo; run_mlr -n put -v 'end {}'
|
||||
echo; run_mlr -n put -v 'end {1}'
|
||||
echo; run_mlr -n put -v 'if (1) {}'
|
||||
echo; run_mlr -n put -v 'if (1) {2}'
|
||||
echo; run_mlr -n put -v 'for (k in $*) {}'
|
||||
echo; run_mlr -n put -v 'for (k in $*) {2}'
|
||||
echo; run_mlr -n put -v 'while (false) {}'
|
||||
echo; run_mlr -n put -v 'do {} while (false)'
|
||||
|
|
|
|||
|
|
@ -736,6 +736,7 @@ begin{}
|
|||
RAW AST:
|
||||
* StatementBlock
|
||||
* BeginBlock
|
||||
* StatementBlock
|
||||
|
||||
|
||||
|
||||
|
|
@ -760,6 +761,7 @@ end{}
|
|||
RAW AST:
|
||||
* StatementBlock
|
||||
* EndBlock
|
||||
* StatementBlock
|
||||
|
||||
|
||||
|
||||
|
|
@ -818,7 +820,9 @@ begin{} end {}
|
|||
RAW AST:
|
||||
* StatementBlock
|
||||
* BeginBlock
|
||||
* StatementBlock
|
||||
* EndBlock
|
||||
* StatementBlock
|
||||
|
||||
|
||||
|
||||
|
|
@ -1061,9 +1065,9 @@ RAW AST:
|
|||
|
||||
|
||||
----------------------------------------------------------------
|
||||
mlr -n put -v for (k in $*) { emit { k : k} }
|
||||
mlr -n put -v for (k in $*) { emit { k : k } }
|
||||
DSL EXPRESSION:
|
||||
for (k in $*) { emit { k : k} }
|
||||
for (k in $*) { emit { k : k } }
|
||||
RAW AST:
|
||||
* StatementBlock
|
||||
* ForLoopKeyOnly "for"
|
||||
|
|
@ -1076,3 +1080,131 @@ RAW AST:
|
|||
* LocalVariable "k"
|
||||
* LocalVariable "k"
|
||||
|
||||
|
||||
|
||||
----------------------------------------------------------------
|
||||
mlr -n put -v begin {}
|
||||
DSL EXPRESSION:
|
||||
begin {}
|
||||
RAW AST:
|
||||
* StatementBlock
|
||||
* BeginBlock
|
||||
* StatementBlock
|
||||
|
||||
|
||||
|
||||
----------------------------------------------------------------
|
||||
mlr -n put -v begin {1}
|
||||
DSL EXPRESSION:
|
||||
begin {1}
|
||||
RAW AST:
|
||||
* StatementBlock
|
||||
* BeginBlock
|
||||
* StatementBlock
|
||||
* BareBoolean
|
||||
* IntLiteral "1"
|
||||
|
||||
|
||||
|
||||
----------------------------------------------------------------
|
||||
mlr -n put -v end {}
|
||||
DSL EXPRESSION:
|
||||
end {}
|
||||
RAW AST:
|
||||
* StatementBlock
|
||||
* EndBlock
|
||||
* StatementBlock
|
||||
|
||||
|
||||
|
||||
----------------------------------------------------------------
|
||||
mlr -n put -v end {1}
|
||||
DSL EXPRESSION:
|
||||
end {1}
|
||||
RAW AST:
|
||||
* StatementBlock
|
||||
* EndBlock
|
||||
* StatementBlock
|
||||
* BareBoolean
|
||||
* IntLiteral "1"
|
||||
|
||||
|
||||
|
||||
----------------------------------------------------------------
|
||||
mlr -n put -v if (1) {}
|
||||
DSL EXPRESSION:
|
||||
if (1) {}
|
||||
RAW AST:
|
||||
* StatementBlock
|
||||
* IfChain
|
||||
* IfItem "if"
|
||||
* IntLiteral "1"
|
||||
* StatementBlock
|
||||
|
||||
|
||||
|
||||
----------------------------------------------------------------
|
||||
mlr -n put -v if (1) {2}
|
||||
DSL EXPRESSION:
|
||||
if (1) {2}
|
||||
RAW AST:
|
||||
* StatementBlock
|
||||
* IfChain
|
||||
* IfItem "if"
|
||||
* IntLiteral "1"
|
||||
* StatementBlock
|
||||
* BareBoolean
|
||||
* IntLiteral "2"
|
||||
|
||||
|
||||
|
||||
----------------------------------------------------------------
|
||||
mlr -n put -v for (k in $*) {}
|
||||
DSL EXPRESSION:
|
||||
for (k in $*) {}
|
||||
RAW AST:
|
||||
* StatementBlock
|
||||
* ForLoopKeyOnly "for"
|
||||
* LocalVariable "k"
|
||||
* FullSrec "$*"
|
||||
* StatementBlock
|
||||
|
||||
|
||||
|
||||
----------------------------------------------------------------
|
||||
mlr -n put -v for (k in $*) {2}
|
||||
DSL EXPRESSION:
|
||||
for (k in $*) {2}
|
||||
RAW AST:
|
||||
* StatementBlock
|
||||
* ForLoopKeyOnly "for"
|
||||
* LocalVariable "k"
|
||||
* FullSrec "$*"
|
||||
* StatementBlock
|
||||
* BareBoolean
|
||||
* IntLiteral "2"
|
||||
|
||||
|
||||
|
||||
----------------------------------------------------------------
|
||||
mlr -n put -v while (false) {}
|
||||
DSL EXPRESSION:
|
||||
while (false) {}
|
||||
RAW AST:
|
||||
* StatementBlock
|
||||
* WhileLoop "while"
|
||||
* BoolLiteral "false"
|
||||
* StatementBlock
|
||||
|
||||
|
||||
|
||||
----------------------------------------------------------------
|
||||
mlr -n put -v do {} while (false)
|
||||
DSL EXPRESSION:
|
||||
do {} while (false)
|
||||
RAW AST:
|
||||
* StatementBlock
|
||||
* DoWhileLoop "do"
|
||||
* StatementBlock
|
||||
* BoolLiteral "false"
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue