code: func (v *TypeValuerEval) EvalType(expr Expr) (DataType, error) {
  	switch expr := expr.(type) {
  	case *VarRef:
  		return v.evalVarRefExprType(expr)
  	case *Call:
  		return v.evalCallExprType(expr)
  	case *BinaryExpr:
  		return v.evalBinaryExprType(expr)
  	case *ParenExpr:
  		return v.EvalType(expr.Expr)
  	case *NumberLiteral:
  		return Float, nil
  	case *IntegerLiteral:
  		return Integer, nil
  	case *UnsignedLiteral:
  		return Unsigned, nil
  	case *StringLiteral:
  		return String, nil
  	case *BooleanLiteral:
  		return Boolean, nil
  	}
  	return Unknown, nil
  }
docs: // EvalType returns the type for an expression. If the expression cannot
  // be evaluated for some reason, like incompatible types, it is returned
  // as a TypeError in the error. If the error is non-fatal so we can continue
  // even though an error happened, true will be returned.
  // This function assumes that the expression has already been reduced.