| // Copyright 2017 The Wuffs Authors. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // https://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| package check |
| |
| import ( |
| "fmt" |
| |
| "github.com/google/wuffs/lang/builtin" |
| |
| a "github.com/google/wuffs/lang/ast" |
| t "github.com/google/wuffs/lang/token" |
| ) |
| |
| var ( |
| exprArgs = a.NewExpr(0, 0, t.IDArgs, nil, nil, nil, nil) |
| exprNullptr = a.NewExpr(0, 0, t.IDNullptr, nil, nil, nil, nil) |
| exprThis = a.NewExpr(0, 0, t.IDThis, nil, nil, nil, nil) |
| ) |
| |
| var ( |
| typeExprGeneric1 = a.NewTypeExpr(0, t.IDBase, t.IDDagger1, nil, nil, nil) |
| typeExprGeneric2 = a.NewTypeExpr(0, t.IDBase, t.IDDagger2, nil, nil, nil) |
| typeExprIdeal = a.NewTypeExpr(0, t.IDBase, t.IDQIdeal, nil, nil, nil) |
| typeExprList = a.NewTypeExpr(0, t.IDBase, t.IDComma, nil, nil, nil) |
| typeExprNonNullptr = a.NewTypeExpr(0, t.IDBase, t.IDQNonNullptr, nil, nil, nil) |
| typeExprNullptr = a.NewTypeExpr(0, t.IDBase, t.IDQNullptr, nil, nil, nil) |
| typeExprPackage = a.NewTypeExpr(0, t.IDBase, t.IDQPackage, nil, nil, nil) |
| typeExprPlaceholder = a.NewTypeExpr(0, t.IDBase, t.IDQPlaceholder, nil, nil, nil) |
| typeExprTypeExpr = a.NewTypeExpr(0, t.IDBase, t.IDQTypeExpr, nil, nil, nil) |
| |
| typeExprU8 = a.NewTypeExpr(0, t.IDBase, t.IDU8, nil, nil, nil) |
| typeExprU16 = a.NewTypeExpr(0, t.IDBase, t.IDU16, nil, nil, nil) |
| typeExprU32 = a.NewTypeExpr(0, t.IDBase, t.IDU32, nil, nil, nil) |
| typeExprU64 = a.NewTypeExpr(0, t.IDBase, t.IDU64, nil, nil, nil) |
| |
| typeExprEmptyStruct = a.NewTypeExpr(0, t.IDBase, t.IDEmptyStruct, nil, nil, nil) |
| typeExprBool = a.NewTypeExpr(0, t.IDBase, t.IDBool, nil, nil, nil) |
| typeExprUtility = a.NewTypeExpr(0, t.IDBase, t.IDUtility, nil, nil, nil) |
| |
| typeExprRangeIEU32 = a.NewTypeExpr(0, t.IDBase, t.IDRangeIEU32, nil, nil, nil) |
| typeExprRangeIIU32 = a.NewTypeExpr(0, t.IDBase, t.IDRangeIIU32, nil, nil, nil) |
| typeExprRangeIEU64 = a.NewTypeExpr(0, t.IDBase, t.IDRangeIEU64, nil, nil, nil) |
| typeExprRangeIIU64 = a.NewTypeExpr(0, t.IDBase, t.IDRangeIIU64, nil, nil, nil) |
| typeExprRectIEU32 = a.NewTypeExpr(0, t.IDBase, t.IDRectIEU32, nil, nil, nil) |
| typeExprRectIIU32 = a.NewTypeExpr(0, t.IDBase, t.IDRectIIU32, nil, nil, nil) |
| |
| typeExprMoreInformation = a.NewTypeExpr(0, t.IDBase, t.IDMoreInformation, nil, nil, nil) |
| |
| typeExprStatus = a.NewTypeExpr(0, t.IDBase, t.IDStatus, nil, nil, nil) |
| |
| typeExprIOReader = a.NewTypeExpr(0, t.IDBase, t.IDIOReader, nil, nil, nil) |
| typeExprIOWriter = a.NewTypeExpr(0, t.IDBase, t.IDIOWriter, nil, nil, nil) |
| typeExprTokenReader = a.NewTypeExpr(0, t.IDBase, t.IDTokenReader, nil, nil, nil) |
| typeExprTokenWriter = a.NewTypeExpr(0, t.IDBase, t.IDTokenWriter, nil, nil, nil) |
| |
| typeExprFrameConfig = a.NewTypeExpr(0, t.IDBase, t.IDFrameConfig, nil, nil, nil) |
| typeExprImageConfig = a.NewTypeExpr(0, t.IDBase, t.IDImageConfig, nil, nil, nil) |
| typeExprPixelBlend = a.NewTypeExpr(0, t.IDBase, t.IDPixelBlend, nil, nil, nil) |
| typeExprPixelBuffer = a.NewTypeExpr(0, t.IDBase, t.IDPixelBuffer, nil, nil, nil) |
| typeExprPixelConfig = a.NewTypeExpr(0, t.IDBase, t.IDPixelConfig, nil, nil, nil) |
| typeExprPixelFormat = a.NewTypeExpr(0, t.IDBase, t.IDPixelFormat, nil, nil, nil) |
| typeExprPixelSwizzler = a.NewTypeExpr(0, t.IDBase, t.IDPixelSwizzler, nil, nil, nil) |
| |
| typeExprDecodeFrameOptions = a.NewTypeExpr(0, t.IDBase, t.IDDecodeFrameOptions, nil, nil, nil) |
| |
| typeExprARMCRC32Utility = a.NewTypeExpr(0, t.IDBase, t.IDARMCRC32Utility, nil, nil, nil) |
| typeExprARMCRC32U32 = a.NewTypeExpr(0, t.IDBase, t.IDARMCRC32U32, nil, nil, nil) |
| |
| typeExprARMNeonUtility = a.NewTypeExpr(0, t.IDBase, t.IDARMNeonUtility, nil, nil, nil) |
| typeExprARMNeonU8x8 = a.NewTypeExpr(0, t.IDBase, t.IDARMNeonU8x8, nil, nil, nil) |
| typeExprARMNeonU16x4 = a.NewTypeExpr(0, t.IDBase, t.IDARMNeonU16x4, nil, nil, nil) |
| typeExprARMNeonU32x2 = a.NewTypeExpr(0, t.IDBase, t.IDARMNeonU32x2, nil, nil, nil) |
| typeExprARMNeonU64x1 = a.NewTypeExpr(0, t.IDBase, t.IDARMNeonU64x1, nil, nil, nil) |
| typeExprARMNeonU8x16 = a.NewTypeExpr(0, t.IDBase, t.IDARMNeonU8x16, nil, nil, nil) |
| typeExprARMNeonU16x8 = a.NewTypeExpr(0, t.IDBase, t.IDARMNeonU16x8, nil, nil, nil) |
| typeExprARMNeonU32x4 = a.NewTypeExpr(0, t.IDBase, t.IDARMNeonU32x4, nil, nil, nil) |
| typeExprARMNeonU64x2 = a.NewTypeExpr(0, t.IDBase, t.IDARMNeonU64x2, nil, nil, nil) |
| |
| typeExprX86SSE42Utility = a.NewTypeExpr(0, t.IDBase, t.IDX86SSE42Utility, nil, nil, nil) |
| typeExprX86M128I = a.NewTypeExpr(0, t.IDBase, t.IDX86M128I, nil, nil, nil) |
| |
| typeExprX86AVX2Utility = a.NewTypeExpr(0, t.IDBase, t.IDX86AVX2Utility, nil, nil, nil) |
| typeExprX86M256I = a.NewTypeExpr(0, t.IDBase, t.IDX86M256I, nil, nil, nil) |
| |
| typeExprSliceU8 = a.NewTypeExpr(t.IDSlice, 0, 0, nil, nil, typeExprU8) |
| typeExprTableU8 = a.NewTypeExpr(t.IDTable, 0, 0, nil, nil, typeExprU8) |
| ) |
| |
| func setPlaceholderMBoundsMType(n *a.Node) { |
| n.SetMBounds(bounds{zero, zero}) |
| n.SetMType(typeExprPlaceholder) |
| } |
| |
| // typeMap maps from variable names (as token IDs) to types. |
| type typeMap map[t.ID]*a.TypeExpr |
| |
| var builtInTypeMap = typeMap{ |
| t.IDU8: typeExprU8, |
| t.IDU16: typeExprU16, |
| t.IDU32: typeExprU32, |
| t.IDU64: typeExprU64, |
| |
| t.IDEmptyStruct: typeExprEmptyStruct, |
| t.IDBool: typeExprBool, |
| t.IDUtility: typeExprUtility, |
| |
| t.IDRangeIEU32: typeExprRangeIEU32, |
| t.IDRangeIIU32: typeExprRangeIIU32, |
| t.IDRangeIEU64: typeExprRangeIEU64, |
| t.IDRangeIIU64: typeExprRangeIIU64, |
| t.IDRectIEU32: typeExprRectIEU32, |
| t.IDRectIIU32: typeExprRectIIU32, |
| |
| t.IDMoreInformation: typeExprMoreInformation, |
| |
| t.IDStatus: typeExprStatus, |
| |
| t.IDIOReader: typeExprIOReader, |
| t.IDIOWriter: typeExprIOWriter, |
| t.IDTokenReader: typeExprTokenReader, |
| t.IDTokenWriter: typeExprTokenWriter, |
| |
| t.IDFrameConfig: typeExprFrameConfig, |
| t.IDImageConfig: typeExprImageConfig, |
| t.IDPixelBlend: typeExprPixelBlend, |
| t.IDPixelBuffer: typeExprPixelBuffer, |
| t.IDPixelConfig: typeExprPixelConfig, |
| t.IDPixelFormat: typeExprPixelFormat, |
| t.IDPixelSwizzler: typeExprPixelSwizzler, |
| |
| t.IDDecodeFrameOptions: typeExprDecodeFrameOptions, |
| |
| t.IDARMCRC32Utility: typeExprARMCRC32Utility, |
| t.IDARMCRC32U32: typeExprARMCRC32U32, |
| |
| t.IDARMNeonUtility: typeExprARMNeonUtility, |
| t.IDARMNeonU8x8: typeExprARMNeonU8x8, |
| t.IDARMNeonU16x4: typeExprARMNeonU16x4, |
| t.IDARMNeonU32x2: typeExprARMNeonU32x2, |
| t.IDARMNeonU64x1: typeExprARMNeonU64x1, |
| t.IDARMNeonU8x16: typeExprARMNeonU8x16, |
| t.IDARMNeonU16x8: typeExprARMNeonU16x8, |
| t.IDARMNeonU32x4: typeExprARMNeonU32x4, |
| t.IDARMNeonU64x2: typeExprARMNeonU64x2, |
| |
| t.IDX86SSE42Utility: typeExprX86SSE42Utility, |
| t.IDX86M128I: typeExprX86M128I, |
| |
| t.IDX86AVX2Utility: typeExprX86AVX2Utility, |
| t.IDX86M256I: typeExprX86M256I, |
| } |
| |
| func (c *Checker) parseBuiltInFuncs(m map[t.QQID]*a.Func, ss []string) error { |
| return builtin.ParseFuncs(c.tm, ss, func(f *a.Func) error { |
| if err := c.checkFuncSignature1(f.AsNode(), false); err != nil { |
| return err |
| } |
| if m != nil { |
| m[f.QQID()] = f |
| } |
| return nil |
| }) |
| } |
| |
| func (c *Checker) resolveFunc(typ *a.TypeExpr) (*a.Func, error) { |
| if typ.Decorator() != t.IDFunc { |
| return nil, fmt.Errorf("check: resolveFunc cannot look up non-func TypeExpr %q", typ.Str(c.tm)) |
| } |
| lTyp := typ.Receiver() |
| lQID := lTyp.QID() |
| qqid := t.QQID{lQID[0], lQID[1], typ.FuncName()} |
| |
| if lTyp.IsSliceType() { |
| qqid[0] = t.IDBase |
| qqid[1] = t.IDDagger1 |
| if f := c.builtInSliceFuncs[qqid]; f != nil { |
| return f, nil |
| } |
| if lTyp.Eq(typeExprSliceU8) { |
| if f := c.builtInSliceU8Funcs[qqid]; f != nil { |
| return f, nil |
| } |
| } |
| |
| } else if lTyp.IsTableType() { |
| qqid[0] = t.IDBase |
| qqid[1] = t.IDDagger2 |
| if f := c.builtInTableFuncs[qqid]; f != nil { |
| return f, nil |
| } |
| |
| } else if f := c.funcs[qqid]; f != nil { |
| return f, nil |
| } |
| return nil, fmt.Errorf("check: resolveFunc cannot look up %q", typ.Str(c.tm)) |
| } |