Beispiel #1
0
func (self *Gen) genBlock(code *ir.Code, b *ast.Block) {
	code.EnterScope()

	for _, stmt := range b.Stmts {
		self.genStmt(code, stmt)
	}

	code.ExitScope()
}
Beispiel #2
0
func (self *Gen) genIdent(code *ir.Code, tok *tok.Token) *obj {
	assert(tok.Type.(tt.T) == tt.Ident)

	o, t := code.Query(tok.Lit)
	if o == nil {
		self.errorf(tok, "%q undefined", tok.Lit)
		return nil
	}

	return &obj{o, t}
}
Beispiel #3
0
func (self *Gen) genCall(code *ir.Code, call *ast.CallExpr) *obj {
	f := self.genExpr(code, call.Func) // evaluate the function first
	if f == nil {
		return nil
	}

	ft, isFunc := f.t.(*types.Func)
	if !isFunc {
		self.errorf(call.Token, "calling on a non-function")
		return nil
	}

	if len(call.Args) != len(ft.Args) {
		self.errorf(call.Token, "wrong number of arguments")
		return nil
	}

	var args []*obj
	for i, arg := range call.Args {
		o := self.genExpr(code, arg)
		if o == nil {
			return nil
		}
		if !types.Equals(o.t, ft.Args[i]) {
			self.errorf(call.Token, "wrong argument type")
			return nil
		}
		args = append(args, o)
	}

	// TODO: push the ret first
	ret := voidObj

	for _, o := range args {
		code.Push(o.o) // now we can push the stuff for call
	}

	code.Call(f.o)

	var pops []ir.Obj
	for _, o := range args {
		pops = append(pops, o.o)
	}
	code.Pop(pops...)

	return ret
}