public BuiltInUnaryOperator(string name, CheezType resType, CheezType sub, ComptimeExecution exe = null) { Name = name; ResultType = resType; SubExprType = sub; this.Execution = exe; }
private bool ComputeSizeAndAlignmentOfRemainingTypes() { bool changes = false; while (true) { var typesWithMissingProperties = CheezType.TypesWithMissingProperties; if (typesWithMissingProperties.Count() == 0) { break; } changes = true; CheezType.ClearAllTypes(); foreach (var type in typesWithMissingProperties) { { if (type is AbstractType || type.IsErrorType || type.IsPolyType) { continue; } // force computation of all types sizes GetSizeOfType(type); IsTypeDefaultConstructable(type); } } } return(changes); }
public NodeFinderResult(Scope s, AstExpression expr = null, AstStatement stmt = null, CheezType type = null) { Scope = s; Expr = expr; Stmt = stmt; Type = type; }
public BuiltInBinaryOperator(string name, CheezType resType, CheezType lhs, CheezType rhs, ComptimeExecution exe = null) { Name = name; ResultType = resType; LhsType = lhs; RhsType = rhs; Execution = exe; }
public int Accepts(CheezType lhs, CheezType rhs) { if (lhs is FunctionType f1 && rhs is FunctionType f2 && f1 == f2) { return(0); } return(-1); }
public int Accepts(CheezType sub) { if (SubExprType == sub) { return(0); } return(-1); }
public int Accepts(CheezType lhs, CheezType rhs) { if (lhs == rhs && lhs == EnumType) { return(0); } return(-1); }
public int Accepts(CheezType lhs, CheezType rhs) { if (lhs is TraitType && rhs == PointerType.NullLiteralType) { return(0); } return(-1); }
public int Accepts(CheezType lhs, CheezType rhs) { if (lhs is PointerType lt && rhs is PointerType rt) { return(0); } return(-1); }
/// <summary> /// Returns a list of all impl blocks which apply to a given type /// /// </summary> /// <param name="type"></param> /// <param name="trait"></param> /// <returns></returns> public List <AstImplBlock> GetImplsForType(CheezType type, CheezType trait = null) { var impls = GetImplsForTypeHelper(type); if (trait != null) { return(impls.Where(i => i.Trait == trait).ToList()); } return(impls.ToList()); }
private int GetAlignOfType(CheezType type) { if (type.GetSize() >= 0) { return(type.GetAlignment()); } var path = new List <CheezType>(); return(ComputeSizeAndAlignmentOfType(type, path).alignment); }
private bool IsTypeDefaultConstructable(CheezType type) { if (type.IsDefaultConstructableComputed()) { return(type.GetIsDefaultConstructable()); } var path = new List <CheezType>(); return(ComputeIsDefaultConstructableOfType(type, path)); }
private bool SizeOfTypeDependsOnSelfType(CheezType type) { switch (type) { case SelfType _: return(true); case StructType str: ComputeStructMembers(str.Declaration); return(str.Declaration.Members.Any(m => SizeOfTypeDependsOnSelfType(m.Type))); case TupleType t: return(t.Members.Any(m => SizeOfTypeDependsOnSelfType(m.type))); case EnumType en: ComputeEnumMembers(en.Declaration); return(en.Declaration.Members.Any(m => m.AssociatedType != null ? SizeOfTypeDependsOnSelfType(m.AssociatedType) : false)); case ArrayType t: return(SizeOfTypeDependsOnSelfType(t.TargetType)); case RangeType r: return(SizeOfTypeDependsOnSelfType(r.TargetType)); case ReferenceType _: case PointerType _: case SliceType _: case FunctionType _: case TraitType _: case VoidType _: case PolyType _: case IntType _: case FloatType _: case BoolType _: case CharType _: case StringType _: return(false); case CheezTypeType _: return(false); case GenericStructType _: case GenericEnumType _: case GenericTraitType _: case GenericFunctionType _: return(false); case ErrorType _: return(false); default: throw new NotImplementedException(); } }
public int Accepts(CheezType lhs, CheezType rhs) { if (lhs is PolyValueType && rhs is PolyValueType) { return(0); } if (lhs is PolyValueType || rhs is PolyValueType) { return(1); } return(-1); }
public int Accepts(CheezType lhs, CheezType rhs) { var ml = LhsType.Match(lhs, null); var mr = RhsType.Match(rhs, null); if (ml == -1 || mr == -1) { return(-1); } return(ml + mr); }
public int Accepts(CheezType sub) { Dictionary <string, (CheezType type, object value)> polyTypes = null; // TODO: necessary? //if (SubExprType.IsPolyType) //{ // polyTypes = new Dictionary<string, CheezType>(); // Workspace.CollectPolyTypes(SubExprType, lhs, polyTypes); //} return(SubExprType.Match(sub, polyTypes)); }
private AstExpression InferTypeGenericExpr(AstGenericExpr expr, CheezType expected, TypeInferenceContext context) { foreach (var param in expr.Parameters) { param.Scope = expr.Scope; param.TypeExpr.AttachTo(expr); param.TypeExpr = InferTypeHelper(param.TypeExpr, null, context); param.Type = param.TypeExpr.Value as CheezType; if (!ValidatePolymorphicParameterType(param.Location, param.Type)) { return(expr); } } expr.Type = new GenericType(expr); expr.Value = new PolyValue("generic"); return(expr); }
public int Accepts(CheezType lhs, CheezType rhs) { Dictionary <string, (CheezType type, object value)> polyTypes = null; if (LhsType.IsPolyType || RhsType.IsPolyType) { polyTypes = new Dictionary <string, (CheezType type, object value)>(); Workspace.CollectPolyTypes(LhsType, lhs, polyTypes); Workspace.CollectPolyTypes(RhsType, rhs, polyTypes); } var ml = LhsType.Match(lhs, polyTypes); var mr = RhsType.Match(rhs, polyTypes); if (ml == -1 || mr == -1) { return(-1); } return(ml + mr); }
private HashSet <AstImplBlock> GetImplsForTypeHelper(CheezType type) { if (type.IsErrorType) { WellThatsNotSupposedToHappen(); } if (m_typeImplMap == null) { UpdateTypeImplMap(); } if (m_typeImplMap.TryGetValue(type, out var _list)) { return(_list.impls); } m_typeImplMap[type] = new TypeImplList(mAllImpls); UpdateTypeImplMap(); return(m_typeImplMap[type].impls); }
private AstExpression ResolveTypeHelper(AstExpression expr, out CheezType type) { expr = InferType(expr, CheezType.Type); if (expr.Type.IsErrorType) { type = CheezType.Error; expr.Value = CheezType.Error; return(expr); } if (expr.Type != CheezType.Type) { ReportError(expr, $"Expected type"); type = CheezType.Error; expr.Value = CheezType.Error; return(expr); } else { type = expr.Value as CheezType; } return(expr); }
private bool Move(CheezType targetType, AstExpression expr, SymbolStatusTable symStatTable, ILocation location) { //if (!(targetType is ReferenceType) && expr.Type is ReferenceType r && !r.TargetType.IsCopy) //{ // ReportError(location, $"Can't move out of reference, the type '{r.TargetType}' can't be copied"); // return false; //} switch (expr) { //case AstTempVarExpr tmp: // { // return Move(targetType, tmp.Expr, symStatTable, location); // } case AstDotExpr dot: { if (dot.Left.Type is EnumType) { Move(targetType, dot.Left, symStatTable, location); return(true); } else if (!dot.Type.IsCopy) { ReportError(location ?? expr, $"Can't move out of '{dot}' because type {dot.Type} is not copy"); return(false); } return(true); } case AstDereferenceExpr d when(!(targetType is ReferenceType) && d.Reference): { return(Move(targetType, d.SubExpression, symStatTable, location)); } case AstIdExpr id: { if (symStatTable.TryGetSymbolStatus(id.Symbol, out var status)) { if (status.kind != SymbolStatus.Kind.initialized) { ReportError(location ?? expr, $"Can't move out of '{id.Name}' because it is {status.kind}", ("Moved here:", status.location)); return(false); } else { // check if type is move or copy var type = (id.Symbol as ITypedSymbol).Type; if (!type.IsCopy) { symStatTable.UpdateSymbolStatus(id.Symbol, SymbolStatus.Kind.moved, expr); } } } else if (id.Symbol is Using use) { return(Move(targetType, use.Expr, symStatTable, id.Location)); } return(true); } //case AstStructValueExpr _: // // TODO: move arguments // break; default: return(true); } }
public override int Match(CheezType concrete, Dictionary <string, (CheezType type, object value)> polyTypes)
private AstExpression ResolveTypeNow(AstExpression expr, out CheezType type, bool resolvePolyExprToConcreteType = false, HashSet <AstDecl> dependencies = null, bool forceInfer = false) { expr = InferType(expr, CheezType.Type, resolvePolyExprToConcreteType, dependencies, forceInfer); return(ResolveTypeHelper(expr, out type)); }
private AstExpression ResolveType(AstExpression expr, List <AstDecl> newPolyDecls, out CheezType type) { expr = InferTypeHelper(expr, CheezType.Type, new TypeInferenceContext { newPolyDeclarations = newPolyDecls }); return(ResolveTypeHelper(expr, out type)); }
private AstExpression ResolveType(AstExpression expr, TypeInferenceContext context, out CheezType type) { expr = InferTypeHelper(expr, CheezType.Type, context); return(ResolveTypeHelper(expr, out type)); }
private void Pass3TraitImpl(AstImplBlock impl) { if (!impl.IsPolyInstance) { impl.SubScope = new Scope($"impl {impl.TraitExpr} for {impl.TargetTypeExpr}", impl.Scope); if (impl.Parameters?.Count > 0) { impl.IsPolymorphic = true; } } impl.TraitExpr.Scope = impl.SubScope; if (impl.IsPolymorphic) { // setup scopes foreach (var param in impl.Parameters) { param.Scope = impl.Scope; param.TypeExpr.Scope = impl.Scope; param.TypeExpr.SetFlag(ExprFlags.ValueRequired, true); param.TypeExpr = ResolveTypeNow(param.TypeExpr, out var newType, forceInfer: true); if (newType is AbstractType) { continue; } param.Type = newType; switch (param.Type) { case CheezTypeType _: param.Value = new PolyType(param.Name.Name, true); if (param.Name != null) { impl.SubScope.DefineTypeSymbol(param.Name.Name, new PolyType(param.Name.Name, true)); } break; case IntType _: case FloatType _: case BoolType _: case CharType _: if (param.Name != null) { impl.SubScope.DefineConstant(param.Name.Name, param.Type, new PolyValue(param.Name.Name)); } //impl.SubScope.DefineConstant(param.Name.Name, CheezType.PolyValue, new PolyValue(param.Name.Name)); break; case ErrorType _: break; default: ReportError(param.TypeExpr, $"The type '{param.Type}' is not allowed here."); break; } } } impl.TraitExpr.SetFlag(ExprFlags.ValueRequired, true); impl.TraitExpr = ResolveTypeNow(impl.TraitExpr, out var type, resolvePolyExprToConcreteType: true); if (type is TraitType tt) { impl.Trait = tt; } else { if (!type.IsErrorType) { ReportError(impl.TraitExpr, $"{type} is not a trait"); } impl.Trait = new TraitErrorType(); return; } impl.TargetTypeExpr.SetFlag(ExprFlags.ValueRequired, true); impl.TargetTypeExpr.Scope = impl.SubScope; impl.TargetTypeExpr = ResolveTypeNow(impl.TargetTypeExpr, out var t, resolvePolyExprToConcreteType: !impl.IsPolymorphic); impl.TargetType = t; if (impl.TargetType is StructType @struct) { @struct.Declaration.Traits.Add(impl.Trait); } if (impl.Conditions != null) { if (impl.Parameters == null) { ReportError(new Location(impl.Conditions.First().Location.Beginning, impl.Conditions.Last().Location.End), $"An impl block can't have a condition without parameters"); } foreach (var cond in impl.Conditions) { cond.Scope = impl.SubScope; } } if (impl.IsPolymorphic) { return; } impl.SubScope.DefineTypeSymbol("Self", impl.TargetType); // register impl in trait if (impl.Trait.Declaration.Implementations.TryGetValue(impl.TargetType, out var otherImpl)) { ReportError(impl.TargetTypeExpr, $"There already exists an implementation of trait {impl.Trait} for type {impl.TargetType}", ("Other implementation here:", otherImpl.TargetTypeExpr)); } impl.Trait.Declaration.Implementations[impl.TargetType] = impl; // @TODO: should not be necessary AddTraitForType(impl.TargetType, impl); SortDeclarationsIntoImplBlock(impl); // handle functions foreach (var f in impl.Functions) { f.Scope = impl.SubScope; f.ConstScope = new Scope($"fn$ {f.Name}", f.Scope); f.SubScope = new Scope($"fn {f.Name}", f.ConstScope); f.ImplBlock = impl; InferTypeFuncExpr(f); CheckForSelfParam(f); impl.Scope.DefineImplFunction(f); impl.SubScope.DefineSymbol(f); if (f.Body == null) { ReportError(f.ParameterLocation, $"Function must have an implementation"); } } ComputeTraitMembers(impl.Trait.Declaration); // match functions against trait functions foreach (var traitFunc in impl.Trait.Declaration.Functions) { // find matching function bool found = false; foreach (var func in impl.Functions) { if (func.Name != traitFunc.Name) { continue; } func.TraitFunction = traitFunc; found = true; if (func.SelfType != traitFunc.SelfType) { ReportError(func.ParameterLocation, $"The self parameter of this function doesn't match the trait functions self parameter", ("Trait function defined here:", traitFunc.ParameterLocation)); continue; } if (func.Parameters.Count != traitFunc.Parameters.Count) { ReportError(func.ParameterLocation, $"This function must take the same parameters as the corresponding trait function", ("Trait function defined here:", traitFunc)); continue; } int i = 0; // if first param is self param, skip it if (func.SelfType != SelfParamType.None) { i = 1; } for (; i < func.Parameters.Count; i++) { var fp = func.Parameters[i]; var tp = traitFunc.Parameters[i]; if (tp.Type is SelfType) { if (fp.Type != impl.TargetType) { ReportError( fp.TypeExpr, $"Type of parameter '{fp.Type}' must be the implemented type '{impl.TargetType}'", ("Trait function parameter type defined here:", tp.TypeExpr)); } } else if (!CheezType.TypesMatch(fp.Type, tp.Type)) { ReportError( fp.TypeExpr, $"Type of parameter '{fp.Type}' must match the type of the trait functions parameter '{tp.Type}'", ("Trait function parameter type defined here:", tp.TypeExpr)); } } // check return type if (traitFunc.ReturnType is SelfType) { if (func.ReturnType != impl.TargetType) { ReportError( func.ReturnTypeExpr?.Location ?? func.ParameterLocation, $"Return type '{func.ReturnType}' must be the implemented type '{impl.TargetType}'", ("Trait function parameter type defined here:", traitFunc.ReturnTypeExpr?.Location ?? traitFunc.ParameterLocation)); } } else if (!CheezType.TypesMatch(func.ReturnType, traitFunc.ReturnType)) { ReportError( func.ReturnTypeExpr?.Location ?? func.ParameterLocation, $"Return type must match the trait functions return type", ("Trait function parameter type defined here:", traitFunc.ReturnTypeExpr?.Location ?? traitFunc.ParameterLocation)); } } if (!found) { ReportError( impl.TargetTypeExpr, $"Missing implementation for trait function '{traitFunc.Name}'", ("Trait function defined here:", traitFunc)); } } }
public ConstSymbol(string name, CheezType type, object value) { this.Name = name; this.Type = type; this.Value = value; }
public BuiltInPolyValueBinaryOperator(string name, CheezType resType) { Name = name; ResultType = resType; }
public TypeSymbol(string name, CheezType type) { this.Name = name; this.Type = type; }
public int Accepts(CheezType sub) { return(SubExprType.Match(sub, null)); }