示例#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
}
示例#2
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))
}