Example #1
0
func (b *Builder) ParseMethodCallOrMapLookup(ctx *builderCtx, invocant node.Node) node.Node {
	// We have already seen identifier followed by a period
	symbol := b.NextNonSpace(ctx)
	if symbol.Type() != ItemIdentifier {
		b.Unexpected(ctx, "Expected identifier for method call or map lookup, got %s", symbol.Type())
	}

	var n node.Node
	next := b.NextNonSpace(ctx)
	if next.Type() != ItemOpenParen {
		// it's a map lookup. Put back that extra token we read
		b.Backup(ctx)
		n = node.NewFetchFieldNode(invocant.Pos(), invocant, symbol.Value())
	} else {
		// It's a method call! Parse the list
		args := b.ParseList(ctx)
		closeParen := b.NextNonSpace(ctx)
		if closeParen.Type() != ItemCloseParen {
			b.Unexpected(ctx, "Expected ')', got %s", closeParen.Type())
		}
		n = node.NewMethodCallNode(invocant.Pos(), invocant, symbol.Value(), args.(*node.ListNode))
	}

	// If we are followed by another period, we are going to have to
	// check for another level of methodcall / lookup
	if b.PeekNonSpace(ctx).Type() == ItemPeriod {
		b.NextNonSpace(ctx) // consume period
		return b.ParseMethodCallOrMapLookup(ctx, n)
	}
	return n
}
Example #2
0
func compile(ctx *context, n node.Node) {
	switch n.Type() {
	case node.Int, node.Text:
		compileLiteral(ctx, n)
	case node.FetchSymbol:
		compileFetchSymbol(ctx, n.(*node.TextNode))
	case node.FetchField:
		compileFetchField(ctx, n.(*node.FetchFieldNode))
	case node.FetchArrayElement:
		compileFetchArrayElement(ctx, n.(*node.BinaryNode))
	case node.LocalVar:
		compileLoadLvar(ctx, n.(*node.LocalVarNode))
	case node.Assignment:
		compileAssignment(ctx, n.(*node.AssignmentNode))
	case node.Print:
		compilePrint(ctx, n.(*node.ListNode))
	case node.PrintRaw:
		compilePrintRaw(ctx, n.(*node.ListNode))
	case node.Foreach:
		compileForeach(ctx, n.(*node.ForeachNode))
	case node.While:
		compileWhile(ctx, n.(*node.WhileNode))
	case node.If:
		compileIf(ctx, n.(*node.IfNode))
	case node.Else:
		compileElse(ctx, n.(*node.ElseNode))
	case node.MakeArray:
		compileMakeArray(ctx, n.(*node.UnaryNode))
	case node.Range:
		compileRange(ctx, n.(*node.BinaryNode))
	case node.List:
		compileList(ctx, n.(*node.ListNode))
	case node.FunCall:
		compileFunCall(ctx, n.(*node.FunCallNode))
	case node.MethodCall:
		compileMethodCall(ctx, n.(*node.MethodCallNode))
	case node.Include:
		compileInclude(ctx, n.(*node.IncludeNode))
	case node.Group:
		compile(ctx, n.(*node.UnaryNode).Child)
	case node.Equals, node.NotEquals, node.LT, node.GT:
		compileComparison(ctx, n.(*node.BinaryNode))
	case node.Plus, node.Minus, node.Mul, node.Div:
		compileBinaryArithmetic(ctx, n.(*node.BinaryNode))
	case node.Filter:
		compileFilter(ctx, n.(*node.FilterNode))
	case node.Wrapper:
		compileWrapper(ctx, n.(*node.WrapperNode))
	case node.Macro:
		compileMacro(ctx, n.(*node.MacroNode))
	default:
		fmt.Printf("Unknown node: %s\n", n.Type())
	}
}
Example #3
0
func compileLiteral(ctx *context, n node.Node) {
	var op vm.Op
	switch n.Type() {
	case node.Int:
		op = ctx.AppendOp(vm.TXOPLiteral, n.(*node.NumberNode).Value.Int())
	case node.Text:
		op = ctx.AppendOp(vm.TXOPLiteral, n.(*node.TextNode).Text)
	default:
		panic("unknown literal value")
	}
	op.SetComment("Save literal to sa")
}
Example #4
0
func (b *Builder) ParseFunCall(ctx *builderCtx, invocant node.Node) node.Node {
	next := b.NextNonSpace(ctx)
	if next.Type() != ItemOpenParen {
		b.Unexpected(ctx, "Expected '(', got %s", next.Type())
	}

	args := b.ParseList(ctx)
	closeParen := b.NextNonSpace(ctx)
	if closeParen.Type() != ItemCloseParen {
		b.Unexpected(ctx, "Expected ')', got %s", closeParen.Type())
	}

	return node.NewFunCallNode(invocant.Pos(), invocant, args.(*node.ListNode))
}