示例#1
0
文件: define.go 项目: Xslxy/e8vm
// allocPrepare checks if the provided types are all allocable, and insert
// implicit type casts if needed. Only literay expression list needs alloc
// prepare.
func allocPrepare(
	b *builder, toks []*lex8.Token, lst *tast.ExprList,
) *tast.ExprList {
	ret := tast.NewExprList()
	for i, tok := range toks {
		e := lst.Exprs[i]
		t := e.Type()
		if types.IsNil(t) {
			b.Errorf(tok.Pos, "cannot infer type from nil for %q", tok.Lit)
			return nil
		}
		if v, ok := types.NumConst(t); ok {
			e = constCastInt(b, tok.Pos, v, e)
			if e == nil {
				return nil
			}
		}
		if !types.IsAllocable(t) {
			b.Errorf(tok.Pos, "cannot allocate for %s", t)
			return nil
		}
		ret.Append(e)
	}
	return ret
}
示例#2
0
func buildVarDecl(b *builder, d *ast.VarDecl) *tast.Define {
	ids := d.Idents.Idents

	if d.Eq != nil {
		right := b.buildExpr(d.Exprs)
		if right == nil {
			return nil
		}

		if d.Type == nil {
			ret := define(b, ids, right, d.Eq)
			if ret == nil {
				return nil
			}
			return ret
		}

		tdest := b.buildType(d.Type)
		if tdest == nil {
			return nil
		}

		if !types.IsAllocable(tdest) {
			pos := ast.ExprPos(d.Type)
			b.Errorf(pos, "%s is not allocatable", tdest)
			return nil
		}

		// assignable check
		ts := right.R().TypeList()
		for _, t := range ts {
			if !types.CanAssign(tdest, t) {
				b.Errorf(d.Eq.Pos, "cannot assign %s to %s", t, tdest)
				return nil
			}
		}

		// cast literal expression lists
		// after the casting, all types should be matching to tdest
		if exprList, ok := tast.MakeExprList(right); ok {
			exprList = varDeclPrepare(b, ids, exprList, tdest)
			if exprList == nil {
				return nil
			}
			right = exprList
		}

		syms := declareVars(b, ids, tdest, false)
		if syms == nil {
			return nil
		}
		return &tast.Define{syms, right}
	}

	if d.Type == nil {
		panic("type missing")
	}

	t := b.buildType(d.Type)
	if t == nil {
		return nil
	}

	syms := declareVars(b, ids, t, false)
	if syms == nil {
		return nil
	}
	return &tast.Define{syms, nil}
}