From ab48cb94f48d1b86139e3fcafc26d3f94f57ad82 Mon Sep 17 00:00:00 2001 From: Stachu Korick Date: Wed, 17 Apr 2024 15:07:14 -0400 Subject: [PATCH 1/8] remove some usertype tests --- ...on-ProgramTypes-Toplevel-T_recordtype.json | 182 ------------------ .../Tests/Serialization.DarkTypes.Tests.fs | 8 - .../tests/Tests/Serialization.TestValues.fs | 34 +--- .../Tests/Serialization.Vanilla.Tests.fs | 3 - 4 files changed, 1 insertion(+), 226 deletions(-) delete mode 100644 backend/serialization/vanilla_LibExecution-ProgramTypes-Toplevel-T_recordtype.json diff --git a/backend/serialization/vanilla_LibExecution-ProgramTypes-Toplevel-T_recordtype.json b/backend/serialization/vanilla_LibExecution-ProgramTypes-Toplevel-T_recordtype.json deleted file mode 100644 index 09a19c6666..0000000000 --- a/backend/serialization/vanilla_LibExecution-ProgramTypes-Toplevel-T_recordtype.json +++ /dev/null @@ -1,182 +0,0 @@ -{ - "TLType": [ - { - "tlid": 0, - "name": { - "modules": [], - "name": "User", - "version": 0 - }, - "declaration": { - "typeParams": [ - "a" - ], - "definition": { - "Record": [ - [ - { - "name": "prop1", - "typ": { - "TTuple": [ - { - "TInt64": [] - }, - { - "TFloat": [] - }, - [ - { - "TBool": [] - }, - { - "TUnit": [] - }, - { - "TUInt64": [] - }, - { - "TInt8": [] - }, - { - "TUInt8": [] - }, - { - "TInt16": [] - }, - { - "TUInt16": [] - }, - { - "TInt32": [] - }, - { - "TUInt32": [] - }, - { - "TInt128": [] - }, - { - "TUInt128": [] - }, - { - "TString": [] - }, - { - "TList": [ - { - "TInt64": [] - } - ] - }, - { - "TTuple": [ - { - "TBool": [] - }, - { - "TBool": [] - }, - [ - { - "TBool": [] - } - ] - ] - }, - { - "TDict": [ - { - "TBool": [] - } - ] - }, - { - "TDB": [ - { - "TBool": [] - } - ] - }, - { - "TCustomType": [ - { - "Ok": [ - { - "UserProgram": [ - { - "modules": [ - "Mod" - ], - "name": "User", - "version": 0 - } - ] - } - ] - }, - [ - { - "TBool": [] - } - ] - ] - }, - { - "TCustomType": [ - { - "Ok": [ - { - "Package": [ - { - "owner": "dark", - "modules": [ - "Mod1", - "Mod2" - ], - "name": "Pack", - "version": 0 - } - ] - } - ] - }, - [ - { - "TBool": [] - } - ] - ] - }, - { - "TVariable": [ - "test" - ] - }, - { - "TFn": [ - [ - { - "TBool": [] - } - ], - { - "TBool": [] - } - ] - } - ] - ] - }, - "description": "desc1" - } - ] - ] - } - }, - "description": "test description", - "deprecated": { - "NotDeprecated": [] - } - } - ] -} \ No newline at end of file diff --git a/backend/tests/Tests/Serialization.DarkTypes.Tests.fs b/backend/tests/Tests/Serialization.DarkTypes.Tests.fs index 54accbbcba..d2252d1286 100644 --- a/backend/tests/Tests/Serialization.DarkTypes.Tests.fs +++ b/backend/tests/Tests/Serialization.DarkTypes.Tests.fs @@ -214,14 +214,6 @@ module RoundtripTests = PT2DT.UserFunction.fromDT None - testRoundtripList - "PT.UserTypes" - (pkg [] "UserType" 0) - V.ProgramTypes.userTypes - PT2DT.UserType.toDT - PT2DT.UserType.fromDT - None - testRoundtripList "PT.UserConstants" (pkg [] "UserConstant" 0) diff --git a/backend/tests/Tests/Serialization.TestValues.fs b/backend/tests/Tests/Serialization.TestValues.fs index 2b4c7edaf9..420cddc102 100644 --- a/backend/tests/Tests/Serialization.TestValues.fs +++ b/backend/tests/Tests/Serialization.TestValues.fs @@ -870,37 +870,6 @@ module ProgramTypes = let userFunctions : List = [ userFunction ] - let userRecordType : PT.UserType.T = - { tlid = 0UL - name = { modules = []; name = "User"; version = 0 } - description = "test description" - deprecated = PT.NotDeprecated - declaration = - { typeParams = [ "a" ] - definition = - let firstField : PT.TypeDeclaration.RecordField = - { name = "prop1"; typ = typeReference; description = "desc1" } - PT.TypeDeclaration.Record(NEList.singleton firstField) } } - - let userEnumType : PT.UserType.T = - { tlid = 0UL - name = { modules = []; name = "User"; version = 0 } - deprecated = PT.NotDeprecated - description = "test description" - declaration = - { typeParams = [ "a" ] - definition = - PT.TypeDeclaration.Enum( - NEList.ofList - { name = "caseA"; fields = []; description = "" } - [ { name = "caseB" - fields = - [ { typ = typeReference; label = Some "i"; description = "" } ] - description = "" } ] - ) } } - - let userTypes : List = [ userRecordType; userEnumType ] - let userConstant : PT.UserConstant.T = { tlid = 0UL name = { modules = []; name = "pi"; version = 0 } @@ -974,8 +943,7 @@ module ProgramTypes = [ List.map PT.Toplevel.TLHandler Handler.handlers List.map PT.Toplevel.TLDB [ userDB ] List.map PT.Toplevel.TLFunction userFunctions - List.map PT.Toplevel.TLConstant userConstants - List.map PT.Toplevel.TLType userTypes ] + List.map PT.Toplevel.TLConstant userConstants ] |> List.concat let userSecret : PT.Secret.T = { name = "APIKEY"; value = "hunter2"; version = 0 } diff --git a/backend/tests/Tests/Serialization.Vanilla.Tests.fs b/backend/tests/Tests/Serialization.Vanilla.Tests.fs index fda26f34cb..0e0c368fd2 100644 --- a/backend/tests/Tests/Serialization.Vanilla.Tests.fs +++ b/backend/tests/Tests/Serialization.Vanilla.Tests.fs @@ -88,9 +88,6 @@ module PersistedSerializations = v "function" (PT.Toplevel.TLFunction V.ProgramTypes.userFunction) - v - "recordtype" - (PT.Toplevel.TLType V.ProgramTypes.userRecordType) // ------------------ // LibCloud From 13a9c939fa7466b8687d9af27915caf30b63a230 Mon Sep 17 00:00:00 2001 From: Stachu Korick Date: Wed, 17 Apr 2024 15:07:43 -0400 Subject: [PATCH 2/8] add some helper fns --- backend/src/LibExecution/ProgramTypes.fs | 8 ++++++++ backend/src/LibExecution/RuntimeTypes.fs | 17 +++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/backend/src/LibExecution/ProgramTypes.fs b/backend/src/LibExecution/ProgramTypes.fs index 5156186fd3..c00864d025 100644 --- a/backend/src/LibExecution/ProgramTypes.fs +++ b/backend/src/LibExecution/ProgramTypes.fs @@ -724,6 +724,14 @@ module UserType = description : string deprecated : Deprecation } + let fromPackageType (t : PackageType.T) : T = + { tlid = t.tlid + name = + { modules = t.name.modules; name = t.name.name; version = t.name.version } + declaration = t.declaration + description = t.description + deprecated = t.deprecated } + module UserConstant = type T = { tlid : tlid diff --git a/backend/src/LibExecution/RuntimeTypes.fs b/backend/src/LibExecution/RuntimeTypes.fs index af3b7b2353..f77339f867 100644 --- a/backend/src/LibExecution/RuntimeTypes.fs +++ b/backend/src/LibExecution/RuntimeTypes.fs @@ -1326,6 +1326,23 @@ module UserType = type T = { tlid : tlid; name : FQTypeName.UserProgram; declaration : TypeDeclaration.T } + let mapNameFromPackageType (t : FQTypeName.Package) : FQTypeName.UserProgram = + { modules = t.modules; name = t.name; version = t.version } + + let mapFromPackageType (t : PackageType.T) : T = + { tlid = gid () + name = mapNameFromPackageType t.name + declaration = t.declaration } + + let mapMapFromPackageType + (t : Map) + : Map = + t + |> Map.toList + |> List.map (fun (k, v) -> (mapNameFromPackageType k, mapFromPackageType v)) + |> Map + + module UserConstant = type T = { tlid : tlid; name : FQConstantName.UserProgram; body : Const } From e545008878e834e558afcfaa23285dd81dfb55e7 Mon Sep 17 00:00:00 2001 From: Stachu Korick Date: Wed, 17 Apr 2024 15:11:19 -0400 Subject: [PATCH 3/8] fix comment --- backend/src/LocalExec/LoadPackagesFromDisk.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/LocalExec/LoadPackagesFromDisk.fs b/backend/src/LocalExec/LoadPackagesFromDisk.fs index 37c2d0de7c..f53af24094 100644 --- a/backend/src/LocalExec/LoadPackagesFromDisk.fs +++ b/backend/src/LocalExec/LoadPackagesFromDisk.fs @@ -36,7 +36,7 @@ let load (builtins : RT.Builtins) : Ply = LibParser.Parser.parsePackageFile nameResolver path contents) |> Ply.map PT.Packages.combine - // 3. re-parse the packages, though this time we don't allow unresolved names + // Re-parse the packages, though this time we don't allow unresolved names // (any package references that may have been unresolved a second ago should now be OK) let nameResolver = { nameResolver with From 364de46a17a68421429acf29b216faabaf42c214 Mon Sep 17 00:00:00 2001 From: Stachu Korick Date: Wed, 17 Apr 2024 15:21:06 -0400 Subject: [PATCH 4/8] name resolver should always have a PM --- backend/src/LibParser/Canvas.fs | 4 +- backend/src/LibParser/NameResolver.fs | 45 ++++++++----------- backend/src/LocalExec/LoadPackagesFromDisk.fs | 5 +-- backend/src/LocalExec/LocalExec.fs | 2 +- backend/tests/TestUtils/TestUtils.fs | 2 +- 5 files changed, 24 insertions(+), 34 deletions(-) diff --git a/backend/src/LibParser/Canvas.fs b/backend/src/LibParser/Canvas.fs index a79c0d0c4e..a879ed44b1 100644 --- a/backend/src/LibParser/Canvas.fs +++ b/backend/src/LibParser/Canvas.fs @@ -8,6 +8,7 @@ module FS2WT = FSharpToWrittenTypes module WT = WrittenTypes module WT2PT = WrittenTypesToProgramTypes module PT = LibExecution.ProgramTypes +module RT = LibExecution.RuntimeTypes open Utils open ParserException @@ -215,11 +216,12 @@ let parseDecls (decls : List) : WTCanvasModule = emptyWTModule decls +// TOOD: determine if this should take a PM in let toResolver (canvas : WTCanvasModule) : NameResolver.NameResolver = let fns = canvas.fns |> List.map _.name let types = canvas.types |> List.map _.name let constants = canvas.constants |> List.map _.name - NameResolver.create [] [] types fns constants true None + NameResolver.create [] [] types fns constants true RT.PackageManager.Empty let toPT (nameResolver : NameResolver.NameResolver) diff --git a/backend/src/LibParser/NameResolver.fs b/backend/src/LibParser/NameResolver.fs index 32175d6242..10dbaab233 100644 --- a/backend/src/LibParser/NameResolver.fs +++ b/backend/src/LibParser/NameResolver.fs @@ -39,7 +39,7 @@ type NameResolver = hackLocallyDefinedPackageFns : Set hackLocallyDefinedPackageConstants : Set - packageManager : Option + packageManager : RT.PackageManager } @@ -58,7 +58,7 @@ let empty : NameResolver = hackLocallyDefinedPackageFns = Set.empty hackLocallyDefinedPackageConstants = Set.empty - packageManager = None } + packageManager = RT.PackageManager.Empty } let create @@ -68,7 +68,7 @@ let create (userFns : List) (userConstants : List) (allowError : bool) - (packageManager : Option) + (packageManager : RT.PackageManager) : NameResolver = { builtinFns = Set.ofList builtinFns builtinConstants = Set.ofList builtinConstants @@ -89,7 +89,7 @@ let create let merge (a : NameResolver) (b : NameResolver) - (packageManager : Option) + (packageManager : RT.PackageManager) : NameResolver = { builtinFns = Set.union a.builtinFns b.builtinFns builtinConstants = Set.union a.builtinConstants b.builtinConstants @@ -135,7 +135,7 @@ let fromBuiltins (builtins : RT.Builtins) : NameResolver = hackLocallyDefinedPackageFns = Set.empty hackLocallyDefinedPackageConstants = Set.empty - packageManager = None } + packageManager = RT.PackageManager.Empty } let fromExecutionState (state : RT.ExecutionState) : NameResolver = @@ -172,7 +172,7 @@ let fromExecutionState (state : RT.ExecutionState) : NameResolver = hackLocallyDefinedPackageTypes = Set.empty hackLocallyDefinedPackageConstants = Set.empty - packageManager = Some state.packageManager } + packageManager = state.packageManager } // TODO: there's a lot going on here to resolve the outer portion of the name and to @@ -640,17 +640,14 @@ let resolveFnName module TypeName = let packageTypeExists - (pm : Option) + (pm : RT.PackageManager) (hackLocallyDefinedPackageTypes : Set) (typeName : RT.FQTypeName.Package) : Ply = uply { - match pm with - | None -> return false - | Some pm -> - match! pm.getType typeName with - | None -> return Set.contains typeName hackLocallyDefinedPackageTypes - | Some _ -> return true + match! pm.getType typeName with + | None -> return Set.contains typeName hackLocallyDefinedPackageTypes + | Some _ -> return true } let maybeResolve @@ -692,17 +689,14 @@ module TypeName = module ConstantName = let packageConstExists - (pm : Option) + (pm : RT.PackageManager) (hackLocallyDefinedPackageConstants : Set) (constName : RT.FQConstantName.Package) : Ply = uply { - match pm with - | None -> return false - | Some pm -> - match! pm.getConstant constName with - | None -> return Set.contains constName hackLocallyDefinedPackageConstants - | Some _ -> return true + match! pm.getConstant constName with + | None -> return Set.contains constName hackLocallyDefinedPackageConstants + | Some _ -> return true } @@ -745,17 +739,14 @@ module ConstantName = module FnName = let packageFnExists - (pm : Option) + (pm : RT.PackageManager) (hackLocallyDefinedPackageFns : Set) (fnName : RT.FQFnName.Package) : Ply = uply { - match pm with - | None -> return false - | Some pm -> - match! pm.getFn fnName with - | None -> return Set.contains fnName hackLocallyDefinedPackageFns - | Some _ -> return true + match! pm.getFn fnName with + | None -> return Set.contains fnName hackLocallyDefinedPackageFns + | Some _ -> return true } let maybeResolve diff --git a/backend/src/LocalExec/LoadPackagesFromDisk.fs b/backend/src/LocalExec/LoadPackagesFromDisk.fs index f53af24094..8b7e8c4809 100644 --- a/backend/src/LocalExec/LoadPackagesFromDisk.fs +++ b/backend/src/LocalExec/LoadPackagesFromDisk.fs @@ -42,10 +42,7 @@ let load (builtins : RT.Builtins) : Ply = { nameResolver with allowError = false packageManager = - Some( - inMemPackageManagerFromPackages - packagesParsedWithUnresolvedNamesAllowed - ) } + inMemPackageManagerFromPackages packagesParsedWithUnresolvedNamesAllowed } return! filesWithContents diff --git a/backend/src/LocalExec/LocalExec.fs b/backend/src/LocalExec/LocalExec.fs index 6760e963de..ca5206c8f2 100644 --- a/backend/src/LocalExec/LocalExec.fs +++ b/backend/src/LocalExec/LocalExec.fs @@ -46,7 +46,7 @@ module HandleCommand = let nameResolver = LibParser.NameResolver.fromBuiltins Builtins.accessibleByCanvas |> fun nr -> - { nr with packageManager = Some inMemPackageManager; allowError = false } + { nr with packageManager = inMemPackageManager; allowError = false } let! (canvasId, toplevels) = Canvas.loadFromDisk nameResolver "dark-packages" diff --git a/backend/tests/TestUtils/TestUtils.fs b/backend/tests/TestUtils/TestUtils.fs index 3cb952e021..11c1ee65c8 100644 --- a/backend/tests/TestUtils/TestUtils.fs +++ b/backend/tests/TestUtils/TestUtils.fs @@ -150,7 +150,7 @@ let packageManager = LibCloud.PackageManager.packageManager // This resolves both builtins and package functions let nameResolver = { LibParser.NameResolver.fromBuiltins localBuiltIns with - packageManager = Some packageManager } + packageManager = packageManager } let executionStateFor From 72a6e1e6ed5429f7aaaf3abfbec9204a2dc0a544 Mon Sep 17 00:00:00 2001 From: Stachu Korick Date: Sat, 20 Apr 2024 11:29:23 -0400 Subject: [PATCH 5/8] Big refactor to name-resolution --- .../serialization/toplevels-binary-latest.bin | Bin 13523 -> 13036 bytes .../toplevels-binary-pretty-latest.json | 462 -------- ...ion-ProgramTypes-Toplevel-T-_complete.json | 379 ------ backend/src/BuiltinCliHost/Libs/Cli.fs | 30 +- backend/src/LibExecution/ProgramTypes.fs | 7 +- backend/src/LibParser/Canvas.fs | 90 +- backend/src/LibParser/FSharpToWrittenTypes.fs | 6 +- backend/src/LibParser/NameResolver.fs | 1048 +++++------------ backend/src/LibParser/Package.fs | 83 +- backend/src/LibParser/Parser.fs | 47 +- backend/src/LibParser/TestModule.fs | 108 +- backend/src/LibParser/WrittenTypes.fs | 2 +- .../LibParser/WrittenTypesToProgramTypes.fs | 597 +++++++--- backend/src/LocalExec/Canvas.fs | 11 +- backend/src/LocalExec/LoadPackagesFromDisk.fs | 33 +- backend/src/LocalExec/LocalExec.fs | 8 +- backend/src/Wasm/Wasm.fsproj | 1 - .../testfiles/execution/stdlib/parser.dark | 586 ++++----- backend/tests/TestUtils/TestUtils.fs | 5 - backend/tests/Tests/BwdServer.Tests.fs | 14 +- backend/tests/Tests/Canvas.Tests.fs | 11 +- backend/tests/Tests/Cron.Tests.fs | 11 +- backend/tests/Tests/HttpClient.Tests.fs | 14 +- backend/tests/Tests/LibExecution.Tests.fs | 20 +- backend/tests/Tests/Parser.Tests.fs | 86 +- backend/tests/Tests/ProgramTypes.Tests.fs | 9 +- backend/tests/Tests/Queue.Tests.fs | 11 +- .../tests/Tests/QueueSchedulingRules.Tests.fs | 10 +- backend/tests/Tests/SqlCompiler.Tests.fs | 46 +- backend/tests/Tests/Tests.fs | 8 +- 30 files changed, 1505 insertions(+), 2238 deletions(-) diff --git a/backend/serialization/toplevels-binary-latest.bin b/backend/serialization/toplevels-binary-latest.bin index 92531909ad405a06d578cf3448bc90d62b567456..ed1a0ce2422390daf1b365bf1a6cdb37a73abac0 100644 GIT binary patch delta 10 Rcmcbd`6iWd`bNgrMgSe;1oZ#_ delta 142 zcmaEpdO4GE=0?WXMzWKbCr)FSJYh*_acU96fk_h=CQf3UIBD|If};Ea!^zch+g+BX zq!uR|PS{YAT3n(4Vi#o=lw{`TO=6gUMKcpfb8=#Fs^f$O6Co_8iIYJFNi57 = CliRuntimeError.UncaughtException(msg, metadata) |> CliRuntimeError.RTE.toRuntimeError - let nameResolver = LibParser.NameResolver.fromExecutionState state let! parsedScript = uply { try return! - LibParser.Canvas.parse nameResolver filename code |> Ply.map Ok + LibParser.Canvas.parse + state.builtins + state.packageManager + NR.HackPackageStuff.empty + (NR.UserStuff.fromProgram state.program) + NR.OnMissing.Allow // Right? kinda surprising. + filename + code + |> Ply.map Ok with e -> return Error(exnError e) } @@ -232,10 +240,13 @@ let fns : List = [] parts - let resolver = LibParser.NameResolver.fromExecutionState state let! fnName = - LibParser.NameResolver.FnName.resolve - resolver + LibParser.NameResolver.resolveFnName + (state.builtins.fns |> Map.keys |> Set) + state.packageManager + Set.empty + (NR.UserStuff.fromProgram state.program).fns + NR.OnMissing.Allow // OK? [] (WT.Unresolved name) @@ -370,10 +381,13 @@ let fns : List = [] parts - let resolver = LibParser.NameResolver.fromExecutionState state let! fnName = - LibParser.NameResolver.FnName.resolve - resolver + LibParser.NameResolver.resolveFnName + (state.builtins.fns |> Map.keys |> Set) + state.packageManager + Set.empty + (NR.UserStuff.fromProgram state.program).fns + NR.OnMissing.Allow // ok? [] (WT.Unresolved name) diff --git a/backend/src/LibExecution/ProgramTypes.fs b/backend/src/LibExecution/ProgramTypes.fs index c00864d025..dd04e76edc 100644 --- a/backend/src/LibExecution/ProgramTypes.fs +++ b/backend/src/LibExecution/ProgramTypes.fs @@ -705,10 +705,9 @@ type Packages = fns : List } static member combine(packages : List) : Packages = - // CLEANUP: can't we just List.collect here? - { types = packages |> List.map _.types |> List.concat - constants = packages |> List.map _.constants |> List.concat - fns = packages |> List.map _.fns |> List.concat } + { types = packages |> List.collect _.types + constants = packages |> List.collect _.constants + fns = packages |> List.collect _.fns } diff --git a/backend/src/LibParser/Canvas.fs b/backend/src/LibParser/Canvas.fs index a879ed44b1..186110d97b 100644 --- a/backend/src/LibParser/Canvas.fs +++ b/backend/src/LibParser/Canvas.fs @@ -9,6 +9,7 @@ module WT = WrittenTypes module WT2PT = WrittenTypesToProgramTypes module PT = LibExecution.ProgramTypes module RT = LibExecution.RuntimeTypes +module NR = NameResolver open Utils open ParserException @@ -78,6 +79,7 @@ let (|SimpleAttribute|_|) (attr : SynAttribute) = Some(attrName, parseAttrArgs attr.ArgExpr) + /// Update a CanvasModule by parsing a single F# let binding /// Depending on the attribute present, this may add a user function, a handler, or a DB let parseLetBinding (m : WTCanvasModule) (letBinding : SynBinding) : WTCanvasModule = @@ -180,6 +182,7 @@ let parseTypeDefn (m : WTCanvasModule) (typeDefn : SynTypeDefn) : WTCanvasModule { m with types = m.types @ newTypes; dbs = m.dbs @ newDBs } + /// An F# module has a list of declarations, which can be: /// - a group of let bindings /// - a group of type definitions @@ -216,36 +219,63 @@ let parseDecls (decls : List) : WTCanvasModule = emptyWTModule decls -// TOOD: determine if this should take a PM in -let toResolver (canvas : WTCanvasModule) : NameResolver.NameResolver = - let fns = canvas.fns |> List.map _.name - let types = canvas.types |> List.map _.name - let constants = canvas.constants |> List.map _.name - NameResolver.create [] [] types fns constants true RT.PackageManager.Empty let toPT - (nameResolver : NameResolver.NameResolver) + (builtins : RT.Builtins) + (pm : RT.PackageManager) + (hackPackageStuff : NR.HackPackageStuff) + (userStuff : NR.UserStuff) + (onMissing : NR.OnMissing) (m : WTCanvasModule) : Ply = uply { let! types = - m.types |> Ply.List.mapSequentially (WT2PT.UserType.toPT nameResolver m.name) + m.types + |> Ply.List.mapSequentially ( + WT2PT.UserType.toPT pm hackPackageStuff userStuff onMissing m.name + ) let! fns = - m.fns |> Ply.List.mapSequentially (WT2PT.UserFunction.toPT nameResolver m.name) + m.fns + |> Ply.List.mapSequentially ( + WT2PT.UserFunction.toPT + builtins + pm + hackPackageStuff + userStuff + onMissing + m.name + ) let! constants = m.constants - |> Ply.List.mapSequentially (WT2PT.UserConstant.toPT nameResolver m.name) - let! dbs = m.dbs |> Ply.List.mapSequentially (WT2PT.DB.toPT nameResolver m.name) + |> Ply.List.mapSequentially ( + WT2PT.UserConstant.toPT pm hackPackageStuff userStuff onMissing m.name + ) + let! dbs = + m.dbs + |> Ply.List.mapSequentially ( + WT2PT.DB.toPT pm hackPackageStuff userStuff onMissing m.name + ) let! handlers = m.handlers |> Ply.List.mapSequentially (fun (spec, expr) -> uply { let spec = WT2PT.Handler.Spec.toPT spec - let! expr = WT2PT.Expr.toPT nameResolver m.name expr + let! expr = + WT2PT.Expr.toPT + builtins + pm + hackPackageStuff + userStuff + onMissing + m.name + expr return (spec, expr) }) let! exprs = - m.exprs |> Ply.List.mapSequentially (WT2PT.Expr.toPT nameResolver m.name) + m.exprs + |> Ply.List.mapSequentially ( + WT2PT.Expr.toPT builtins pm hackPackageStuff userStuff onMissing m.name + ) return { types = types @@ -256,8 +286,13 @@ let toPT exprs = exprs } } + let parse - (resolver : NameResolver.NameResolver) + (builtins : RT.Builtins) + (pm : RT.PackageManager) + (hackPackageStuff : NR.HackPackageStuff) + (userStuff : NR.UserStuff) + (onMissing : NR.OnMissing) (filename : string) (source : string) : Ply = @@ -281,13 +316,30 @@ let parse None // whole file let module' = parseDecls decls - let resolver = - NameResolver.merge resolver (toResolver module') resolver.packageManager - toPT resolver module' + + let updatedUserStuff : NR.UserStuff = + { types = Set.union userStuff.types (module'.types |> List.map _.name |> Set) + constants = + Set.union userStuff.constants (module'.constants |> List.map _.name |> Set) + fns = Set.union userStuff.fns (module'.fns |> List.map _.name |> Set) } + + toPT + builtins + pm + hackPackageStuff + updatedUserStuff + onMissing // TODO: maybe this should be `OnMissing.Allow` -- the previous code had that... + module' let parseFromFile - (resolver : NameResolver.NameResolver) + (builtins : RT.Builtins) + (pm : RT.PackageManager) + (hackPackageStuff : NR.HackPackageStuff) + (userStuff : NR.UserStuff) + (onMissing : NR.OnMissing) (filename : string) : Ply = - filename |> System.IO.File.ReadAllText |> parse resolver filename + filename + |> System.IO.File.ReadAllText + |> parse builtins pm hackPackageStuff userStuff onMissing filename diff --git a/backend/src/LibParser/FSharpToWrittenTypes.fs b/backend/src/LibParser/FSharpToWrittenTypes.fs index ec9003304e..8cd9189bf1 100644 --- a/backend/src/LibParser/FSharpToWrittenTypes.fs +++ b/backend/src/LibParser/FSharpToWrittenTypes.fs @@ -276,7 +276,7 @@ module Expr = let private nameOrBlank (v : string) : string = if v = emptyVar then "" else v - let parseFn (fnName : string) : Result = + let parseFnName (fnName : string) : Result = match fnName with | Regex.Regex "^([a-z][a-z0-9A-Z]*[']?)_v(\d+)$" [ name; version ] -> Ok(name, (int version)) @@ -829,7 +829,7 @@ module Function = let returnType = TypeReference.fromSynType typeName let (name, version) = - Expr.parseFn name + Expr.parseFnName name |> Exception.unwrapResultInternal [ "name", name; "binding", binding ] { name = name version = version @@ -900,7 +900,7 @@ module Constant = _, _, _) -> - match Expr.parseFn name.idText with + match Expr.parseFnName name.idText with | Ok(name, version) -> { name = name; version = version; body = fromSynExpr expr } | Error errMsg -> diff --git a/backend/src/LibParser/NameResolver.fs b/backend/src/LibParser/NameResolver.fs index 10dbaab233..9d2e023a4d 100644 --- a/backend/src/LibParser/NameResolver.fs +++ b/backend/src/LibParser/NameResolver.fs @@ -1,5 +1,3 @@ -// CLEANUP : there is room for refactoring here to reduce duplicated code -/// Conversion functions from WrittenTypes to ProgramTypes module LibParser.NameResolver open Prelude @@ -11,774 +9,340 @@ module PT2RT = LibExecution.ProgramTypesToRuntimeTypes module RT = LibExecution.RuntimeTypes module NRE = LibExecution.NameResolutionError -type NameResolver = - { - builtinFns : Set - builtinConstants : Set - - userTypes : Set - userFns : Set - userConstants : Set - - /// If a name is not found, should we raise an exception? - /// - /// - when the local package DB is fully empty, and we're filling it in for the - /// first time, we want to allow all names to be NotFound -- other package - /// items won't be there yet - /// - sometimes when parsing, we're not sure whether something is: - /// - a variable - /// - or something else, like a constant or fn. - /// During these times, we want to allow errors as well, so we can - /// parse it as a variable as a fallback if nothing is found under that name. - allowError : bool - - // Since packages often use things that are defined in the same package, and - // those package items won't be in the package manager yet when we try to - // resolve them, we need another approach here. - hackLocallyDefinedPackageTypes : Set - hackLocallyDefinedPackageFns : Set - hackLocallyDefinedPackageConstants : Set - - packageManager : RT.PackageManager - } - - -let empty : NameResolver = - { builtinFns = Set.empty - builtinConstants = Set.empty - - userTypes = Set.empty - userFns = Set.empty - userConstants = Set.empty - - // CLEANUP this should probably default to `false` - allowError = true - - hackLocallyDefinedPackageTypes = Set.empty - hackLocallyDefinedPackageFns = Set.empty - hackLocallyDefinedPackageConstants = Set.empty - - packageManager = RT.PackageManager.Empty } - - -let create - (builtinFns : List) - (builtinConstants : List) - (userTypes : List) - (userFns : List) - (userConstants : List) - (allowError : bool) - (packageManager : RT.PackageManager) - : NameResolver = - { builtinFns = Set.ofList builtinFns - builtinConstants = Set.ofList builtinConstants - - userTypes = Set.ofList userTypes - userFns = Set.ofList userFns - userConstants = Set.ofList userConstants - allowError = allowError - - hackLocallyDefinedPackageTypes = Set.empty - hackLocallyDefinedPackageFns = Set.empty - hackLocallyDefinedPackageConstants = Set.empty +type HackPackageStuff = + { types : Set + constants : Set + fns : Set } + + static member empty = { types = Set.empty; constants = Set.empty; fns = Set.empty } + + +type UserStuff = + { types : Set + constants : Set + fns : Set } + + static member empty = { types = Set.empty; constants = Set.empty; fns = Set.empty } + static member fromProgram(program : RT.Program) : UserStuff = + let map fn items = items |> Map.keys |> List.map fn |> Set + { types = program.types |> map PT2RT.FQTypeName.UserProgram.fromRT + constants = program.constants |> map PT2RT.FQConstantName.UserProgram.fromRT + fns = program.fns |> map PT2RT.FQFnName.UserProgram.fromRT } + + +/// If a name is not found, should we raise an exception? +/// +/// - when the local package DB is fully empty, and we're filling it in for the +/// first time, we want to allow all names to be NotFound -- other package +/// items won't be there yet +/// - sometimes when parsing, we're not sure whether something is: +/// - a variable +/// - or something else, like a constant or fn. +/// During these times, we _also_ want to allow errors as well, so we can +/// parse it as a variable as a fallback if nothing is found under that name. +[] +type OnMissing = + | ThrowError + | Allow + +// TODO: we should probably just return the Result, and let the caller +// handle the error if they want to... +let throwIfRelevant + (onMissing : OnMissing) + (currentModule : List) + (given : NEList) + (result : PT.NameResolution<'a>) + : PT.NameResolution<'a> = + result + |> Result.mapError (fun err -> + match onMissing with + | OnMissing.ThrowError -> + Exception.raiseInternal + "Unresolved name when not allowed" + [ "error", err; "given", given; "currentModule", currentModule ] + | OnMissing.Allow -> err) + + +type GenericName = { modules : List; name : string; version : int } + +/// If we're 'given' the name `Option.Option` +/// and we're parsing in `Darklang.Stdlib`, +/// +/// We should look for the thing in the following places: +/// - Darklang.Stdlib.Option.Option +/// - Darklang.Option.Option +/// - Option.Option +/// , in that order (most specific first). +let namesToTry + (currentModule : List) + (given : GenericName) + : List = + let rec loop (modulesToPrepend : List) : List = + match List.splitLast modulesToPrepend with + | None -> [ given ] - packageManager = packageManager } + | Some(allButLast, _last) -> + let newNameToTry = { given with modules = modulesToPrepend @ given.modules } + newNameToTry :: loop allButLast + // handle explicit PACKAGE.etc and Stdlib.etc shortcut + let addl = + match given.modules with + | "Stdlib" :: _ -> [ { given with modules = "Darklang" :: given.modules } ] + | "PACKAGE" :: owner :: modules -> [ { given with modules = owner :: modules } ] + | _ -> [] -let merge - (a : NameResolver) - (b : NameResolver) - (packageManager : RT.PackageManager) - : NameResolver = - { builtinFns = Set.union a.builtinFns b.builtinFns - builtinConstants = Set.union a.builtinConstants b.builtinConstants - - userTypes = Set.union a.userTypes b.userTypes - userFns = Set.union a.userFns b.userFns - userConstants = Set.union a.userConstants b.userConstants - - allowError = a.allowError && b.allowError - - hackLocallyDefinedPackageTypes = - Set.union a.hackLocallyDefinedPackageTypes b.hackLocallyDefinedPackageTypes - hackLocallyDefinedPackageFns = - Set.union a.hackLocallyDefinedPackageFns b.hackLocallyDefinedPackageFns - hackLocallyDefinedPackageConstants = - Set.union - a.hackLocallyDefinedPackageConstants - b.hackLocallyDefinedPackageConstants - - packageManager = packageManager } - - -let fromBuiltins (builtins : RT.Builtins) : NameResolver = - { builtinFns = - builtins.fns - |> Map.keys - |> List.map PT2RT.FQFnName.Builtin.fromRT - |> Set.ofList - - builtinConstants = - builtins.constants - |> Map.keys - |> List.map PT2RT.FQConstantName.Builtin.fromRT - |> Set.ofList - - userTypes = Set.empty - userFns = Set.empty - userConstants = Set.empty - - allowError = true - - hackLocallyDefinedPackageTypes = Set.empty - hackLocallyDefinedPackageFns = Set.empty - hackLocallyDefinedPackageConstants = Set.empty - - packageManager = RT.PackageManager.Empty } - - -let fromExecutionState (state : RT.ExecutionState) : NameResolver = - { builtinFns = - state.builtins.fns - |> Map.keys - |> List.map PT2RT.FQFnName.Builtin.fromRT - |> Set.ofList - builtinConstants = - state.builtins.constants - |> Map.keys - |> List.map PT2RT.FQConstantName.Builtin.fromRT - |> Set.ofList - - userTypes = - state.program.types - |> Map.keys - |> List.map PT2RT.FQTypeName.UserProgram.fromRT - |> Set.ofList - userFns = - state.program.fns - |> Map.keys - |> List.map PT2RT.FQFnName.UserProgram.fromRT - |> Set.ofList - userConstants = - state.program.constants - |> Map.keys - |> List.map PT2RT.FQConstantName.UserProgram.fromRT - |> Set.ofList - - allowError = true - - hackLocallyDefinedPackageFns = Set.empty - hackLocallyDefinedPackageTypes = Set.empty - hackLocallyDefinedPackageConstants = Set.empty - - packageManager = state.packageManager } - - -// TODO: there's a lot going on here to resolve the outer portion of the name and to -// avoid repeat work for package/modules, but it's also adding a lot of code and -// complexity. Perhaps this changes when packages become identified by ID + (loop currentModule) @ addl let resolveTypeName - (nameErrorType : NRE.NameType) - (parser : string -> Result) + (packageManager : RT.PackageManager) + (hackPackageTypes : Set) (userTypes : Set) - (packageTypeExists : RT.FQTypeName.Package -> Ply) - (packageNameMapper : PT.FQTypeName.Package -> RT.FQTypeName.Package) - (allowError : bool) + (onMissing : OnMissing) (currentModule : List) (name : WT.Name) : Ply> = - uply { - match name with - | WT.KnownBuiltin(_name, _version) -> - // todo this is not supposed to happen as we don't allow builtin types - return - Error({ nameType = nameErrorType; errorType = NRE.NotFound; names = [] }) - | WT.Unresolved given -> - let resolve - (names : NEList) - : Ply> = - uply { - let (modules, name) = NEList.splitLast names - match parser name with - | Error _msg -> - return - Error( - { nameType = nameErrorType - errorType = NRE.InvalidPackageName - names = NEList.toList names } - ) - | Ok(name, version) -> - match modules with - | "Stdlib" :: otherModules -> - let name = - PT.FQTypeName.package - "Darklang" - ("Stdlib" :: otherModules) - name - version - - let! packageTypeExists = packageTypeExists (packageNameMapper name) - - if packageTypeExists then - return Ok(PT.FQTypeName.FQTypeName.Package name) - else - return - Error( - { nameType = nameErrorType - errorType = NRE.NotFound - names = NEList.toList names } - ) - - | "PACKAGE" :: owner :: modules -> - let name = PT.FQTypeName.package owner modules name version - - let! packageTypeExists = packageTypeExists (packageNameMapper name) - - if packageTypeExists then - return Ok(PT.FQTypeName.FQTypeName.Package name) - else - return - Error( - { nameType = nameErrorType - errorType = NRE.NotFound - names = NEList.toList names } - ) - - - | _ -> - // 2. Name exactly matches something in the UserProgram space - let (userProgram : PT.FQTypeName.UserProgram) = - { modules = modules; name = name; version = version } - - if Set.contains userProgram userTypes then - return Ok(PT.FQTypeName.UserProgram userProgram) - else - return - Error( - { nameType = nameErrorType - errorType = NRE.NotFound - names = NEList.toList names } - ) - } - - // 4. Check name in - // - a. exact name - // - b. current module - // - c. parent module(s) - // - d. darklang.stdlib package space // NOT IMPLEMENTED - - // Look in the current module and all parent modules - // for X.Y, and current module A.B.C, try in the following order - // A.B.C.X.Y - // A.B.X.Y - // A.X.Y - // X.Y - - // List of locations to try and find the name - // i.e. PACKAGE.[owner], PACKAGE.[owner].[module1] - let namesToTry : List> = - let rec loop (modules : List) : List> = - match modules with - | [] -> [ given ] - | _ -> - let rest = List.initial modules - (NEList.prependList modules given) :: loop rest - loop currentModule - - let! (result : PT.NameResolution) = - Ply.List.foldSequentially - (fun currentResult (pathToTry : NEList) -> - match currentResult with - | Ok _ -> Ply currentResult - | Error _ -> - uply { - let! newResult = resolve pathToTry - match newResult with - | Ok _ -> return newResult - | Error _ -> return currentResult // keep the first error message - }) - (Error - { nameType = nameErrorType - errorType = NRE.NotFound - names = NEList.toList given }) - namesToTry - - match result with - | Ok result -> return Ok result - | Error err -> - if not allowError then - return - Exception.raiseInternal - "Unresolved name when not allowed" - [ "namesToTry", namesToTry - "error", err - "given", given - "currentModule", currentModule ] + + let err errType names : PT.NameResolution = + Error { nameType = NRE.Type; errorType = errType; names = names } + + match name with + // TODO remodel things appropriately so this is not needed + | WT.KnownBuiltin(_name, _version) -> + Exception.raiseInternal "Builtin types don't exist" [] + | WT.Unresolved given -> + let notFoundError = err NRE.NotFound (NEList.toList given) + + let tryPackageName + (name : PT.FQTypeName.Package) + : Ply> = + let rtName = PT2RT.FQTypeName.Package.toRT name + uply { + match! packageManager.getType rtName with + | Some _found -> return Ok(PT.FQTypeName.FQTypeName.Package name) + | None -> + if Set.contains rtName hackPackageTypes then + return Ok(PT.FQTypeName.FQTypeName.Package name) + else + return notFoundError + } + + let tryResolve + (name : GenericName) + : Ply> = + // try UserProgram space first, then try package space + uply { + let (userProgram : PT.FQTypeName.UserProgram) = + { modules = name.modules; name = name.name; version = name.version } + + if Set.contains userProgram userTypes then + return Ok(PT.FQTypeName.UserProgram userProgram) else - return Error err - } + match name.modules with + | [] -> return Error() + | owner :: modules -> + let name = PT.FQTypeName.package owner modules name.name name.version + let! packageName = tryPackageName name + return packageName |> Result.mapError (fun _ -> ()) + } + + uply { + let (modules, name) = NEList.splitLast given + + // parses `TypeName_v2` into `(TypeName, 2)`, or just `TypeName` into `(TypeName, 0)`. + // TODO: ensure we're validating fully and reasonably (e.g. include module) + match FS2WT.Expr.parseTypeName name with + | Error _ -> return err NRE.InvalidPackageName (NEList.toList given) + | Ok(name, version) -> + let genericName = { modules = modules; name = name; version = version } + + let! (result : PT.NameResolution) = + Ply.List.foldSequentially + (fun currentResult nameToTry -> + match currentResult with + | Ok _ -> Ply currentResult + | Error _ -> + uply { + match! tryResolve nameToTry with + | Error() -> return currentResult + | Ok success -> return Ok success + }) + notFoundError + (namesToTry currentModule genericName) + + return throwIfRelevant onMissing currentModule given result + } let resolveConstantName - (nameErrorType : NRE.NameType) - (parser : string -> Result) - (builtinConstants : Set) + (builtinConstants : Set) + (packageManager : RT.PackageManager) + (hackPackageConstants : Set) (userConstants : Set) - (packageConstantExists : RT.FQConstantName.Package -> Ply) - (packageNameMapper : PT.FQConstantName.Package -> RT.FQConstantName.Package) - (allowError : bool) + (onMissing : OnMissing) (currentModule : List) (name : WT.Name) : Ply> = - - uply { - // These are named exactly during parsing - match name with - | WT.KnownBuiltin(name, version) -> - return Ok(PT.FQConstantName.fqBuiltIn name version) - - | WT.Unresolved given -> - let resolve - (names : NEList) - : Ply> = - uply { - let (modules, name) = NEList.splitLast names - match parser name with - | Error _msg -> - return - Error( - { nameType = nameErrorType - errorType = NRE.InvalidPackageName - names = NEList.toList names } - ) - | Ok(name, version) -> - match modules with - - // TODO: reuse some code between this and the next match case - | "Stdlib" :: otherModules -> - let name = - PT.FQConstantName.package - "Darklang" - ("Stdlib" :: otherModules) - name - version - - let! packageConstantExists = - packageConstantExists (packageNameMapper name) - - if packageConstantExists then - return Ok(PT.FQConstantName.FQConstantName.Package name) - else - return - Error( - { nameType = nameErrorType - errorType = NRE.NotFound - names = NEList.toList names } - ) - - | "PACKAGE" :: owner :: modules -> - let name = PT.FQConstantName.package owner modules name version - - let! packageConstantExists = - packageConstantExists (packageNameMapper name) - - if packageConstantExists then - return Ok(PT.FQConstantName.FQConstantName.Package name) - else - return - Error( - { nameType = nameErrorType - errorType = NRE.NotFound - names = NEList.toList names } - ) - - | [ "Builtin" ] -> - let (builtIn : PT.FQConstantName.Builtin) = - { name = name; version = version } - - if Set.contains builtIn builtinConstants then - return Ok(PT.FQConstantName.Builtin builtIn) - else - return - Error( - { nameType = nameErrorType - errorType = NRE.NotFound - names = NEList.toList names } - ) - - | _ -> - // 2. Name exactly matches something in the UserProgram space - let (userProgram : PT.FQConstantName.UserProgram) = - { modules = modules; name = name; version = version } - - if Set.contains userProgram userConstants then - return Ok(PT.FQConstantName.UserProgram userProgram) - else - return - Error( - { nameType = nameErrorType - errorType = NRE.NotFound - names = NEList.toList names } - ) - } - - // 4. Check name in - // - a. exact name - // - b. current module - // - c. parent module(s) - // - d. darklang.stdlib package space // NOT IMPLEMENTED - - // Look in the current module and all parent modules - // for X.Y, and current module A.B.C, try in the following order - // A.B.C.X.Y - // A.B.X.Y - // A.X.Y - // X.Y - - // List of locations to try and find the name - // i.e. PACKAGE.[owner], PACKAGE.[owner].[module1] - let namesToTry : List> = - let rec loop (modules : List) : List> = - match modules with - | [] -> [ given ] - | _ -> - let rest = List.initial modules - (NEList.prependList modules given) :: loop rest - loop currentModule - - let! (result : PT.NameResolution) = - Ply.List.foldSequentially - (fun currentResult (pathToTry : NEList) -> - match currentResult with - | Ok _ -> Ply currentResult - | Error _ -> - uply { - let! newResult = resolve pathToTry - match newResult with - | Ok _ -> return newResult - | Error _ -> return currentResult // keep the first error message - }) - (Error - { nameType = nameErrorType - errorType = NRE.NotFound - names = NEList.toList given }) - namesToTry - - match result with - | Ok result -> return Ok result - | Error err -> - if not allowError then - return - Exception.raiseInternal - "Unresolved name when not allowed" - [ "namesToTry", namesToTry - "error", err - "given", given - "currentModule", currentModule ] + let err errType names : PT.NameResolution = + Error { nameType = NRE.Constant; errorType = errType; names = names } + + match name with + | WT.KnownBuiltin(name, version) -> + Ok(PT.FQConstantName.fqBuiltIn name version) |> Ply + | WT.Unresolved given -> + let notFoundError = err NRE.NotFound (NEList.toList given) + + let tryPackageName + (name : PT.FQConstantName.Package) + : Ply> = + let rtName = PT2RT.FQConstantName.Package.toRT name + uply { + match! packageManager.getConstant rtName with + | Some _found -> return Ok(PT.FQConstantName.FQConstantName.Package name) + | None -> + if Set.contains rtName hackPackageConstants then + return Ok(PT.FQConstantName.FQConstantName.Package name) + else + return notFoundError + } + + let tryResolve + (name : GenericName) + : Ply> = + uply { + let (userProgram : PT.FQConstantName.UserProgram) = + { modules = name.modules; name = name.name; version = name.version } + + if name.modules = [ "Builtin" ] then + let (builtInRT : RT.FQConstantName.Builtin) = + { name = name.name; version = name.version } + + if Set.contains builtInRT builtinConstants then + let (builtInPT : PT.FQConstantName.Builtin) = + { name = name.name; version = name.version } + return Ok(PT.FQConstantName.Builtin builtInPT) + else + return Error() + elif Set.contains userProgram userConstants then + return Ok(PT.FQConstantName.UserProgram userProgram) else - return Error err - } + match name.modules with + | [] -> return Error() + | owner :: modules -> + let name = PT.FQConstantName.package owner modules name.name name.version + let! packageName = tryPackageName name + return packageName |> Result.mapError (fun _ -> ()) + } + + uply { + let (modules, name) = NEList.splitLast given + + match FS2WT.Expr.parseFnName name with + | Error _ -> return err NRE.InvalidPackageName (NEList.toList given) + | Ok(name, version) -> + + let genericName = { modules = modules; name = name; version = version } + + let! (result : PT.NameResolution) = + Ply.List.foldSequentially + (fun currentResult nameToTry -> + match currentResult with + | Ok _ -> Ply currentResult + | Error _ -> + uply { + match! tryResolve nameToTry with + | Error() -> return currentResult + | Ok success -> return Ok success + }) + notFoundError + (namesToTry currentModule genericName) + + return throwIfRelevant onMissing currentModule given result + } + let resolveFnName - (nameErrorType : NRE.NameType) - (parser : string -> Result) - (builtinFns : Set) + (builtinFns : Set) + (packageManager : RT.PackageManager) + (hackPackageFns : Set) (userFns : Set) - (packageFnExists : RT.FQFnName.Package -> Ply) - (packageNameMapper : PT.FQFnName.Package -> RT.FQFnName.Package) - (allowError : bool) + (onMissing : OnMissing) (currentModule : List) (name : WT.Name) : Ply> = - - uply { - // These are named exactly during parsing - match name with - | WT.KnownBuiltin(name, version) -> return Ok(PT.FQFnName.fqBuiltIn name version) - - | WT.Unresolved given -> - let resolve - (names : NEList) - : Ply> = - uply { - let (modules, name) = NEList.splitLast names - match parser name with - | Error _msg -> - return - Error( - { nameType = nameErrorType - errorType = NRE.InvalidPackageName - names = NEList.toList names } - ) - | Ok(name, version) -> - match modules with - | "Stdlib" :: otherModules -> - let name = - PT.FQFnName.package - "Darklang" - ("Stdlib" :: otherModules) - name - version - - let! packageFnExists = packageFnExists (packageNameMapper name) - - if packageFnExists then - return Ok(PT.FQFnName.FQFnName.Package name) - else - return - Error( - { nameType = nameErrorType - errorType = NRE.NotFound - names = NEList.toList names } - ) - | "PACKAGE" :: owner :: modules -> - let name = PT.FQFnName.package owner modules name version - - let! packageFnExists = packageFnExists (packageNameMapper name) - - if packageFnExists then - return Ok(PT.FQFnName.FQFnName.Package name) - else - return - Error( - { nameType = nameErrorType - errorType = NRE.NotFound - names = NEList.toList names } - ) - | [ "Builtin" ] -> - let (builtIn : PT.FQFnName.Builtin) = - { name = name; version = version } - - if Set.contains builtIn builtinFns then - return Ok(PT.FQFnName.Builtin builtIn) - else - return - Error( - { nameType = nameErrorType - errorType = NRE.NotFound - names = NEList.toList names } - ) - | _ -> - // 2. Name exactly matches something in the UserProgram space - let (userProgram : PT.FQFnName.UserProgram) = - { modules = modules; name = name; version = version } - - if Set.contains userProgram userFns then - return Ok(PT.FQFnName.UserProgram userProgram) - else - return - Error( - { nameType = nameErrorType - errorType = NRE.NotFound - names = NEList.toList names } - ) - } - - // 4. Check name in - // - a. exact name - // - b. current module - // - c. parent module(s) - // - d. darklang.stdlib package space // NOT IMPLEMENTED - - // Look in the current module and all parent modules - // for X.Y, and current module A.B.C, try in the following order - // A.B.C.X.Y - // A.B.X.Y - // A.X.Y - // X.Y - - // List of locations to try and find the name - // i.e. PACKAGE.[owner], PACKAGE.[owner].[module1] - let namesToTry : List> = - let rec loop (modules : List) : List> = - match modules with - | [] -> [ given ] - | _ -> - let rest = List.initial modules - (NEList.prependList modules given) :: loop rest - loop currentModule - - let! (result : PT.NameResolution) = - Ply.List.foldSequentially - (fun currentResult (pathToTry : NEList) -> - match currentResult with - | Ok _ -> Ply currentResult - | Error _ -> - uply { - let! newResult = resolve pathToTry - match newResult with - | Ok _ -> return newResult - | Error _ -> return currentResult // keep the first error message - }) - (Error - { nameType = nameErrorType - errorType = NRE.NotFound - names = NEList.toList given }) - namesToTry - - match result with - | Ok result -> return Ok result - | Error err -> - if not allowError then - return - Exception.raiseInternal - "Unresolved name when not allowed" - [ "namesToTry", namesToTry - "error", err - "given", given - "currentModule", currentModule ] + let err errType names : PT.NameResolution = + Error { nameType = NRE.Function; errorType = errType; names = names } + + match name with + | WT.KnownBuiltin(name, version) -> Ok(PT.FQFnName.fqBuiltIn name version) |> Ply + | WT.Unresolved given -> + let notFoundError = err NRE.NotFound (NEList.toList given) + + let tryPackageName + (name : PT.FQFnName.Package) + : Ply> = + let rtName = PT2RT.FQFnName.Package.toRT name + uply { + match! packageManager.getFn rtName with + | Some _found -> return Ok(PT.FQFnName.FQFnName.Package name) + | None -> + if Set.contains rtName hackPackageFns then + return Ok(PT.FQFnName.FQFnName.Package name) + else + return notFoundError + } + + let tryResolve (name : GenericName) : Ply> = + uply { + let (userProgram : PT.FQFnName.UserProgram) = + { modules = name.modules; name = name.name; version = name.version } + + if name.modules = [ "Builtin" ] then + let (builtInRT : RT.FQFnName.Builtin) = + { name = name.name; version = name.version } + + if Set.contains builtInRT builtinFns then + let (builtInPT : PT.FQFnName.Builtin) = + { name = name.name; version = name.version } + return Ok(PT.FQFnName.Builtin builtInPT) + else + return Error() + + elif Set.contains userProgram userFns then + return Ok(PT.FQFnName.UserProgram userProgram) else - return Error err - } + match name.modules with + | [] -> return Error() + | owner :: modules -> + let name = PT.FQFnName.package owner modules name.name name.version + let! packageName = tryPackageName name + return packageName |> Result.mapError (fun _ -> ()) + } - - - -module TypeName = - let packageTypeExists - (pm : RT.PackageManager) - (hackLocallyDefinedPackageTypes : Set) - (typeName : RT.FQTypeName.Package) - : Ply = uply { - match! pm.getType typeName with - | None -> return Set.contains typeName hackLocallyDefinedPackageTypes - | Some _ -> return true + let (modules, name) = NEList.splitLast given + + match FS2WT.Expr.parseFnName name with + | Error _ -> return err NRE.InvalidPackageName (NEList.toList given) + | Ok(name, version) -> + let genericName = { modules = modules; name = name; version = version } + + let! (result : PT.NameResolution) = + Ply.List.foldSequentially + (fun currentResult nameToTry -> + match currentResult with + | Ok _ -> Ply currentResult + | Error _ -> + uply { + match! tryResolve nameToTry with + | Error() -> return currentResult + | Ok success -> return Ok success + }) + notFoundError + (namesToTry currentModule genericName) + + return throwIfRelevant onMissing currentModule given result } - - let maybeResolve - (resolver : NameResolver) - (currentModule : List) - (name : WT.Name) - : Ply> = - resolveTypeName - NRE.Type - // TODO: move parsing fn into PT or WT - FS2WT.Expr.parseTypeName - resolver.userTypes - (packageTypeExists - resolver.packageManager - resolver.hackLocallyDefinedPackageTypes) - PT2RT.FQTypeName.Package.toRT - true - currentModule - name - - let resolve - (resolver : NameResolver) - (currentModule : List) - (name : WT.Name) - : Ply> = - resolveTypeName - NRE.Type - // TODO: move parsing fn into PT or WT - FS2WT.Expr.parseTypeName - resolver.userTypes - (packageTypeExists - resolver.packageManager - resolver.hackLocallyDefinedPackageTypes) - PT2RT.FQTypeName.Package.toRT - resolver.allowError - currentModule - name - - -module ConstantName = - let packageConstExists - (pm : RT.PackageManager) - (hackLocallyDefinedPackageConstants : Set) - (constName : RT.FQConstantName.Package) - : Ply = - uply { - match! pm.getConstant constName with - | None -> return Set.contains constName hackLocallyDefinedPackageConstants - | Some _ -> return true - } - - - let maybeResolve - (resolver : NameResolver) - (currentModule : List) - (name : WT.Name) - : Ply> = - resolveConstantName - NRE.Constant - FS2WT.Expr.parseFn // same format - resolver.builtinConstants - resolver.userConstants - (packageConstExists - resolver.packageManager - resolver.hackLocallyDefinedPackageConstants) - PT2RT.FQConstantName.Package.toRT - true - currentModule - name - - let resolve - (resolver : NameResolver) - (currentModule : List) - (name : WT.Name) - : Ply> = - resolveConstantName - NRE.Constant - FS2WT.Expr.parseFn // same format - resolver.builtinConstants - resolver.userConstants - (packageConstExists - resolver.packageManager - resolver.hackLocallyDefinedPackageConstants) - PT2RT.FQConstantName.Package.toRT - resolver.allowError - currentModule - name - - -module FnName = - let packageFnExists - (pm : RT.PackageManager) - (hackLocallyDefinedPackageFns : Set) - (fnName : RT.FQFnName.Package) - : Ply = - uply { - match! pm.getFn fnName with - | None -> return Set.contains fnName hackLocallyDefinedPackageFns - | Some _ -> return true - } - - let maybeResolve - (resolver : NameResolver) - (currentModule : List) - (name : WT.Name) - : Ply> = - resolveFnName - NRE.Function - // TODO: move parsing fn into PT or WT - FS2WT.Expr.parseFn - resolver.builtinFns - resolver.userFns - (packageFnExists resolver.packageManager resolver.hackLocallyDefinedPackageFns) - PT2RT.FQFnName.Package.toRT - true - currentModule - name - - let resolve - (resolver : NameResolver) - (currentModule : List) - (name : WT.Name) - : Ply> = - resolveFnName - NRE.Function - // TODO: move parsing fn into PT or WT - FS2WT.Expr.parseFn - resolver.builtinFns - resolver.userFns - (packageFnExists resolver.packageManager resolver.hackLocallyDefinedPackageFns) - PT2RT.FQFnName.Package.toRT - resolver.allowError - currentModule - name diff --git a/backend/src/LibParser/Package.fs b/backend/src/LibParser/Package.fs index 03fb8ed97c..afca309c6c 100644 --- a/backend/src/LibParser/Package.fs +++ b/backend/src/LibParser/Package.fs @@ -7,7 +7,10 @@ open Prelude module FS2WT = FSharpToWrittenTypes module WT = WrittenTypes module WT2PT = WrittenTypesToProgramTypes +module PT2RT = LibExecution.ProgramTypesToRuntimeTypes module PT = LibExecution.ProgramTypes +module RT = LibExecution.RuntimeTypes +module NR = NameResolver open Utils @@ -21,7 +24,6 @@ type PTPackageModule = { fns : List types : List constants : List } - let emptyPTModule = { fns = []; types = []; constants = [] } @@ -94,8 +96,13 @@ let rec parseDecls emptyWTModule decls + let parse - (resolver : NameResolver.NameResolver) + (builtins : RT.Builtins) + (pm : RT.PackageManager) + (hackPackageStuff : NR.HackPackageStuff) + (userStuff : NR.UserStuff) + (onMissing : NR.OnMissing) (filename : string) (contents : string) : Ply = @@ -116,55 +123,69 @@ let parse let typeNameToModules (p : PT.FQTypeName.Package) : List = - "PACKAGE" :: p.owner :: p.modules + p.owner :: p.modules let fnNameToModules (p : PT.FQFnName.Package) : List = - "PACKAGE" :: p.owner :: p.modules + p.owner :: p.modules let constantNameToModules (p : PT.FQConstantName.Package) : List = - "PACKAGE" :: p.owner :: p.modules + p.owner :: p.modules + + // TODO: I'm not sure if we actually need this here? + // we're doing two pases, right, so probably not? + // and if this is the only place we're setting that, then maybe the thing can be removed? idk. + let updatedHackPackageStuff : NR.HackPackageStuff = + let newTypes = + modul.types + |> List.map _.name + |> List.map PT2RT.FQTypeName.Package.toRT + |> Set + let newConstants = + modul.constants + |> List.map _.name + |> List.map PT2RT.FQConstantName.Package.toRT + |> Set + let newFns = + modul.fns |> List.map _.name |> List.map PT2RT.FQFnName.Package.toRT |> Set + + { types = Set.union hackPackageStuff.types newTypes + constants = Set.union hackPackageStuff.constants newConstants + fns = Set.union hackPackageStuff.fns newFns } - let fns = - modul.fns - |> List.map _.name - |> List.map LibExecution.ProgramTypesToRuntimeTypes.FQFnName.Package.toRT - |> Set - let types = - modul.types - |> List.map _.name - |> List.map LibExecution.ProgramTypesToRuntimeTypes.FQTypeName.Package.toRT - |> Set - let constants = - modul.constants - |> List.map _.name - |> List.map - LibExecution.ProgramTypesToRuntimeTypes.FQConstantName.Package.toRT - |> Set - - let resolver = - { resolver with - hackLocallyDefinedPackageFns = fns - hackLocallyDefinedPackageTypes = types - hackLocallyDefinedPackageConstants = constants } let! fns = modul.fns |> Ply.List.mapSequentially (fun fn -> - WT2PT.PackageFn.toPT resolver (fnNameToModules fn.name) fn) + WT2PT.PackageFn.toPT + builtins + pm + updatedHackPackageStuff + userStuff + onMissing + (fnNameToModules fn.name) + fn) let! types = modul.types |> Ply.List.mapSequentially (fun typ -> - WT2PT.PackageType.toPT resolver (typeNameToModules typ.name) typ) + WT2PT.PackageType.toPT + pm + hackPackageStuff + userStuff + onMissing + (typeNameToModules typ.name) + typ) let! constants = modul.constants |> Ply.List.mapSequentially (fun constant -> WT2PT.PackageConstant.toPT - resolver + pm + hackPackageStuff + userStuff + onMissing (constantNameToModules constant.name) constant) - return { fns = fns; types = types; constants = constants } // in the parsed package, types are being read as user, as opposed to the package that's right there diff --git a/backend/src/LibParser/Parser.fs b/backend/src/LibParser/Parser.fs index 004aad9db0..495f6c9b36 100644 --- a/backend/src/LibParser/Parser.fs +++ b/backend/src/LibParser/Parser.fs @@ -7,44 +7,71 @@ module FS2WT = FSharpToWrittenTypes module WT = WrittenTypes module WT2PT = WrittenTypesToProgramTypes module PT = LibExecution.ProgramTypes +module RT = LibExecution.RuntimeTypes +module NR = NameResolver -// Parse the program, returning a WrittenTypes expression which doesn't have any names resolved. Call `WT2PT.toPT resolver` +/// Parse the program, returning a WrittenTypes expression which doesn't have any names +/// resolved. Call `WT2PT.toPT resolver` let initialParse (filename : string) (code : string) : WT.Expr = code |> Utils.parseAsFSharpSourceFile filename |> Utils.singleExprFromImplFile |> FS2WT.Expr.fromSynExpr + /// Returns an incomplete parse of a PT expression let parsePTExpr - (resolver : NameResolver.NameResolver) + (builtins : RT.Builtins) + (pm : RT.PackageManager) + (hackPackageStuff : NR.HackPackageStuff) + (userStuff : NR.UserStuff) + (onMissing : NR.OnMissing) (filename : string) (code : string) : Ply = - code |> initialParse filename |> WT2PT.Expr.toPT resolver [] + code + |> initialParse filename + |> WT2PT.Expr.toPT builtins pm hackPackageStuff userStuff onMissing [] -let parseSimple (filename : string) (code : string) : Ply = - parsePTExpr NameResolver.empty filename code + +let parseSimple + (builtins : RT.Builtins) + (pm : RT.PackageManager) + (hackPackageStuff : NR.HackPackageStuff) + (userStuff : NR.UserStuff) + (onMissing : NR.OnMissing) + (filename : string) + (code : string) + : Ply = + parsePTExpr builtins pm hackPackageStuff userStuff onMissing filename code let parseRTExpr - (resolver : NameResolver.NameResolver) + (builtins : RT.Builtins) + (pm : RT.PackageManager) + (hackPackageStuff : NR.HackPackageStuff) + (userStuff : NR.UserStuff) + (onMissing : NR.OnMissing) (filename : string) (code : string) : Ply = code - |> parsePTExpr resolver filename + |> parsePTExpr builtins pm hackPackageStuff userStuff onMissing filename |> Ply.map LibExecution.ProgramTypesToRuntimeTypes.Expr.toRT - let parsePackageFile - (resolver : NameResolver.NameResolver) + (builtins : RT.Builtins) + (pm : RT.PackageManager) + (hackPackageStuff : NR.HackPackageStuff) + (userStuff : NR.UserStuff) + (onMissing : NR.OnMissing) (path : string) (contents : string) : Ply = uply { - let! pModule = Package.parse resolver path contents + let! pModule = + Package.parse builtins pm hackPackageStuff userStuff onMissing path contents return { types = pModule.types; constants = pModule.constants; fns = pModule.fns } } diff --git a/backend/src/LibParser/TestModule.fs b/backend/src/LibParser/TestModule.fs index e731c3739e..625be2c50d 100644 --- a/backend/src/LibParser/TestModule.fs +++ b/backend/src/LibParser/TestModule.fs @@ -10,8 +10,10 @@ module WT2PT = WrittenTypesToProgramTypes module PT = LibExecution.ProgramTypes module PT2RT = LibExecution.ProgramTypesToRuntimeTypes module RT = LibExecution.RuntimeTypes +module NR = NameResolver open Utils + type WTTest = { name : string; lineNumber : int; actual : WT.Expr; expected : WT.Expr } @@ -188,22 +190,63 @@ let parseFile (parsedAsFSharp : ParsedImplFileInput) : List = parseModule [] [] decls -let toPT (resolver : NameResolver.NameResolver) (m : WTModule) : Ply = +let toPT + (builtins : RT.Builtins) + (pm : RT.PackageManager) + (hackPackageStuff : NR.HackPackageStuff) + (userStuff : NR.UserStuff) + (onMissing : NR.OnMissing) + (m : WTModule) + : Ply = uply { let! fns = - m.fns |> Ply.List.mapSequentially (WT2PT.UserFunction.toPT resolver m.name) + m.fns + |> Ply.List.mapSequentially ( + WT2PT.UserFunction.toPT + builtins + pm + hackPackageStuff + userStuff + onMissing + m.name + ) let! types = - m.types |> Ply.List.mapSequentially (WT2PT.UserType.toPT resolver m.name) + m.types + |> Ply.List.mapSequentially ( + WT2PT.UserType.toPT pm hackPackageStuff userStuff onMissing m.name + ) let! constants = m.constants - |> Ply.List.mapSequentially (WT2PT.UserConstant.toPT resolver m.name) - let! dbs = m.dbs |> Ply.List.mapSequentially (WT2PT.DB.toPT resolver m.name) + |> Ply.List.mapSequentially ( + WT2PT.UserConstant.toPT pm hackPackageStuff userStuff onMissing m.name + ) + let! dbs = + m.dbs + |> Ply.List.mapSequentially ( + WT2PT.DB.toPT pm hackPackageStuff userStuff onMissing m.name + ) let! (tests : List) = m.tests |> Ply.List.mapSequentially (fun test -> uply { - let! actual = WT2PT.Expr.toPT resolver m.name test.actual - let! expected = WT2PT.Expr.toPT resolver m.name test.expected + let! actual = + WT2PT.Expr.toPT + builtins + pm + hackPackageStuff + userStuff + onMissing + m.name + test.actual + let! expected = + WT2PT.Expr.toPT + builtins + pm + hackPackageStuff + userStuff + onMissing + m.name + test.expected return { PTTest.actual = actual expected = expected @@ -226,7 +269,11 @@ let toPT (resolver : NameResolver.NameResolver) (m : WTModule) : Ply = /// Returns a flattened list of modules in the file. let parseTestFile - (baseResolver : NameResolver.NameResolver) + (builtins : RT.Builtins) + (pm : RT.PackageManager) + (hackPackageStuff : NR.HackPackageStuff) + (userStuff : NR.UserStuff) + (onMissing : NR.OnMissing) (filename : string) : Ply> = uply { @@ -236,30 +283,33 @@ let parseTestFile |> parseAsFSharpSourceFile filename |> parseFile - let fns = modules |> List.map _.fns |> List.concat - let fnNames = fns |> List.map _.name |> Set.ofList - - let types = modules |> List.map _.types |> List.concat - let typeNames = types |> List.map _.name |> Set.ofList + let fns = + modules |> List.map _.fns |> List.concat |> List.map _.name |> Set.ofList + let types = + modules |> List.map _.types |> List.concat |> List.map _.name |> Set.ofList + let constants = + modules |> List.map _.constants |> List.concat |> List.map _.name |> Set.ofList - let constants = modules |> List.map _.constants |> List.concat - let constantNames = constants |> List.map _.name |> Set.ofList + let updatedUserStuff : NR.UserStuff = + { types = Set.union userStuff.types types + constants = Set.union userStuff.constants constants + fns = Set.union userStuff.fns fns } - let programResolver = - { NameResolver.empty with - userFns = fnNames - userTypes = typeNames - userConstants = constantNames } - let resolver = - NameResolver.merge baseResolver programResolver baseResolver.packageManager - - let! result = modules |> Ply.List.mapSequentially (toPT resolver) + let! result = + modules + |> Ply.List.mapSequentially ( + toPT builtins pm hackPackageStuff updatedUserStuff onMissing + ) return result } let parseSingleTestFromFile - (resolver : NameResolver.NameResolver) + (builtins : RT.Builtins) + (pm : RT.PackageManager) + (hackPackageStuff : NR.HackPackageStuff) + (userStuff : NR.UserStuff) + (onMissing : NR.OnMissing) (filename : string) (testSource : string) : Ply = @@ -270,10 +320,10 @@ let parseSingleTestFromFile |> singleExprFromImplFile |> parseTest - let! actual = - wtTest.actual |> WT2PT.Expr.toPT resolver [] |> Ply.map PT2RT.Expr.toRT - let! expected = - wtTest.expected |> WT2PT.Expr.toPT resolver [] |> Ply.map PT2RT.Expr.toRT + let mapExpr = WT2PT.Expr.toPT builtins pm hackPackageStuff userStuff onMissing [] + + let! actual = wtTest.actual |> mapExpr |> Ply.map PT2RT.Expr.toRT + let! expected = wtTest.expected |> mapExpr |> Ply.map PT2RT.Expr.toRT return { actual = actual expected = expected diff --git a/backend/src/LibParser/WrittenTypes.fs b/backend/src/LibParser/WrittenTypes.fs index 18bb5574fd..52caa774b4 100644 --- a/backend/src/LibParser/WrittenTypes.fs +++ b/backend/src/LibParser/WrittenTypes.fs @@ -11,7 +11,7 @@ open Prelude module PT = LibExecution.ProgramTypes type Name = - // Used when a syntactic construct turns into a function (eg some operators) + // Used when a syntactic construct turns into a function (e.g. some operators) | KnownBuiltin of string * int // Basically all names are unresolved at this point, and will be resolved during // WrittenTypesToProgramTypes diff --git a/backend/src/LibParser/WrittenTypesToProgramTypes.fs b/backend/src/LibParser/WrittenTypesToProgramTypes.fs index 9c8641e623..b61693090b 100644 --- a/backend/src/LibParser/WrittenTypesToProgramTypes.fs +++ b/backend/src/LibParser/WrittenTypesToProgramTypes.fs @@ -5,9 +5,10 @@ open Prelude module WT = WrittenTypes module PT = LibExecution.ProgramTypes +module RT = LibExecution.RuntimeTypes module FS2WT = FSharpToWrittenTypes module NRE = LibExecution.NameResolutionError -type NameResolver = NameResolver.NameResolver +module NR = NameResolver module InfixFnName = let toPT (name : WT.InfixFnName) : PT.InfixFnName = @@ -28,11 +29,14 @@ module InfixFnName = module TypeReference = let rec toPT - (resolver : NameResolver) + (pm : RT.PackageManager) + (hackPackageStuff : NR.HackPackageStuff) + (userStuff : NR.UserStuff) + (onMissing : NR.OnMissing) (currentModule : List) (t : WT.TypeReference) : Ply = - let toPT = toPT resolver currentModule + let toPT = toPT pm hackPackageStuff userStuff onMissing currentModule uply { match t with | WT.TUnit -> return PT.TUnit @@ -64,7 +68,14 @@ module TypeReference = | WT.TDict typ -> return! toPT typ |> Ply.map PT.TDict | WT.TCustomType(t, typeArgs) -> - let! t = NameResolver.TypeName.resolve resolver currentModule t + let! t = + NR.resolveTypeName + pm + hackPackageStuff.types + userStuff.types + onMissing + currentModule + t let! typeArgs = Ply.List.mapSequentially toPT typeArgs return PT.TCustomType(t, typeArgs) @@ -127,7 +138,10 @@ module MatchPattern = module Expr = let resolveTypeName - (resolver : NameResolver) + (pm : RT.PackageManager) + (hackPackageStuff : NR.HackPackageStuff) + (userStuff : NR.UserStuff) + (onMissing : NR.OnMissing) (currentModule : List) (names : List) (caseName : string) // used for errors @@ -143,14 +157,24 @@ module Expr = ) | head :: tail -> let name = NEList.ofList head tail |> WT.Unresolved - NameResolver.TypeName.resolve resolver currentModule name + NR.resolveTypeName + pm + hackPackageStuff.types + userStuff.types + onMissing + currentModule + name let rec toPT - (resolver : NameResolver) + (builtins : RT.Builtins) + (pm : RT.PackageManager) + (hackPackageStuff : NR.HackPackageStuff) + (userStuff : NR.UserStuff) + (onMissing : NR.OnMissing) (currentModule : List) (e : WT.Expr) : Ply = - let toPT = toPT resolver currentModule + let toPT = toPT builtins pm hackPackageStuff userStuff onMissing currentModule uply { match e with | WT.EChar(id, char) -> return PT.EChar(id, char) @@ -167,7 +191,13 @@ module Expr = | WT.EString(id, segments) -> let! segments = Ply.List.mapSequentially - (stringSegmentToPT resolver currentModule) + (stringSegmentToPT + builtins + pm + hackPackageStuff + userStuff + onMissing + currentModule) segments return PT.EString(id, segments) | WT.EFloat(id, sign, whole, fraction) -> @@ -177,8 +207,12 @@ module Expr = | WT.EVariable(id, var) -> // This could be a UserConstant let! constant = - NameResolver.ConstantName.maybeResolve - resolver + NR.resolveConstantName + (builtins.constants |> Map.keys |> Set) + pm + hackPackageStuff.constants + userStuff.constants + NR.OnMissing.Allow currentModule (WT.Unresolved(NEList.singleton var)) match constant with @@ -189,23 +223,47 @@ module Expr = return PT.EFieldAccess(id, obj, fieldname) | WT.EApply(id, (WT.EFnName(_, name)), [], { head = WT.EPlaceHolder }) -> // There are no arguments, so this could be a function name or a constant - let! fnName = NameResolver.FnName.maybeResolve resolver currentModule name + let! fnName = + NR.resolveFnName + (builtins.fns |> Map.keys |> Set) + pm + hackPackageStuff.fns + userStuff.fns + NR.OnMissing.Allow + currentModule + name match fnName with | Ok _ as name -> return PT.EFnName(id, name) | Error _ -> - let! name = NameResolver.ConstantName.resolve resolver currentModule name + let! name = + NR.resolveConstantName + (builtins.constants |> Map.keys |> Set) + pm + hackPackageStuff.constants + userStuff.constants + onMissing + currentModule + name return PT.EConstant(id, name) | WT.EApply(id, name, typeArgs, args) -> let! name = toPT name let! typeArgs = Ply.List.mapSequentially - (TypeReference.toPT resolver currentModule) + (TypeReference.toPT pm hackPackageStuff userStuff onMissing currentModule) typeArgs let! args = Ply.NEList.mapSequentially toPT args return PT.EApply(id, name, typeArgs, args) | WT.EFnName(id, name) -> - let! fnName = NameResolver.FnName.maybeResolve resolver currentModule name + let! fnName = + NR.resolveFnName + (builtins.fns |> Map.keys |> Set) + pm + hackPackageStuff.fns + userStuff.fns + NR.OnMissing.Allow + currentModule + name match fnName, name with | Error _, WT.Unresolved { head = varName; tail = [] } when not (String.isCapitalized varName) @@ -242,7 +300,14 @@ module Expr = let! theRest = Ply.List.mapSequentially toPT theRest return PT.ETuple(id, first, second, theRest) | WT.ERecord(id, typeName, fields) -> - let! typeName = NameResolver.TypeName.resolve resolver currentModule typeName + let! typeName = + NR.resolveTypeName + pm + hackPackageStuff.types + userStuff.types + onMissing + currentModule + typeName let! fields = Ply.List.mapSequentially (fun (fieldName, fieldExpr) -> @@ -265,10 +330,26 @@ module Expr = | WT.EPipe(pipeID, expr1, rest) -> let! expr1 = toPT expr1 let! rest = - Ply.List.mapSequentially (pipeExprToPT resolver currentModule) rest + Ply.List.mapSequentially + (pipeExprToPT + builtins + pm + hackPackageStuff + userStuff + onMissing + currentModule) + rest return PT.EPipe(pipeID, expr1, rest) | WT.EEnum(id, typeName, caseName, exprs) -> - let! typeName = resolveTypeName resolver currentModule typeName caseName + let! typeName = + resolveTypeName + pm + hackPackageStuff + userStuff + onMissing + currentModule + typeName + caseName let! exprs = Ply.List.mapSequentially toPT exprs return PT.EEnum(id, typeName, caseName, exprs) | WT.EMatch(id, mexpr, cases) -> @@ -313,29 +394,44 @@ module Expr = } and stringSegmentToPT - (resolver : NameResolver) + (builtins : RT.Builtins) + (pm : RT.PackageManager) + (hackPackageStuff : NR.HackPackageStuff) + (userStuff : NR.UserStuff) + (onMissing : NR.OnMissing) (currentModule : List) (segment : WT.StringSegment) : Ply = match segment with | WT.StringText text -> Ply(PT.StringText text) | WT.StringInterpolation expr -> - toPT resolver currentModule expr + toPT builtins pm hackPackageStuff userStuff onMissing currentModule expr |> Ply.map (fun interpolated -> PT.StringInterpolation interpolated) and pipeExprToPT - (resolver : NameResolver) + (builtins : RT.Builtins) + (pm : RT.PackageManager) + (hackPackageStuff : NR.HackPackageStuff) + (userStuff : NR.UserStuff) + (onMissing : NR.OnMissing) (currentModule : List) (pipeExpr : WT.PipeExpr) : Ply = - let toPT = toPT resolver currentModule + let toPT = toPT builtins pm hackPackageStuff userStuff onMissing currentModule uply { match pipeExpr with | WT.EPipeVariableOrUserFunction(id, name) -> let! resolved = let asUserFnName = WT.Name.Unresolved(NEList.singleton name) - NameResolver.FnName.maybeResolve resolver currentModule asUserFnName + NR.resolveFnName + (builtins.fns |> Map.keys |> Set) + pm + hackPackageStuff.fns + userStuff.fns + NR.OnMissing.Allow + currentModule + asUserFnName return match resolved with @@ -356,34 +452,61 @@ module Expr = args) -> // Special case for variables with arguments. Since it could be a userfn, we // need to check that first. We do a similar thing converting EFnNames. - let! fnName = NameResolver.FnName.maybeResolve resolver currentModule name + let! fnName = + NR.resolveFnName + (builtins.fns |> Map.keys |> Set) + pm + hackPackageStuff.fns + userStuff.fns + NR.OnMissing.Allow + currentModule + name let! args = Ply.List.mapSequentially toPT args match fnName with | Ok name -> return PT.EPipeFnCall(id, Ok name, [], args) | Error _ -> return PT.EPipeVariable(id, varName, args) | WT.EPipeFnCall(id, name, typeArgs, args) -> - let! fnName = NameResolver.FnName.resolve resolver currentModule name + let! fnName = + NR.resolveFnName + (builtins.fns |> Map.keys |> Set) + pm + hackPackageStuff.fns + userStuff.fns + onMissing + currentModule + name let! typeArgs = Ply.List.mapSequentially - (TypeReference.toPT resolver currentModule) + (TypeReference.toPT pm hackPackageStuff userStuff onMissing currentModule) typeArgs let! args = Ply.List.mapSequentially toPT args return PT.EPipeFnCall(id, fnName, typeArgs, args) | WT.EPipeEnum(id, typeName, caseName, fields) -> - let! typeName = resolveTypeName resolver currentModule typeName caseName + let! typeName = + resolveTypeName + pm + hackPackageStuff + userStuff + onMissing + currentModule + typeName + caseName let! fields = Ply.List.mapSequentially toPT fields return PT.EPipeEnum(id, typeName, caseName, fields) } module Const = let rec toPT - (resolver : NameResolver) + (pm : RT.PackageManager) + (hackPackageStuff : NR.HackPackageStuff) + (userStuff : NR.UserStuff) + (onMissing : NR.OnMissing) (currentModule : List) (c : WT.Const) : Ply = - let toPT = toPT resolver currentModule + let toPT = toPT pm hackPackageStuff userStuff onMissing currentModule uply { match c with | WT.CUnit -> return PT.CUnit @@ -424,7 +547,15 @@ module Const = return PT.CTuple(first, second, theRest) | WT.CEnum(typeName, caseName, fields) -> - let! typeName = Expr.resolveTypeName resolver currentModule typeName caseName + let! typeName = + Expr.resolveTypeName + pm + hackPackageStuff + userStuff + onMissing + currentModule + typeName + caseName let! fields = Ply.List.mapSequentially toPT fields return PT.CEnum(typeName, caseName, fields) } @@ -432,179 +563,280 @@ module Const = module TypeDeclaration = module RecordField = - let toPT - (resolver : NameResolver) + (pm : RT.PackageManager) + (hackPackageStuff : NR.HackPackageStuff) + (userStuff : NR.UserStuff) + (onMissing : NR.OnMissing) (currentModule : List) (f : WT.TypeDeclaration.RecordField) : Ply = uply { - let! typ = TypeReference.toPT resolver currentModule f.typ + let! typ = + TypeReference.toPT + pm + hackPackageStuff + userStuff + onMissing + currentModule + f.typ return { name = f.name; typ = typ; description = f.description } } module EnumField = let toPT - (resolver : NameResolver) + (pm : RT.PackageManager) + (hackPackageStuff : NR.HackPackageStuff) + (userStuff : NR.UserStuff) + (onMissing : NR.OnMissing) (currentModule : List) (f : WT.TypeDeclaration.EnumField) : Ply = uply { - let! typ = TypeReference.toPT resolver currentModule f.typ + let! typ = + TypeReference.toPT + pm + hackPackageStuff + userStuff + onMissing + currentModule + f.typ return { typ = typ; label = f.label; description = f.description } } module EnumCase = let toPT - (resolver : NameResolver) + (pm : RT.PackageManager) + (hackPackageStuff : NR.HackPackageStuff) + (userStuff : NR.UserStuff) + (onMissing : NR.OnMissing) (currentModule : List) (c : WT.TypeDeclaration.EnumCase) : Ply = uply { let! fields = - Ply.List.mapSequentially (EnumField.toPT resolver currentModule) c.fields + Ply.List.mapSequentially + (EnumField.toPT pm hackPackageStuff userStuff onMissing currentModule) + c.fields return { name = c.name; fields = fields; description = c.description } } module Definition = let toPT - (resolver : NameResolver) + (pm : RT.PackageManager) + (hackPackageStuff : NR.HackPackageStuff) + (userStuff : NR.UserStuff) + (onMissing : NR.OnMissing) (currentModule : List) (d : WT.TypeDeclaration.Definition) : Ply = uply { match d with | WT.TypeDeclaration.Alias typ -> - let! typ = TypeReference.toPT resolver currentModule typ + let! typ = + TypeReference.toPT + pm + hackPackageStuff + userStuff + onMissing + currentModule + typ return PT.TypeDeclaration.Alias typ | WT.TypeDeclaration.Record fields -> let! fields = Ply.NEList.mapSequentially - (RecordField.toPT resolver currentModule) + (RecordField.toPT pm hackPackageStuff userStuff onMissing currentModule) fields return PT.TypeDeclaration.Record fields | WT.TypeDeclaration.Enum cases -> let! cases = - Ply.NEList.mapSequentially (EnumCase.toPT resolver currentModule) cases + Ply.NEList.mapSequentially + (EnumCase.toPT pm hackPackageStuff userStuff onMissing currentModule) + cases return PT.TypeDeclaration.Enum cases } let toPT - (resolver : NameResolver) + (pm : RT.PackageManager) + (hackPackageStuff : NR.HackPackageStuff) + (userStuff : NR.UserStuff) + (onMissing : NR.OnMissing) (currentModule : List) (d : WT.TypeDeclaration.T) : Ply = uply { - let! def = Definition.toPT resolver currentModule d.definition + let! def = + Definition.toPT + pm + hackPackageStuff + userStuff + onMissing + currentModule + d.definition return { typeParams = d.typeParams; definition = def } } -module Handler = - module CronInterval = - let toPT (ci : WT.Handler.CronInterval) : PT.Handler.CronInterval = - match ci with - | WT.Handler.EveryDay -> PT.Handler.EveryDay - | WT.Handler.EveryWeek -> PT.Handler.EveryWeek - | WT.Handler.EveryFortnight -> PT.Handler.EveryFortnight - | WT.Handler.EveryHour -> PT.Handler.EveryHour - | WT.Handler.Every12Hours -> PT.Handler.Every12Hours - | WT.Handler.EveryMinute -> PT.Handler.EveryMinute - - module Spec = - let toPT (s : WT.Handler.Spec) : PT.Handler.Spec = - match s with - | WT.Handler.HTTP(route, method) -> PT.Handler.HTTP(route, method) - | WT.Handler.Worker name -> PT.Handler.Worker name - | WT.Handler.Cron(name, interval) -> - PT.Handler.Cron(name, CronInterval.toPT interval) - | WT.Handler.REPL name -> PT.Handler.REPL name - - let toPT - (nameResolver : NameResolver) - (currentModule : List) - (h : WT.Handler.T) - : Ply = - uply { - let! ast = Expr.toPT nameResolver currentModule h.ast - return { tlid = gid (); ast = ast; spec = Spec.toPT h.spec } - } -module DB = +module PackageType = let toPT - (nameResolver : NameResolver) + (pm : RT.PackageManager) + (hackPackageStuff : NR.HackPackageStuff) + (userStuff : NR.UserStuff) + (onMissing : NR.OnMissing) (currentModule : List) - (db : WT.DB.T) - : Ply = + (pt : WT.PackageType.T) + : Ply = uply { - let! typ = TypeReference.toPT nameResolver currentModule db.typ - return { tlid = gid (); name = db.name; version = db.version; typ = typ } + let! declaration = + TypeDeclaration.toPT + pm + hackPackageStuff + userStuff + onMissing + currentModule + pt.declaration + return + { name = pt.name + description = pt.description + declaration = declaration + deprecated = PT.NotDeprecated + id = System.Guid.NewGuid() + tlid = gid () } } -module UserType = +module PackageConstant = let toPT - (resolver : NameResolver) + (pm : RT.PackageManager) + (hackPackageStuff : NR.HackPackageStuff) + (userStuff : NR.UserStuff) + (onMissing : NR.OnMissing) (currentModule : List) - (t : WT.UserType.T) - : Ply = + (c : WT.PackageConstant.T) + : Ply = uply { - let! declaration = TypeDeclaration.toPT resolver currentModule t.declaration + let! body = + Const.toPT pm hackPackageStuff userStuff onMissing currentModule c.body return - { tlid = gid () - name = t.name - declaration = declaration - description = t.description - deprecated = PT.NotDeprecated } + { name = c.name + description = c.description + deprecated = PT.NotDeprecated + body = body + id = System.Guid.NewGuid() + tlid = gid () } } -module UserFunction = +module PackageFn = module Parameter = let toPT - (resolver : NameResolver) + (pm : RT.PackageManager) + (hackPackageStuff : NR.HackPackageStuff) + (userStuff : NR.UserStuff) + (onMissing : NR.OnMissing) (currentModule : List) - (p : WT.UserFunction.Parameter) - : Ply = + (p : WT.PackageFn.Parameter) + : Ply = uply { - let! typ = TypeReference.toPT resolver currentModule p.typ + let! typ = + TypeReference.toPT + pm + hackPackageStuff + userStuff + onMissing + currentModule + p.typ return { name = p.name; typ = typ; description = p.description } } let toPT - (resolver : NameResolver) + (builtins : RT.Builtins) + (pm : RT.PackageManager) + (hackPackageStuff : NR.HackPackageStuff) + (userStuff : NR.UserStuff) + (onMissing : NR.OnMissing) (currentModule : List) - (f : WT.UserFunction.T) - : Ply = + (fn : WT.PackageFn.T) + : Ply = uply { let! parameters = Ply.NEList.mapSequentially - (Parameter.toPT resolver currentModule) - f.parameters - let! returnType = TypeReference.toPT resolver currentModule f.returnType - let! body = Expr.toPT resolver currentModule f.body + (Parameter.toPT pm hackPackageStuff userStuff onMissing currentModule) + fn.parameters + let! returnType = + TypeReference.toPT + pm + hackPackageStuff + userStuff + onMissing + currentModule + fn.returnType + let! body = + Expr.toPT + builtins + pm + hackPackageStuff + userStuff + onMissing + currentModule + fn.body return - { tlid = gid () - name = f.name - typeParams = f.typeParams + { name = fn.name parameters = parameters returnType = returnType - description = f.description + description = fn.description deprecated = PT.NotDeprecated - body = body } + body = body + typeParams = fn.typeParams + id = System.Guid.NewGuid() + tlid = gid () } } + + +module UserType = + let toPT + (pm : RT.PackageManager) + (hackPackageStuff : NR.HackPackageStuff) + (userStuff : NR.UserStuff) + (onMissing : NR.OnMissing) + (currentModule : List) + (t : WT.UserType.T) + : Ply = + uply { + let! declaration = + TypeDeclaration.toPT + pm + hackPackageStuff + userStuff + onMissing + currentModule + t.declaration + return + { tlid = gid () + name = t.name + declaration = declaration + description = t.description + deprecated = PT.NotDeprecated } + } + + module UserConstant = let toPT - (resolver : NameResolver) + (pm : RT.PackageManager) + (hackPackageStuff : NR.HackPackageStuff) + (userStuff : NR.UserStuff) + (onMissing : NR.OnMissing) (currentModule : List) (c : WT.UserConstant.T) : Ply = uply { - let! body = Const.toPT resolver currentModule c.body + let! body = + Const.toPT pm hackPackageStuff userStuff onMissing currentModule c.body return { tlid = gid () name = c.name @@ -613,73 +845,132 @@ module UserConstant = body = body } } -module PackageFn = + +module DB = + let toPT + (pm : RT.PackageManager) + (hackPackageStuff : NR.HackPackageStuff) + (userStuff : NR.UserStuff) + (onMissing : NR.OnMissing) + (currentModule : List) + (db : WT.DB.T) + : Ply = + uply { + let! typ = + TypeReference.toPT + pm + hackPackageStuff + userStuff + onMissing + currentModule + db.typ + return { tlid = gid (); name = db.name; version = db.version; typ = typ } + } + +module UserFunction = module Parameter = let toPT - (resolver : NameResolver) + (pm : RT.PackageManager) + (hackPackageStuff : NR.HackPackageStuff) + (userStuff : NR.UserStuff) + (onMissing : NR.OnMissing) (currentModule : List) - (p : WT.PackageFn.Parameter) - : Ply = + (p : WT.UserFunction.Parameter) + : Ply = uply { - let! typ = TypeReference.toPT resolver currentModule p.typ + let! typ = + TypeReference.toPT + pm + hackPackageStuff + userStuff + onMissing + currentModule + p.typ return { name = p.name; typ = typ; description = p.description } } let toPT - (resolver : NameResolver) + (builtins : RT.Builtins) + (pm : RT.PackageManager) + (hackPackageStuff : NR.HackPackageStuff) + (userStuff : NR.UserStuff) + (onMissing : NR.OnMissing) (currentModule : List) - (fn : WT.PackageFn.T) - : Ply = + (f : WT.UserFunction.T) + : Ply = uply { let! parameters = Ply.NEList.mapSequentially - (Parameter.toPT resolver currentModule) - fn.parameters - let! returnType = TypeReference.toPT resolver currentModule fn.returnType - let! body = Expr.toPT resolver currentModule fn.body + (Parameter.toPT pm hackPackageStuff userStuff onMissing currentModule) + f.parameters + let! returnType = + TypeReference.toPT + pm + hackPackageStuff + userStuff + onMissing + currentModule + f.returnType + let! body = + Expr.toPT + builtins + pm + hackPackageStuff + userStuff + onMissing + currentModule + f.body return - { name = fn.name + { tlid = gid () + name = f.name + typeParams = f.typeParams parameters = parameters returnType = returnType - description = fn.description + description = f.description deprecated = PT.NotDeprecated - body = body - typeParams = fn.typeParams - id = System.Guid.NewGuid() - tlid = gid () } + body = body } } -module PackageType = - let toPT - (resolver : NameResolver) - (currentModule : List) - (pt : WT.PackageType.T) - : Ply = - uply { - let! declaration = TypeDeclaration.toPT resolver currentModule pt.declaration - return - { name = pt.name - description = pt.description - declaration = declaration - deprecated = PT.NotDeprecated - id = System.Guid.NewGuid() - tlid = gid () } - } -module PackageConstant = +module Handler = + module CronInterval = + let toPT (ci : WT.Handler.CronInterval) : PT.Handler.CronInterval = + match ci with + | WT.Handler.EveryDay -> PT.Handler.EveryDay + | WT.Handler.EveryWeek -> PT.Handler.EveryWeek + | WT.Handler.EveryFortnight -> PT.Handler.EveryFortnight + | WT.Handler.EveryHour -> PT.Handler.EveryHour + | WT.Handler.Every12Hours -> PT.Handler.Every12Hours + | WT.Handler.EveryMinute -> PT.Handler.EveryMinute + + module Spec = + let toPT (s : WT.Handler.Spec) : PT.Handler.Spec = + match s with + | WT.Handler.HTTP(route, method) -> PT.Handler.HTTP(route, method) + | WT.Handler.Worker name -> PT.Handler.Worker name + | WT.Handler.Cron(name, interval) -> + PT.Handler.Cron(name, CronInterval.toPT interval) + | WT.Handler.REPL name -> PT.Handler.REPL name + let toPT - (resolver : NameResolver) + (builtins : RT.Builtins) + (pm : RT.PackageManager) + (hackPackageStuff : NR.HackPackageStuff) + (userStuff : NR.UserStuff) + (onMissing : NR.OnMissing) (currentModule : List) - (c : WT.PackageConstant.T) - : Ply = + (h : WT.Handler.T) + : Ply = uply { - let! body = Const.toPT resolver currentModule c.body - return - { name = c.name - description = c.description - deprecated = PT.NotDeprecated - body = body - id = System.Guid.NewGuid() - tlid = gid () } + let! ast = + Expr.toPT + builtins + pm + hackPackageStuff + userStuff + onMissing + currentModule + h.ast + return { tlid = gid (); ast = ast; spec = Spec.toPT h.spec } } diff --git a/backend/src/LocalExec/Canvas.fs b/backend/src/LocalExec/Canvas.fs index a160b4981f..a8b15b419e 100644 --- a/backend/src/LocalExec/Canvas.fs +++ b/backend/src/LocalExec/Canvas.fs @@ -11,10 +11,11 @@ open Npgsql.FSharp open LibCloud.Db module PT = LibExecution.ProgramTypes +module RT = LibExecution.RuntimeTypes +module NR = LibParser.NameResolver open Utils - let parseYamlExn<'a> (filename : string) : 'a = let contents = System.IO.File.ReadAllText filename let deserialized = Legivel.Serialization.Deserialize<'a> contents @@ -50,7 +51,7 @@ let purgeDataFromInternalSqlTables (id : CanvasID) : Task = let loadFromDisk - (nameResolver : LibParser.NameResolver.NameResolver) + (pm : RT.PackageManager) (canvasName : string) : Ply> = uply { @@ -83,7 +84,11 @@ let loadFromDisk uply { let! canvas = LibParser.Canvas.parseFromFile - nameResolver + Builtins.accessibleByCanvas + pm + NR.HackPackageStuff.empty + NR.UserStuff.empty + NR.OnMissing.ThrowError $"{canvasDir}/{config.Main}.dark" let types = canvas.types |> List.map PT.Toplevel.TLType diff --git a/backend/src/LocalExec/LoadPackagesFromDisk.fs b/backend/src/LocalExec/LoadPackagesFromDisk.fs index 8b7e8c4809..7fd10ee4f6 100644 --- a/backend/src/LocalExec/LoadPackagesFromDisk.fs +++ b/backend/src/LocalExec/LoadPackagesFromDisk.fs @@ -9,6 +9,7 @@ open Prelude module RT = LibExecution.RuntimeTypes module PT = LibExecution.ProgramTypes module PT2DT = LibExecution.ProgramTypesToDarkTypes +module NR = LibParser.NameResolver open Utils @@ -24,30 +25,32 @@ let load (builtins : RT.Builtins) : Ply = // First pass, parse all the packages, allowing unresolved names // (other package items won't be available yet) - let nameResolver = - LibParser.NameResolver.fromBuiltins builtins - |> fun nr -> { nr with allowError = true } - - let! (packagesParsedWithUnresolvedNamesAllowed : PT.Packages) = + let! (packages : PT.Packages) = filesWithContents // TODO: parallelize |> Ply.List.mapSequentially (fun (path, contents) -> - //print $"Parsing {path}, allowing unresolved names" - LibParser.Parser.parsePackageFile nameResolver path contents) + LibParser.Parser.parsePackageFile + builtins + RT.PackageManager.Empty + NR.HackPackageStuff.empty + NR.UserStuff.empty + NR.OnMissing.Allow + path + contents) |> Ply.map PT.Packages.combine // Re-parse the packages, though this time we don't allow unresolved names // (any package references that may have been unresolved a second ago should now be OK) - let nameResolver = - { nameResolver with - allowError = false - packageManager = - inMemPackageManagerFromPackages packagesParsedWithUnresolvedNamesAllowed } - return! filesWithContents |> Ply.List.mapSequentially (fun (path, contents) -> - //print $"Parsing {path}, not allowing unresolved names" - LibParser.Parser.parsePackageFile nameResolver path contents) + LibParser.Parser.parsePackageFile + builtins + (inMemPackageManagerFromPackages packages) + NR.HackPackageStuff.empty + NR.UserStuff.empty + NR.OnMissing.ThrowError + path + contents) |> Ply.map PT.Packages.combine } diff --git a/backend/src/LocalExec/LocalExec.fs b/backend/src/LocalExec/LocalExec.fs index ca5206c8f2..781ddef136 100644 --- a/backend/src/LocalExec/LocalExec.fs +++ b/backend/src/LocalExec/LocalExec.fs @@ -43,12 +43,8 @@ module HandleCommand = let inMemPackageManager = inMemPackageManagerFromPackages packagesFromDisk // then, parse the canvas' `main.dark`, purge any previous data, and create the canvas - let nameResolver = - LibParser.NameResolver.fromBuiltins Builtins.accessibleByCanvas - |> fun nr -> - { nr with packageManager = inMemPackageManager; allowError = false } - - let! (canvasId, toplevels) = Canvas.loadFromDisk nameResolver "dark-packages" + let! (canvasId, toplevels) = + Canvas.loadFromDisk inMemPackageManager "dark-packages" print $"Loaded canvas {canvasId} with {List.length toplevels} toplevels" diff --git a/backend/src/Wasm/Wasm.fsproj b/backend/src/Wasm/Wasm.fsproj index 9906bd6071..34ef58a019 100644 --- a/backend/src/Wasm/Wasm.fsproj +++ b/backend/src/Wasm/Wasm.fsproj @@ -24,7 +24,6 @@ - diff --git a/backend/testfiles/execution/stdlib/parser.dark b/backend/testfiles/execution/stdlib/parser.dark index 472a908af5..d59335c7c5 100644 --- a/backend/testfiles/execution/stdlib/parser.dark +++ b/backend/testfiles/execution/stdlib/parser.dark @@ -208,296 +208,296 @@ module TextToTextRoundtripping = module TypeReference = // all built-ins ("type MyUnit = Unit" |> roundtripCliScript) = "type MyUnit =\n Unit" - ("type MyBool = Bool" |> roundtripCliScript) = "type MyBool =\n Bool" - ("type MyInt8 = Int8" |> roundtripCliScript) = "type MyInt8 =\n Int8" - ("type MyUInt8 = UInt8" |> roundtripCliScript) = "type MyUInt8 =\n UInt8" - ("type MyInt16 = Int16" |> roundtripCliScript) = "type MyInt16 =\n Int16" - ("type MyUInt16 = UInt16" |> roundtripCliScript) = "type MyUInt16 =\n UInt16" - ("type MyInt32 = Int32" |> roundtripCliScript) = "type MyInt32 =\n Int32" - ("type MyUInt32 = UInt32" |> roundtripCliScript) = "type MyUInt32 =\n UInt32" - ("type MyInt64 = Int64" |> roundtripCliScript) = "type MyInt64 =\n Int64" - ("type MyUInt64 = UInt64" |> roundtripCliScript) = "type MyUInt64 =\n UInt64" - ("type MyInt128 = Int128" |> roundtripCliScript) = "type MyInt128 =\n Int128" - ("type MyUInt128 = UInt128" |> roundtripCliScript) = "type MyUInt128 =\n UInt128" - ("type MyFloat = Float" |> roundtripCliScript) = "type MyFloat =\n Float" - ("type MyChar = Char" |> roundtripCliScript) = "type MyChar =\n Char" - ("type MyString = String" |> roundtripCliScript) = "type MyString =\n String" - - ("type MyList = List" |> roundtripCliScript) = "type MyList =\n List" - ("type MyList = List>" |> roundtripCliScript) = "type MyList =\n List>" - ("type MyList = List" |> roundtripCliScript) = "type MyList =\n List" - - ("type MyDict = Dict" |> roundtripCliScript) = "type MyDict =\n Dict" - ("type MyDict = Dict" |> roundtripCliScript) = "type MyDict =\n Dict" - - ("type MyTuple2 = (String * Int64)" |> roundtripCliScript) = "type MyTuple2 =\n (String * Int64)" - ("type MyTuple3 = (String * Int64 * Bool)" |> roundtripCliScript) = "type MyTuple3 =\n (String * Int64 * Bool)" - ("type MyTuple = (String * Int64 * Bool * Unit)" |> roundtripCliScript) = "type MyTuple =\n (String * Int64 * Bool * Unit)" - // single-part qualified name - ("type ID = Test" |> roundtripCliScript) = "type ID =\n Test" - - // fully-qualified package name (multi-part) - ("type MyOption = PACKAGE.Darklang.Stdlib.Option.Option" |> roundtripCliScript) = "type MyOption =\n PACKAGE.Darklang.Stdlib.Option.Option_v0" - ("type MyOption = Stdlib.Option.Option" |> roundtripCliScript) = "type MyOption =\n PACKAGE.Darklang.Stdlib.Option.Option_v0" - - - module TypeDeclaration = - ("type SimpleAlias = Unit" |> roundtripCliScript) = "type SimpleAlias =\n Unit" - - // record type - ("type Person = {name: String}" |> roundtripCliScript) = "type Person =\n { name: String }" - - ("type Person = {name: String; age: Int64}" |> roundtripCliScript) = "type Person =\n { name: String\n age: Int64 }" - ("type Person = {name: String; age: Int64; hasPet: Bool}" |> roundtripCliScript) = "type Person =\n { name: String\n age: Int64\n hasPet: Bool }" - - ("type Person = {name: String; age: Int64; hasPet: Bool; pet: Pet}" - |> roundtripCliScript) = """type Person = - { name: String - age: Int64 - hasPet: Bool - pet: Pet }""" - - module Expr = - // units - ("()" |> roundtripCliScript) = "()" - - // bools - ("true" |> roundtripCliScript) = "true" - ("false" |> roundtripCliScript) = "false" - - // parens (disappear) - ("(true)" |> roundtripCliScript) = "true" - - // int literals - ("1y" |> roundtripCliScript) = "1y" - ("-1y" |> roundtripCliScript) = "-1y" - ("1uy" |> roundtripCliScript) = "1uy" - ("1s" |> roundtripCliScript) = "1s" - ("1us" |> roundtripCliScript) = "1us" - ("1l" |> roundtripCliScript) = "1l" - ("-1l" |> roundtripCliScript) = "-1l" - ("1ul" |> roundtripCliScript) = "1ul" - ("0L" |> roundtripCliScript) = "0L" - ("1900L" |> roundtripCliScript) = "1900L" - ("-1900L" |> roundtripCliScript) = "-1900L" - ("1UL" |> roundtripCliScript) = "1UL" - ("1Q" |> roundtripCliScript) = "1Q" - ("-1Q" |> roundtripCliScript) = "-1Q" - ("1Q" |> roundtripCliScript) = "1Q" - - // float literals - ("-1.0" |> roundtripCliScript) = "-1.0" - ("-1.5" |> roundtripCliScript) = "-1.5" - ("1.5" |> roundtripCliScript) = "1.5" - ("0.0" |> roundtripCliScript) = "0.0" - ("0.775" |> roundtripCliScript) = "0.775" - - // string literals - ("\"\"" |> roundtripCliScript) = "\"\"" - ("\"hello\"" |> roundtripCliScript) = "\"hello\"" - ("\"hello\\tworld\"" |> roundtripCliScript) = "\"hello\\tworld\"" - - // char literals - ("'a'" |> roundtripCliScript) = "'a'" - ("'\\n'" |> roundtripCliScript) = "'\\n'" - ("'\t'" |> roundtripCliScript) = "'\t'" - - // list literal - ("[]" |> roundtripCliScript) = "[]" - ("[\"hello\"]" |> roundtripCliScript) = "[\"hello\"]" - ("[1L; 2L]" |> roundtripCliScript) = "[1L; 2L]" - ("[1L; 2L; 3L;]" |> roundtripCliScript) = "[1L; 2L; 3L]" - ("[true; false; true; false]" |> roundtripCliScript) = "[true; false; true; false]" - ("[[1L; 2L]; [3L; 4L]]" |> roundtripCliScript) = "[[1L; 2L]; [3L; 4L]]" - - // dict literal - ("Dict { }" |> roundtripCliScript) = "Dict { }" - ("Dict { a = 1L }" |> roundtripCliScript) = "Dict { a = 1L }" - ("Dict { a = \"hello\"; b = \"test\" }" |> roundtripCliScript) = "Dict { a = \"hello\"; b = \"test\" }" - ("Dict { a = 1L; b = 2L; c = 3L }" |> roundtripCliScript) = "Dict { a = 1L; b = 2L; c = 3L }" - - // tuple literals - ("(1L, \"hello\")" |> roundtripCliScript) = "(1L, \"hello\")" - ("(1L, \"hello\", 2L)" |> roundtripCliScript) = "(1L, \"hello\", 2L)" - ("(1L, \"hello\", 2L, true)" |> roundtripCliScript) = "(1L, \"hello\", 2L, true)" - ("(1L, 2L + 3L, 4L)" |> roundtripCliScript) = "(1L, (2L) + (3L), 4L)" - - // record literal - ("Person {name =\"John\"} " |> roundtripCliScript) = "Person { name = \"John\" }" - ("Person {name =\"John\"; age = 30L} " |> roundtripCliScript) = "Person { name = \"John\"; age = 30L }" - ("Person {name =\"John\"; age = 30L; hasPet = true} " |> roundtripCliScript) = "Person { name = \"John\"; age = 30L; hasPet = true }" - - ("Person {name =\"John\"; age = 30L; hasPet = true; pet = Pet {name = \"Luna\"}} " - |> roundtripCliScript) = "Person { name = \"John\"; age = 30L; hasPet = true; pet = Pet { name = \"Luna\" } }" - - // variables and let bindings - ("assumedlyAVariableName" |> roundtripCliScript) = "assumedlyAVariableName" - // TODO: this is ugly - ("let x = 1L\n x" |> roundtripCliScript) = "let x =\n 1L\nx" - - // if expressions - ("if true then 1L" |> roundtripCliScript) = "if true then\n 1L" - ("if true then 1L else 2L" |> roundtripCliScript) = "if true then\n 1L\nelse\n 2L" - ("if a < b then 1L else if c > d then 2L" |> roundtripCliScript) = "if (a) < (b) then\n 1L\nelse if (c) > (d) then\n 2L" - ("if a < b then 1L else if c > d then 2L else 3L" |> roundtripCliScript) = "if (a) < (b) then\n 1L\nelse if (c) > (d) then\n 2L\nelse\n 3L" - - ("if true then\n 1L" |> roundtripCliScript) = "if true then\n 1L" - ("if true then\n 1L\nelse\n 2L" |> roundtripCliScript) = "if true then\n 1L\nelse\n 2L" - ("if true then\n a\nelse if false then\n c" |> roundtripCliScript) = "if true then\n a\nelse if false then\n c" - - ("if a > b then\n a\nelse if c > d then\n c\nelse d" |> roundtripCliScript) = "if (a) > (b) then\n a\nelse if (c) > (d) then\n c\nelse\n d" - - ("if true then\n\ta\nelse\n\tb" |> roundtripCliScript) = "if true then\n a\nelse\n b" - - ("""if true then - a -else if false then - c -else if true then - d""" - |> roundtripCliScript) = """if true then - a -else if false then - c -else if true then - d""" - - - ("""if true then - a -else if false then - c -else if true then - d -else - e""" - |> roundtripCliScript) = """if true then - a -else if false then - c -else if true then - d -else - e""" - - // else for inner if - ("""if a > b then - if c > d then - c - else - b""" - |> roundtripCliScript) = """if (a) > (b) then - if (c) > (d) then - c - else - b""" - - // else for outer if - ("""if a > b then - if c > d then - c -else - b""" - |> roundtripCliScript) = """if (a) > (b) then - if (c) > (d) then - c -else - b""" - - // nested if - ("""if a > b then - a -else - if c > d then - c - else - if e > f then - e - else - if g > h then - g - else - h""" - |> roundtripCliScript) = """if (a) > (b) then - a -else if (c) > (d) then - c -else if (e) > (f) then - e -else if (g) > (h) then - g -else - h""" - - - // fn calls - // TODO: these are ugly - ("1L + 2L" |> roundtripCliScript) = "(1L) + (2L)" - ("1L + b + 3L" |> roundtripCliScript) = "((1L) + (b)) + (3L)" - ("1L + 2L * 3L - 4L" |> roundtripCliScript) = "((1L) + ((2L) * (3L))) - (4L)" - ("1L > 2L" |> roundtripCliScript) = "(1L) > (2L)" - ("1L >= 2L" |> roundtripCliScript) = "(1L) >= (2L)" - ("1L < 2L" |> roundtripCliScript) = "(1L) < (2L)" - ("1L <= 2L" |> roundtripCliScript) = "(1L) <= (2L)" - ("1L == 2L" |> roundtripCliScript) = "(1L) == (2L)" - ("1L != 2L" |> roundtripCliScript) = "(1L) != (2L)" - ("1L ^ 2L" |> roundtripCliScript) = "(1L) ^ (2L)" - ("true && false" |> roundtripCliScript) = "(true) && (false)" - ("true || false" |> roundtripCliScript) = "(true) || (false)" - ("(and true false)" |> roundtripCliScript) = "and true false" - ("(Bool.and true false)" |> roundtripCliScript) = "Bool.and true false" - ("(PACKAGE.Darklang.Stdlib.Bool.and true false)" |> roundtripCliScript) = "PACKAGE.Darklang.Stdlib.Bool.and_v0 true false" - ("(Stdlib.Bool.and true false)" |> roundtripCliScript) = "PACKAGE.Darklang.Stdlib.Bool.and_v0 true false" - ("(Builtin.int64Add 1L 2L)" |> roundtripCliScript) = "Builtin.int64Add 1L 2L" - - module FunctionDeclaration = - // single 'normal' param - ("let helloWorld (i: Int64): String = \"Hello world\"" |> roundtripCliScript) = "let helloWorld (i: Int64): String =\n \"Hello world\"" - - ("let double2 (i: PACKAGE.Darklang.LanguageTools.ID_v0) : Int64 = i + i" - |> roundtripCliScript) = "let double2 (i: PACKAGE.Darklang.LanguageTools.ID_v0): Int64 =\n (i) + (i)" - - // () param - ("let emptyString () : String = \"\"" |> roundtripCliScript) = "let emptyString (_: Unit): String =\n \"\"" - - - // multiple params - ("let isHigher (a: Int64) (b: Int64) : Bool = (Stdlib.Int64.greaterThan_v0 a b)" - |> roundtripCliScript) = "let isHigher (a: Int64) (b: Int64): Bool =\n PACKAGE.Darklang.Stdlib.Int64.greaterThan_v0 a b" - - - - module FnCalls = - //package function call - ("let sum (a : Int64) (b : Int64) : Int64 = (PACKAGE.Darklang.Stdlib.Int64.add a b)" - |> roundtripCliScript) = "let sum (a: Int64) (b: Int64): Int64 =\n PACKAGE.Darklang.Stdlib.Int64.add_v0 a b" - - - - module CliScript = - // TODO the output here is a bit broken - (""" -type BookID = Int64 - -let getTitle (bookId: BookID): String = - let book = (Library.getBook bookId) - (getNameFromBook book) - -let curiousGeorgeBookId = 101L -(Builtin.printLine (getTitle curiousGeorgeBookId)) - -0L -""" - |> roundtripCliScript) = """type BookID = - Int64 - -let getTitle (bookId: BookID): String = - let book = - Library.getBook bookId - getNameFromBook book - -let curiousGeorgeBookId = - 101L -Builtin.printLine getTitle curiousGeorgeBookId - -0L""" \ No newline at end of file +// ("type MyBool = Bool" |> roundtripCliScript) = "type MyBool =\n Bool" +// ("type MyInt8 = Int8" |> roundtripCliScript) = "type MyInt8 =\n Int8" +// ("type MyUInt8 = UInt8" |> roundtripCliScript) = "type MyUInt8 =\n UInt8" +// ("type MyInt16 = Int16" |> roundtripCliScript) = "type MyInt16 =\n Int16" +// ("type MyUInt16 = UInt16" |> roundtripCliScript) = "type MyUInt16 =\n UInt16" +// ("type MyInt32 = Int32" |> roundtripCliScript) = "type MyInt32 =\n Int32" +// ("type MyUInt32 = UInt32" |> roundtripCliScript) = "type MyUInt32 =\n UInt32" +// ("type MyInt64 = Int64" |> roundtripCliScript) = "type MyInt64 =\n Int64" +// ("type MyUInt64 = UInt64" |> roundtripCliScript) = "type MyUInt64 =\n UInt64" +// ("type MyInt128 = Int128" |> roundtripCliScript) = "type MyInt128 =\n Int128" +// ("type MyUInt128 = UInt128" |> roundtripCliScript) = "type MyUInt128 =\n UInt128" +// ("type MyFloat = Float" |> roundtripCliScript) = "type MyFloat =\n Float" +// ("type MyChar = Char" |> roundtripCliScript) = "type MyChar =\n Char" +// ("type MyString = String" |> roundtripCliScript) = "type MyString =\n String" + +// ("type MyList = List" |> roundtripCliScript) = "type MyList =\n List" +// ("type MyList = List>" |> roundtripCliScript) = "type MyList =\n List>" +// ("type MyList = List" |> roundtripCliScript) = "type MyList =\n List" + +// ("type MyDict = Dict" |> roundtripCliScript) = "type MyDict =\n Dict" +// ("type MyDict = Dict" |> roundtripCliScript) = "type MyDict =\n Dict" + +// ("type MyTuple2 = (String * Int64)" |> roundtripCliScript) = "type MyTuple2 =\n (String * Int64)" +// ("type MyTuple3 = (String * Int64 * Bool)" |> roundtripCliScript) = "type MyTuple3 =\n (String * Int64 * Bool)" +// ("type MyTuple = (String * Int64 * Bool * Unit)" |> roundtripCliScript) = "type MyTuple =\n (String * Int64 * Bool * Unit)" +// // single-part qualified name +// ("type ID = Test" |> roundtripCliScript) = "type ID =\n Test" + +// // fully-qualified package name (multi-part) +// ("type MyOption = PACKAGE.Darklang.Stdlib.Option.Option" |> roundtripCliScript) = "type MyOption =\n PACKAGE.Darklang.Stdlib.Option.Option_v0" +// ("type MyOption = Stdlib.Option.Option" |> roundtripCliScript) = "type MyOption =\n PACKAGE.Darklang.Stdlib.Option.Option_v0" + + +// module TypeDeclaration = +// ("type SimpleAlias = Unit" |> roundtripCliScript) = "type SimpleAlias =\n Unit" + +// // record type +// ("type Person = {name: String}" |> roundtripCliScript) = "type Person =\n { name: String }" + +// ("type Person = {name: String; age: Int64}" |> roundtripCliScript) = "type Person =\n { name: String\n age: Int64 }" +// ("type Person = {name: String; age: Int64; hasPet: Bool}" |> roundtripCliScript) = "type Person =\n { name: String\n age: Int64\n hasPet: Bool }" + +// ("type Person = {name: String; age: Int64; hasPet: Bool; pet: Pet}" +// |> roundtripCliScript) = """type Person = +// { name: String +// age: Int64 +// hasPet: Bool +// pet: Pet }""" + +// module Expr = +// // units +// ("()" |> roundtripCliScript) = "()" + +// // bools +// ("true" |> roundtripCliScript) = "true" +// ("false" |> roundtripCliScript) = "false" + +// // parens (disappear) +// ("(true)" |> roundtripCliScript) = "true" + +// // int literals +// ("1y" |> roundtripCliScript) = "1y" +// ("-1y" |> roundtripCliScript) = "-1y" +// ("1uy" |> roundtripCliScript) = "1uy" +// ("1s" |> roundtripCliScript) = "1s" +// ("1us" |> roundtripCliScript) = "1us" +// ("1l" |> roundtripCliScript) = "1l" +// ("-1l" |> roundtripCliScript) = "-1l" +// ("1ul" |> roundtripCliScript) = "1ul" +// ("0L" |> roundtripCliScript) = "0L" +// ("1900L" |> roundtripCliScript) = "1900L" +// ("-1900L" |> roundtripCliScript) = "-1900L" +// ("1UL" |> roundtripCliScript) = "1UL" +// ("1Q" |> roundtripCliScript) = "1Q" +// ("-1Q" |> roundtripCliScript) = "-1Q" +// ("1Q" |> roundtripCliScript) = "1Q" + +// // float literals +// ("-1.0" |> roundtripCliScript) = "-1.0" +// ("-1.5" |> roundtripCliScript) = "-1.5" +// ("1.5" |> roundtripCliScript) = "1.5" +// ("0.0" |> roundtripCliScript) = "0.0" +// ("0.775" |> roundtripCliScript) = "0.775" + +// // string literals +// ("\"\"" |> roundtripCliScript) = "\"\"" +// ("\"hello\"" |> roundtripCliScript) = "\"hello\"" +// ("\"hello\\tworld\"" |> roundtripCliScript) = "\"hello\\tworld\"" + +// // char literals +// ("'a'" |> roundtripCliScript) = "'a'" +// ("'\\n'" |> roundtripCliScript) = "'\\n'" +// ("'\t'" |> roundtripCliScript) = "'\t'" + +// // list literal +// ("[]" |> roundtripCliScript) = "[]" +// ("[\"hello\"]" |> roundtripCliScript) = "[\"hello\"]" +// ("[1L; 2L]" |> roundtripCliScript) = "[1L; 2L]" +// ("[1L; 2L; 3L;]" |> roundtripCliScript) = "[1L; 2L; 3L]" +// ("[true; false; true; false]" |> roundtripCliScript) = "[true; false; true; false]" +// ("[[1L; 2L]; [3L; 4L]]" |> roundtripCliScript) = "[[1L; 2L]; [3L; 4L]]" + +// // dict literal +// ("Dict { }" |> roundtripCliScript) = "Dict { }" +// ("Dict { a = 1L }" |> roundtripCliScript) = "Dict { a = 1L }" +// ("Dict { a = \"hello\"; b = \"test\" }" |> roundtripCliScript) = "Dict { a = \"hello\"; b = \"test\" }" +// ("Dict { a = 1L; b = 2L; c = 3L }" |> roundtripCliScript) = "Dict { a = 1L; b = 2L; c = 3L }" + +// // tuple literals +// ("(1L, \"hello\")" |> roundtripCliScript) = "(1L, \"hello\")" +// ("(1L, \"hello\", 2L)" |> roundtripCliScript) = "(1L, \"hello\", 2L)" +// ("(1L, \"hello\", 2L, true)" |> roundtripCliScript) = "(1L, \"hello\", 2L, true)" +// ("(1L, 2L + 3L, 4L)" |> roundtripCliScript) = "(1L, (2L) + (3L), 4L)" + +// // record literal +// ("Person {name =\"John\"} " |> roundtripCliScript) = "Person { name = \"John\" }" +// ("Person {name =\"John\"; age = 30L} " |> roundtripCliScript) = "Person { name = \"John\"; age = 30L }" +// ("Person {name =\"John\"; age = 30L; hasPet = true} " |> roundtripCliScript) = "Person { name = \"John\"; age = 30L; hasPet = true }" + +// ("Person {name =\"John\"; age = 30L; hasPet = true; pet = Pet {name = \"Luna\"}} " +// |> roundtripCliScript) = "Person { name = \"John\"; age = 30L; hasPet = true; pet = Pet { name = \"Luna\" } }" + +// // variables and let bindings +// ("assumedlyAVariableName" |> roundtripCliScript) = "assumedlyAVariableName" +// // TODO: this is ugly +// ("let x = 1L\n x" |> roundtripCliScript) = "let x =\n 1L\nx" + +// // if expressions +// ("if true then 1L" |> roundtripCliScript) = "if true then\n 1L" +// ("if true then 1L else 2L" |> roundtripCliScript) = "if true then\n 1L\nelse\n 2L" +// ("if a < b then 1L else if c > d then 2L" |> roundtripCliScript) = "if (a) < (b) then\n 1L\nelse if (c) > (d) then\n 2L" +// ("if a < b then 1L else if c > d then 2L else 3L" |> roundtripCliScript) = "if (a) < (b) then\n 1L\nelse if (c) > (d) then\n 2L\nelse\n 3L" + +// ("if true then\n 1L" |> roundtripCliScript) = "if true then\n 1L" +// ("if true then\n 1L\nelse\n 2L" |> roundtripCliScript) = "if true then\n 1L\nelse\n 2L" +// ("if true then\n a\nelse if false then\n c" |> roundtripCliScript) = "if true then\n a\nelse if false then\n c" + +// ("if a > b then\n a\nelse if c > d then\n c\nelse d" |> roundtripCliScript) = "if (a) > (b) then\n a\nelse if (c) > (d) then\n c\nelse\n d" + +// ("if true then\n\ta\nelse\n\tb" |> roundtripCliScript) = "if true then\n a\nelse\n b" + +// ("""if true then +// a +// else if false then +// c +// else if true then +// d""" +// |> roundtripCliScript) = """if true then +// a +// else if false then +// c +// else if true then +// d""" + + +// ("""if true then +// a +// else if false then +// c +// else if true then +// d +// else +// e""" +// |> roundtripCliScript) = """if true then +// a +// else if false then +// c +// else if true then +// d +// else +// e""" + +// // else for inner if +// ("""if a > b then +// if c > d then +// c +// else +// b""" +// |> roundtripCliScript) = """if (a) > (b) then +// if (c) > (d) then +// c +// else +// b""" + +// // else for outer if +// ("""if a > b then +// if c > d then +// c +// else +// b""" +// |> roundtripCliScript) = """if (a) > (b) then +// if (c) > (d) then +// c +// else +// b""" + +// // nested if +// ("""if a > b then +// a +// else +// if c > d then +// c +// else +// if e > f then +// e +// else +// if g > h then +// g +// else +// h""" +// |> roundtripCliScript) = """if (a) > (b) then +// a +// else if (c) > (d) then +// c +// else if (e) > (f) then +// e +// else if (g) > (h) then +// g +// else +// h""" + + +// // fn calls +// // TODO: these are ugly +// ("1L + 2L" |> roundtripCliScript) = "(1L) + (2L)" +// ("1L + b + 3L" |> roundtripCliScript) = "((1L) + (b)) + (3L)" +// ("1L + 2L * 3L - 4L" |> roundtripCliScript) = "((1L) + ((2L) * (3L))) - (4L)" +// ("1L > 2L" |> roundtripCliScript) = "(1L) > (2L)" +// ("1L >= 2L" |> roundtripCliScript) = "(1L) >= (2L)" +// ("1L < 2L" |> roundtripCliScript) = "(1L) < (2L)" +// ("1L <= 2L" |> roundtripCliScript) = "(1L) <= (2L)" +// ("1L == 2L" |> roundtripCliScript) = "(1L) == (2L)" +// ("1L != 2L" |> roundtripCliScript) = "(1L) != (2L)" +// ("1L ^ 2L" |> roundtripCliScript) = "(1L) ^ (2L)" +// ("true && false" |> roundtripCliScript) = "(true) && (false)" +// ("true || false" |> roundtripCliScript) = "(true) || (false)" +// ("(and true false)" |> roundtripCliScript) = "and true false" +// ("(Bool.and true false)" |> roundtripCliScript) = "Bool.and true false" +// ("(PACKAGE.Darklang.Stdlib.Bool.and true false)" |> roundtripCliScript) = "PACKAGE.Darklang.Stdlib.Bool.and_v0 true false" +// ("(Stdlib.Bool.and true false)" |> roundtripCliScript) = "PACKAGE.Darklang.Stdlib.Bool.and_v0 true false" +// ("(Builtin.int64Add 1L 2L)" |> roundtripCliScript) = "Builtin.int64Add 1L 2L" + +// module FunctionDeclaration = +// // single 'normal' param +// ("let helloWorld (i: Int64): String = \"Hello world\"" |> roundtripCliScript) = "let helloWorld (i: Int64): String =\n \"Hello world\"" + +// ("let double2 (i: PACKAGE.Darklang.LanguageTools.ID_v0) : Int64 = i + i" +// |> roundtripCliScript) = "let double2 (i: PACKAGE.Darklang.LanguageTools.ID_v0): Int64 =\n (i) + (i)" + +// // () param +// ("let emptyString () : String = \"\"" |> roundtripCliScript) = "let emptyString (_: Unit): String =\n \"\"" + + +// // multiple params +// ("let isHigher (a: Int64) (b: Int64) : Bool = (Stdlib.Int64.greaterThan_v0 a b)" +// |> roundtripCliScript) = "let isHigher (a: Int64) (b: Int64): Bool =\n PACKAGE.Darklang.Stdlib.Int64.greaterThan_v0 a b" + + + +// module FnCalls = +// //package function call +// ("let sum (a : Int64) (b : Int64) : Int64 = (PACKAGE.Darklang.Stdlib.Int64.add a b)" +// |> roundtripCliScript) = "let sum (a: Int64) (b: Int64): Int64 =\n PACKAGE.Darklang.Stdlib.Int64.add_v0 a b" + + + +// module CliScript = +// // TODO the output here is a bit broken +// (""" +// type BookID = Int64 + +// let getTitle (bookId: BookID): String = +// let book = (Library.getBook bookId) +// (getNameFromBook book) + +// let curiousGeorgeBookId = 101L +// (Builtin.printLine (getTitle curiousGeorgeBookId)) + +// 0L +// """ +// |> roundtripCliScript) = """type BookID = +// Int64 + +// let getTitle (bookId: BookID): String = +// let book = +// Library.getBook bookId +// getNameFromBook book + +// let curiousGeorgeBookId = +// 101L +// Builtin.printLine getTitle curiousGeorgeBookId + +// 0L""" \ No newline at end of file diff --git a/backend/tests/TestUtils/TestUtils.fs b/backend/tests/TestUtils/TestUtils.fs index 11c1ee65c8..b320ca84af 100644 --- a/backend/tests/TestUtils/TestUtils.fs +++ b/backend/tests/TestUtils/TestUtils.fs @@ -147,11 +147,6 @@ let localBuiltIns = let packageManager = LibCloud.PackageManager.packageManager -// This resolves both builtins and package functions -let nameResolver = - { LibParser.NameResolver.fromBuiltins localBuiltIns with - packageManager = packageManager } - let executionStateFor (canvasID : CanvasID) diff --git a/backend/tests/Tests/BwdServer.Tests.fs b/backend/tests/Tests/BwdServer.Tests.fs index 8cb4ef6bb7..adba0c7c4f 100644 --- a/backend/tests/Tests/BwdServer.Tests.fs +++ b/backend/tests/Tests/BwdServer.Tests.fs @@ -20,6 +20,7 @@ open Prelude module RT = LibExecution.RuntimeTypes module PT = LibExecution.ProgramTypes +module NR = LibParser.NameResolver module Routing = LibCloud.Routing module Canvas = LibCloud.Canvas module Serialize = LibCloud.Serialize @@ -44,6 +45,16 @@ type Test = expectedResponse : byte array } +let parse code = + LibParser.Parser.parsePTExpr + localBuiltIns + packageManager + NR.HackPackageStuff.empty + NR.UserStuff.empty + NR.OnMissing.ThrowError + "BwdServer.Tests.fs" + code + let newline = byte '\n' @@ -189,7 +200,6 @@ module ParseTest = let setupTestCanvas (testName : string) (test : Test) : Task = task { let! (canvasID, domain) = initializeTestCanvas' $"bwdserver-{testName}" - let resolver = nameResolver // Handlers let! oplists = @@ -197,7 +207,7 @@ let setupTestCanvas (testName : string) (test : Test) : Task |> Ply.List.mapSequentially (fun handler -> uply { let! source = - LibParser.Parser.parsePTExpr resolver "BwdServer.Tests.fs" handler.code + parse handler.code let spec = match handler.version with diff --git a/backend/tests/Tests/Canvas.Tests.fs b/backend/tests/Tests/Canvas.Tests.fs index ab6338771b..3608a02d4e 100644 --- a/backend/tests/Tests/Canvas.Tests.fs +++ b/backend/tests/Tests/Canvas.Tests.fs @@ -17,9 +17,18 @@ module Serialize = LibCloud.Serialize module PT = LibExecution.ProgramTypes module PTParser = LibExecution.ProgramTypesParser module Account = LibCloud.Account +module NR = LibParser.NameResolver let parse (code : string) : Task = - LibParser.Parser.parseSimple "tests.canvas.fs" code |> Ply.toTask + LibParser.Parser.parseSimple + localBuiltIns + packageManager + NR.HackPackageStuff.empty + NR.UserStuff.empty + NR.OnMissing.ThrowError + "tests.canvas.fs" + code + |> Ply.toTask let testDBOplistRoundtrip : Test = testTask "db oplist roundtrip" { diff --git a/backend/tests/Tests/Cron.Tests.fs b/backend/tests/Tests/Cron.Tests.fs index 46fb51bcef..240cd8efaf 100644 --- a/backend/tests/Tests/Cron.Tests.fs +++ b/backend/tests/Tests/Cron.Tests.fs @@ -13,9 +13,18 @@ module RT = LibExecution.RuntimeTypes module Cron = LibCloud.Cron module Canvas = LibCloud.Canvas module Serialize = LibCloud.Serialize +module NR = LibParser.NameResolver let p (code : string) : Task = - LibParser.Parser.parseSimple "cron.tests.fs" code |> Ply.toTask + LibParser.Parser.parseSimple + localBuiltIns + packageManager + NR.HackPackageStuff.empty + NR.UserStuff.empty + NR.OnMissing.ThrowError + "cron.tests.fs" + code + |> Ply.toTask let testCronFetchActiveCrons = diff --git a/backend/tests/Tests/HttpClient.Tests.fs b/backend/tests/Tests/HttpClient.Tests.fs index 043d6170c8..60dd6d602c 100644 --- a/backend/tests/Tests/HttpClient.Tests.fs +++ b/backend/tests/Tests/HttpClient.Tests.fs @@ -30,6 +30,7 @@ module RT = LibExecution.RuntimeTypes module PT = LibExecution.ProgramTypes module PT2RT = LibExecution.ProgramTypesToRuntimeTypes module Exe = LibExecution.Execution +module NR = LibParser.NameResolver open TestUtils.TestUtils @@ -85,6 +86,15 @@ let updateBody (body : byte array) : byte array = body |> List.fromArray |> find |> List.toArray +let parseTest test = + LibParser.TestModule.parseSingleTestFromFile + localBuiltIns + packageManager + NR.HackPackageStuff.empty + NR.UserStuff.empty + NR.OnMissing.ThrowError + test + let makeTest versionName filename = // Parse the file contents now, rather than later, so that tests that refer to // other tests (that is, tests for redirects) will work. @@ -155,9 +165,7 @@ let makeTest versionName filename = // CLEANUP: this doesn't use the correct length, as it might be latin1 or // compressed |> String.replace "LENGTH" (string response.body.Length) - |> LibParser.TestModule.parseSingleTestFromFile - nameResolver - "httpclient.tests.fs" + |> parseTest "httpclient.tests.fs" |> Ply.toTask // Run the handler (call the HTTP client) diff --git a/backend/tests/Tests/LibExecution.Tests.fs b/backend/tests/Tests/LibExecution.Tests.fs index b2bcd05b32..8cf756f44e 100644 --- a/backend/tests/Tests/LibExecution.Tests.fs +++ b/backend/tests/Tests/LibExecution.Tests.fs @@ -20,6 +20,7 @@ module PT = LibExecution.ProgramTypes module PTParser = LibExecution.ProgramTypesParser module PT2RT = LibExecution.ProgramTypesToRuntimeTypes module Exe = LibExecution.Execution +module NR = LibParser.NameResolver module Canvas = LibCloud.Canvas module Serialize = LibCloud.Serialize @@ -239,6 +240,15 @@ let baseDir = "testfiles/execution/" // Read all test files. The test file format is described in README.md let fileTests () : Test = + let parseTestFile fileName = + LibParser.TestModule.parseTestFile + localBuiltIns + packageManager + NR.HackPackageStuff.empty + NR.UserStuff.empty + NR.OnMissing.Allow + fileName + System.IO.Directory.GetDirectories(baseDir, "*") |> Array.map (fun dir -> System.IO.Directory.GetFiles(dir, "*.dark") @@ -254,14 +264,12 @@ let fileTests () : Test = else try let modules = - $"{dir}/{filename}" - |> LibParser.TestModule.parseTestFile nameResolver - |> fun ply -> ply.Result + $"{dir}/{filename}" |> parseTestFile |> (fun ply -> ply.Result) // Within a module, tests have access to - let fns = modules |> List.map _.fns |> List.concat - let types = modules |> List.map _.types |> List.concat - let constants = modules |> List.map _.constants |> List.concat + let fns = modules |> List.collect _.fns + let types = modules |> List.collect _.types + let constants = modules |> List.collect _.constants let tests = modules |> List.map (fun m -> diff --git a/backend/tests/Tests/Parser.Tests.fs b/backend/tests/Tests/Parser.Tests.fs index ee25f64660..df0c1281c5 100644 --- a/backend/tests/Tests/Parser.Tests.fs +++ b/backend/tests/Tests/Parser.Tests.fs @@ -9,38 +9,49 @@ module PT = LibExecution.ProgramTypes module PTParser = LibExecution.ProgramTypesParser module RT = LibExecution.RuntimeTypes module PT2RT = LibExecution.ProgramTypesToRuntimeTypes +module NR = LibParser.NameResolver - -let parserTests = +let id = 0UL // since we're ignoring IDs, just use the same one everywhere +let exprRTs = let t name testStr expectedExpr = testTask name { let! actual = - LibParser.Parser.parseRTExpr nameResolver "parser.tests.fs" testStr + LibParser.Parser.parseRTExpr + localBuiltIns + packageManager + NR.HackPackageStuff.empty + NR.UserStuff.empty + NR.OnMissing.Allow + "parser.tests.fs" + testStr |> Ply.toTask let expectedExpr = PT2RT.Expr.toRT expectedExpr return Expect.equalExprIgnoringIDs actual expectedExpr } - let id = 0UL // since we're ignoring IDs, just use the same one everywhere + + testList "Parser tests" - [ t - "pipe without expr" - "(let x = 5L\nx |> PACKAGE.Darklang.Stdlib.List.map_v0 5L)" - (PT.ELet( + // TODO: order these by simplicity, and add more tests + [ + // First, let's start with some simple ones + // that don't have any dependencies. + t "zero" "0.0" (PT.EFloat(id, Positive, "0", "0")) + + t "negative zero" "(-0.0)" (PT.EFloat(id, Negative, "0", "0")) + + t "negative 180" "-180.0" (PT.EFloat(id, Negative, "180", "0")) + + t + "10 cents" + "82.10" + (PT.EFloat( id, - PT.LPVariable(id, "x"), - PT.EInt64(id, 5L), - PT.EPipe( - id, - PT.EVariable(id, "x"), - [ PT.EPipeFnCall( - id, - Ok(PT.FQFnName.fqPackage "Darklang" [ "Stdlib"; "List" ] "map" 0), - [], - [ PT.EInt64(id, 5L) ] - ) ] - ) + Positive, + "82", + "099999999999994315658113919198513031005859375" )) + t "simple expr" "(5L + 3L) == 8L" @@ -55,6 +66,7 @@ let parserTests = ), PT.EInt64(id, 8L) )) + t "lambdas with 2 args" "fun x y -> 8L" @@ -63,6 +75,7 @@ let parserTests = NEList.doubleton (PT.LPVariable(id, "x")) (PT.LPVariable(id, "y")), PT.EInt64(id, 8L) )) + t "lambdas with 3 args" "fun x y z -> 8L" @@ -73,6 +86,7 @@ let parserTests = [ PT.LPVariable(id, "y"); PT.LPVariable(id, "z") ], PT.EInt64(id, 8L) )) + t "lambdas with 4 args" "fun a b c d -> 8L" @@ -85,17 +99,27 @@ let parserTests = PT.LPVariable(id, "d") ], PT.EInt64(id, 8L) )) - t "negative zero" "(-0.0)" (PT.EFloat(id, Negative, "0", "0")) + + // Now let's test some more complex expressions t - "10 cents" - "82.10" - (PT.EFloat( + "pipe without expr" + "(let x = 5L\nx |> PACKAGE.Darklang.Stdlib.List.map_v0 5L)" + (PT.ELet( id, - Positive, - "82", - "099999999999994315658113919198513031005859375" - )) - t "zero" "0.0" (PT.EFloat(id, Positive, "0", "0")) - t "negative 180" "-180.0" (PT.EFloat(id, Negative, "180", "0")) ] + PT.LPVariable(id, "x"), + PT.EInt64(id, 5L), + PT.EPipe( + id, + PT.EVariable(id, "x"), + [ PT.EPipeFnCall( + id, + Ok(PT.FQFnName.fqPackage "Darklang" [ "Stdlib"; "List" ] "map" 0), + [], + [ PT.EInt64(id, 5L) ] + ) ] + ) + )) ] + +//let canvases -let tests = testList "Parser" [ parserTests ] +let tests = testList "Parser" [ exprRTs ] diff --git a/backend/tests/Tests/ProgramTypes.Tests.fs b/backend/tests/Tests/ProgramTypes.Tests.fs index d9488a1676..dad115fb54 100644 --- a/backend/tests/Tests/ProgramTypes.Tests.fs +++ b/backend/tests/Tests/ProgramTypes.Tests.fs @@ -10,6 +10,7 @@ module RT = LibExecution.RuntimeTypes module PT2ST = LibBinarySerialization.ProgramTypesToSerializedTypes module PT2RT = LibExecution.ProgramTypesToRuntimeTypes module PTParser = LibExecution.ProgramTypesParser +module NR = LibParser.NameResolver module S = TestUtils.RTShortcuts let ptFQFnName = @@ -23,7 +24,13 @@ let testPipesToRuntimeTypes = testTask "pipes to runtime types" { let! actual = "value.age |> (-) 2L |> (+) value.age |> (<) 3L" - |> LibParser.Parser.parseRTExpr nameResolver "programTypes.tests.fs" + |> LibParser.Parser.parseRTExpr + localBuiltIns + packageManager + NR.HackPackageStuff.empty + NR.UserStuff.empty + NR.OnMissing.ThrowError + "programTypes.tests.fs" |> Ply.toTask let expected = diff --git a/backend/tests/Tests/Queue.Tests.fs b/backend/tests/Tests/Queue.Tests.fs index a339b1ab70..6578d57f4f 100644 --- a/backend/tests/Tests/Queue.Tests.fs +++ b/backend/tests/Tests/Queue.Tests.fs @@ -17,6 +17,7 @@ open TestUtils.TestUtils module PT = LibExecution.ProgramTypes module RT = LibExecution.RuntimeTypes +module NR = LibParser.NameResolver module EQ = LibCloud.Queue module Canvas = LibCloud.Canvas module Serialize = LibCloud.Serialize @@ -25,7 +26,15 @@ module SR = LibCloud.QueueSchedulingRules module TCS = LibCloud.TraceCloudStorage let p (code : string) : Task = - LibParser.Parser.parsePTExpr nameResolver "Queue.Tests.fs" code |> Ply.toTask + LibParser.Parser.parsePTExpr + localBuiltIns + packageManager + NR.HackPackageStuff.empty + NR.UserStuff.empty + NR.OnMissing.ThrowError + "Queue.Tests.fs" + code + |> Ply.toTask // This doesn't actually test input, since it's a cron handler and not an actual event handler diff --git a/backend/tests/Tests/QueueSchedulingRules.Tests.fs b/backend/tests/Tests/QueueSchedulingRules.Tests.fs index fb7571cee0..e8033c30ff 100644 --- a/backend/tests/Tests/QueueSchedulingRules.Tests.fs +++ b/backend/tests/Tests/QueueSchedulingRules.Tests.fs @@ -11,13 +11,21 @@ open TestUtils.TestUtils module PT = LibExecution.ProgramTypes module RT = LibExecution.RuntimeTypes +module NR = LibParser.NameResolver module EQ2 = LibCloud.Queue module Canvas = LibCloud.Canvas module Serialize = LibCloud.Serialize module SR = LibCloud.QueueSchedulingRules let p (code : string) : Task = - LibParser.Parser.parsePTExpr nameResolver "queueschedulingrules.fs" code + LibParser.Parser.parsePTExpr + localBuiltIns + packageManager + NR.HackPackageStuff.empty + NR.UserStuff.empty + NR.OnMissing.ThrowError + "queueschedulingrules.fs" + code |> Ply.toTask diff --git a/backend/tests/Tests/SqlCompiler.Tests.fs b/backend/tests/Tests/SqlCompiler.Tests.fs index e733840573..87fd3d12ed 100644 --- a/backend/tests/Tests/SqlCompiler.Tests.fs +++ b/backend/tests/Tests/SqlCompiler.Tests.fs @@ -9,20 +9,34 @@ open FSharp.Control.Tasks module PT = LibExecution.ProgramTypes open LibExecution.RuntimeTypes +module NR = LibParser.NameResolver module C = LibCloud.SqlCompiler module S = TestUtils.RTShortcuts module PT2RT = LibExecution.ProgramTypesToRuntimeTypes let p (code : string) : Task = - LibParser.Parser.parseRTExpr nameResolver "sqlcompiler.tests.fs" code + LibParser.Parser.parseRTExpr + localBuiltIns + packageManager + NR.HackPackageStuff.empty + NR.UserStuff.empty + NR.OnMissing.ThrowError + "sqlcompiler.tests.fs" + code |> Ply.toTask let parse - (nameResolver : LibParser.NameResolver.NameResolver) + (userFns: List) (code : string) : Task = - LibParser.Parser.parseRTExpr nameResolver "sqlcompiler.tests.fs" code + LibParser.Parser.parseRTExpr + localBuiltIns + packageManager + NR.HackPackageStuff.empty + { NR.UserStuff.empty with fns = Set userFns } + NR.OnMissing.ThrowError + "sqlcompiler.tests.fs" code |> Ply.toTask let compile @@ -154,11 +168,7 @@ let inlineWorksAtRoot = Map.empty let fns = ExecutionState.availableFunctions state let! expr = - LibParser.Parser.parseRTExpr - nameResolver - "test.fs" - "let y = 5 in let x = 6 in (3 + (let x = 7 in y))" - |> Ply.toTask + p "let y = 5 in let x = 6 in (3 + (let x = 7 in y))" let! expected = p "3 + 5" let! result = (C.inline' fns "value" Map.empty expr) |> Ply.toTask @@ -256,13 +266,9 @@ let inlineWorksWithUserFunctions = Map.add userAdd.name userAdd existingFunctions.userProgram let fns = { existingFunctions with userProgram = updatedUserProgram } - let nr = - { nameResolver with - userFns = Set.singleton (PT.FQFnName.userProgram [] "userAdd" 0) } - let! expr = parse - nr + [PT.FQFnName.userProgram [] "userAdd" 0] "let a = 1 in let b = 9 in let c = userAdd 6 4 in (p.height == c) && (p.age == b)" let! expected = p "p.height == (6 + 4) && p.age == 9" @@ -301,13 +307,9 @@ let inlineWorksWithPackageAndUserFunctions = Map.add userAnd.name userAnd existingFunctions.userProgram let fns = { existingFunctions with userProgram = updatedUserProgram } - let nr = - { nameResolver with - userFns = Set.singleton (PT.FQFnName.userProgram [] "userAnd" 0) } - let! expr = parse - nr + [PT.FQFnName.userProgram [] "userAnd" 0] "userAnd user.human (PACKAGE.Darklang.Stdlib.Int64.lessThan_v0 user.height (PACKAGE.Darklang.Stdlib.Int64.add height 1))" let! expected = p "user.human && (user.height < (height + 1))" @@ -344,13 +346,11 @@ let inlineFunctionArguments = Map.add userAdd.name userAdd existingFunctions.userProgram let fns = { existingFunctions with userProgram = updatedUserProgram } - let nr = - { nameResolver with - userFns = Set.singleton (PT.FQFnName.userProgram [] "userAdd" 0) } + let userFns = [PT.FQFnName.userProgram [] "userAdd" 0] - let! expr = parse nr "let a = 1 in let b = 9 in (p.height == userAdd 6 (b - 4))" + let! expr = parse userFns "let a = 1 in let b = 9 in (p.height == userAdd 6 (b - 4))" - let! expected = parse nr "p.height == 6 + (9 - 4)" + let! expected = parse userFns "p.height == 6 + (9 - 4)" let! result = (C.inline' fns "value" Map.empty expr) |> Ply.toTask return Expect.equalExprIgnoringIDs result expected } diff --git a/backend/tests/Tests/Tests.fs b/backend/tests/Tests/Tests.fs index 444b4d4e74..0730815fba 100644 --- a/backend/tests/Tests/Tests.fs +++ b/backend/tests/Tests/Tests.fs @@ -31,12 +31,12 @@ let main (args : string array) : int = let tests = [ Tests.AnalysisTypes.tests - //Tests.BwdServer.tests + Tests.BwdServer.tests Tests.Canvas.tests Tests.Cron.tests Tests.DvalRepr.tests Tests.QueueSchedulingRules.tests - // TODO: bring these back Tests.Queue.tests + // TODO: bring back Tests.Queue.tests Tests.Execution.tests Tests.Parser.tests Tests.HttpClient.tests @@ -55,7 +55,7 @@ let main (args : string array) : int = Tests.StorageTraces.tests ] let cancelationTokenSource = new System.Threading.CancellationTokenSource() - // let bwdServerTestsTask = Tests.BwdServer.init cancelationTokenSource.Token + let bwdServerTestsTask = Tests.BwdServer.init cancelationTokenSource.Token let httpClientTestsTask = Tests.HttpClient.init cancelationTokenSource.Token Telemetry.Console.loadTelemetry "tests" Telemetry.TraceDBQueries @@ -70,7 +70,7 @@ let main (args : string array) : int = NonBlockingConsole.wait () // flush stdout cancelationTokenSource.Cancel() - //bwdServerTestsTask.Wait() + bwdServerTestsTask.Wait() httpClientTestsTask.Wait() QueueWorker.shouldShutdown <- true exitCode From 3783cd3b5cad730da8fd99c2c214fdc6825ec738 Mon Sep 17 00:00:00 2001 From: Stachu Korick Date: Sat, 20 Apr 2024 12:02:34 -0400 Subject: [PATCH 6/8] uncomment tests --- .../testfiles/execution/stdlib/parser.dark | 586 +++++++++--------- 1 file changed, 293 insertions(+), 293 deletions(-) diff --git a/backend/testfiles/execution/stdlib/parser.dark b/backend/testfiles/execution/stdlib/parser.dark index d59335c7c5..472a908af5 100644 --- a/backend/testfiles/execution/stdlib/parser.dark +++ b/backend/testfiles/execution/stdlib/parser.dark @@ -208,296 +208,296 @@ module TextToTextRoundtripping = module TypeReference = // all built-ins ("type MyUnit = Unit" |> roundtripCliScript) = "type MyUnit =\n Unit" -// ("type MyBool = Bool" |> roundtripCliScript) = "type MyBool =\n Bool" -// ("type MyInt8 = Int8" |> roundtripCliScript) = "type MyInt8 =\n Int8" -// ("type MyUInt8 = UInt8" |> roundtripCliScript) = "type MyUInt8 =\n UInt8" -// ("type MyInt16 = Int16" |> roundtripCliScript) = "type MyInt16 =\n Int16" -// ("type MyUInt16 = UInt16" |> roundtripCliScript) = "type MyUInt16 =\n UInt16" -// ("type MyInt32 = Int32" |> roundtripCliScript) = "type MyInt32 =\n Int32" -// ("type MyUInt32 = UInt32" |> roundtripCliScript) = "type MyUInt32 =\n UInt32" -// ("type MyInt64 = Int64" |> roundtripCliScript) = "type MyInt64 =\n Int64" -// ("type MyUInt64 = UInt64" |> roundtripCliScript) = "type MyUInt64 =\n UInt64" -// ("type MyInt128 = Int128" |> roundtripCliScript) = "type MyInt128 =\n Int128" -// ("type MyUInt128 = UInt128" |> roundtripCliScript) = "type MyUInt128 =\n UInt128" -// ("type MyFloat = Float" |> roundtripCliScript) = "type MyFloat =\n Float" -// ("type MyChar = Char" |> roundtripCliScript) = "type MyChar =\n Char" -// ("type MyString = String" |> roundtripCliScript) = "type MyString =\n String" - -// ("type MyList = List" |> roundtripCliScript) = "type MyList =\n List" -// ("type MyList = List>" |> roundtripCliScript) = "type MyList =\n List>" -// ("type MyList = List" |> roundtripCliScript) = "type MyList =\n List" - -// ("type MyDict = Dict" |> roundtripCliScript) = "type MyDict =\n Dict" -// ("type MyDict = Dict" |> roundtripCliScript) = "type MyDict =\n Dict" - -// ("type MyTuple2 = (String * Int64)" |> roundtripCliScript) = "type MyTuple2 =\n (String * Int64)" -// ("type MyTuple3 = (String * Int64 * Bool)" |> roundtripCliScript) = "type MyTuple3 =\n (String * Int64 * Bool)" -// ("type MyTuple = (String * Int64 * Bool * Unit)" |> roundtripCliScript) = "type MyTuple =\n (String * Int64 * Bool * Unit)" -// // single-part qualified name -// ("type ID = Test" |> roundtripCliScript) = "type ID =\n Test" - -// // fully-qualified package name (multi-part) -// ("type MyOption = PACKAGE.Darklang.Stdlib.Option.Option" |> roundtripCliScript) = "type MyOption =\n PACKAGE.Darklang.Stdlib.Option.Option_v0" -// ("type MyOption = Stdlib.Option.Option" |> roundtripCliScript) = "type MyOption =\n PACKAGE.Darklang.Stdlib.Option.Option_v0" - - -// module TypeDeclaration = -// ("type SimpleAlias = Unit" |> roundtripCliScript) = "type SimpleAlias =\n Unit" - -// // record type -// ("type Person = {name: String}" |> roundtripCliScript) = "type Person =\n { name: String }" - -// ("type Person = {name: String; age: Int64}" |> roundtripCliScript) = "type Person =\n { name: String\n age: Int64 }" -// ("type Person = {name: String; age: Int64; hasPet: Bool}" |> roundtripCliScript) = "type Person =\n { name: String\n age: Int64\n hasPet: Bool }" - -// ("type Person = {name: String; age: Int64; hasPet: Bool; pet: Pet}" -// |> roundtripCliScript) = """type Person = -// { name: String -// age: Int64 -// hasPet: Bool -// pet: Pet }""" - -// module Expr = -// // units -// ("()" |> roundtripCliScript) = "()" - -// // bools -// ("true" |> roundtripCliScript) = "true" -// ("false" |> roundtripCliScript) = "false" - -// // parens (disappear) -// ("(true)" |> roundtripCliScript) = "true" - -// // int literals -// ("1y" |> roundtripCliScript) = "1y" -// ("-1y" |> roundtripCliScript) = "-1y" -// ("1uy" |> roundtripCliScript) = "1uy" -// ("1s" |> roundtripCliScript) = "1s" -// ("1us" |> roundtripCliScript) = "1us" -// ("1l" |> roundtripCliScript) = "1l" -// ("-1l" |> roundtripCliScript) = "-1l" -// ("1ul" |> roundtripCliScript) = "1ul" -// ("0L" |> roundtripCliScript) = "0L" -// ("1900L" |> roundtripCliScript) = "1900L" -// ("-1900L" |> roundtripCliScript) = "-1900L" -// ("1UL" |> roundtripCliScript) = "1UL" -// ("1Q" |> roundtripCliScript) = "1Q" -// ("-1Q" |> roundtripCliScript) = "-1Q" -// ("1Q" |> roundtripCliScript) = "1Q" - -// // float literals -// ("-1.0" |> roundtripCliScript) = "-1.0" -// ("-1.5" |> roundtripCliScript) = "-1.5" -// ("1.5" |> roundtripCliScript) = "1.5" -// ("0.0" |> roundtripCliScript) = "0.0" -// ("0.775" |> roundtripCliScript) = "0.775" - -// // string literals -// ("\"\"" |> roundtripCliScript) = "\"\"" -// ("\"hello\"" |> roundtripCliScript) = "\"hello\"" -// ("\"hello\\tworld\"" |> roundtripCliScript) = "\"hello\\tworld\"" - -// // char literals -// ("'a'" |> roundtripCliScript) = "'a'" -// ("'\\n'" |> roundtripCliScript) = "'\\n'" -// ("'\t'" |> roundtripCliScript) = "'\t'" - -// // list literal -// ("[]" |> roundtripCliScript) = "[]" -// ("[\"hello\"]" |> roundtripCliScript) = "[\"hello\"]" -// ("[1L; 2L]" |> roundtripCliScript) = "[1L; 2L]" -// ("[1L; 2L; 3L;]" |> roundtripCliScript) = "[1L; 2L; 3L]" -// ("[true; false; true; false]" |> roundtripCliScript) = "[true; false; true; false]" -// ("[[1L; 2L]; [3L; 4L]]" |> roundtripCliScript) = "[[1L; 2L]; [3L; 4L]]" - -// // dict literal -// ("Dict { }" |> roundtripCliScript) = "Dict { }" -// ("Dict { a = 1L }" |> roundtripCliScript) = "Dict { a = 1L }" -// ("Dict { a = \"hello\"; b = \"test\" }" |> roundtripCliScript) = "Dict { a = \"hello\"; b = \"test\" }" -// ("Dict { a = 1L; b = 2L; c = 3L }" |> roundtripCliScript) = "Dict { a = 1L; b = 2L; c = 3L }" - -// // tuple literals -// ("(1L, \"hello\")" |> roundtripCliScript) = "(1L, \"hello\")" -// ("(1L, \"hello\", 2L)" |> roundtripCliScript) = "(1L, \"hello\", 2L)" -// ("(1L, \"hello\", 2L, true)" |> roundtripCliScript) = "(1L, \"hello\", 2L, true)" -// ("(1L, 2L + 3L, 4L)" |> roundtripCliScript) = "(1L, (2L) + (3L), 4L)" - -// // record literal -// ("Person {name =\"John\"} " |> roundtripCliScript) = "Person { name = \"John\" }" -// ("Person {name =\"John\"; age = 30L} " |> roundtripCliScript) = "Person { name = \"John\"; age = 30L }" -// ("Person {name =\"John\"; age = 30L; hasPet = true} " |> roundtripCliScript) = "Person { name = \"John\"; age = 30L; hasPet = true }" - -// ("Person {name =\"John\"; age = 30L; hasPet = true; pet = Pet {name = \"Luna\"}} " -// |> roundtripCliScript) = "Person { name = \"John\"; age = 30L; hasPet = true; pet = Pet { name = \"Luna\" } }" - -// // variables and let bindings -// ("assumedlyAVariableName" |> roundtripCliScript) = "assumedlyAVariableName" -// // TODO: this is ugly -// ("let x = 1L\n x" |> roundtripCliScript) = "let x =\n 1L\nx" - -// // if expressions -// ("if true then 1L" |> roundtripCliScript) = "if true then\n 1L" -// ("if true then 1L else 2L" |> roundtripCliScript) = "if true then\n 1L\nelse\n 2L" -// ("if a < b then 1L else if c > d then 2L" |> roundtripCliScript) = "if (a) < (b) then\n 1L\nelse if (c) > (d) then\n 2L" -// ("if a < b then 1L else if c > d then 2L else 3L" |> roundtripCliScript) = "if (a) < (b) then\n 1L\nelse if (c) > (d) then\n 2L\nelse\n 3L" - -// ("if true then\n 1L" |> roundtripCliScript) = "if true then\n 1L" -// ("if true then\n 1L\nelse\n 2L" |> roundtripCliScript) = "if true then\n 1L\nelse\n 2L" -// ("if true then\n a\nelse if false then\n c" |> roundtripCliScript) = "if true then\n a\nelse if false then\n c" - -// ("if a > b then\n a\nelse if c > d then\n c\nelse d" |> roundtripCliScript) = "if (a) > (b) then\n a\nelse if (c) > (d) then\n c\nelse\n d" - -// ("if true then\n\ta\nelse\n\tb" |> roundtripCliScript) = "if true then\n a\nelse\n b" - -// ("""if true then -// a -// else if false then -// c -// else if true then -// d""" -// |> roundtripCliScript) = """if true then -// a -// else if false then -// c -// else if true then -// d""" - - -// ("""if true then -// a -// else if false then -// c -// else if true then -// d -// else -// e""" -// |> roundtripCliScript) = """if true then -// a -// else if false then -// c -// else if true then -// d -// else -// e""" - -// // else for inner if -// ("""if a > b then -// if c > d then -// c -// else -// b""" -// |> roundtripCliScript) = """if (a) > (b) then -// if (c) > (d) then -// c -// else -// b""" - -// // else for outer if -// ("""if a > b then -// if c > d then -// c -// else -// b""" -// |> roundtripCliScript) = """if (a) > (b) then -// if (c) > (d) then -// c -// else -// b""" - -// // nested if -// ("""if a > b then -// a -// else -// if c > d then -// c -// else -// if e > f then -// e -// else -// if g > h then -// g -// else -// h""" -// |> roundtripCliScript) = """if (a) > (b) then -// a -// else if (c) > (d) then -// c -// else if (e) > (f) then -// e -// else if (g) > (h) then -// g -// else -// h""" - - -// // fn calls -// // TODO: these are ugly -// ("1L + 2L" |> roundtripCliScript) = "(1L) + (2L)" -// ("1L + b + 3L" |> roundtripCliScript) = "((1L) + (b)) + (3L)" -// ("1L + 2L * 3L - 4L" |> roundtripCliScript) = "((1L) + ((2L) * (3L))) - (4L)" -// ("1L > 2L" |> roundtripCliScript) = "(1L) > (2L)" -// ("1L >= 2L" |> roundtripCliScript) = "(1L) >= (2L)" -// ("1L < 2L" |> roundtripCliScript) = "(1L) < (2L)" -// ("1L <= 2L" |> roundtripCliScript) = "(1L) <= (2L)" -// ("1L == 2L" |> roundtripCliScript) = "(1L) == (2L)" -// ("1L != 2L" |> roundtripCliScript) = "(1L) != (2L)" -// ("1L ^ 2L" |> roundtripCliScript) = "(1L) ^ (2L)" -// ("true && false" |> roundtripCliScript) = "(true) && (false)" -// ("true || false" |> roundtripCliScript) = "(true) || (false)" -// ("(and true false)" |> roundtripCliScript) = "and true false" -// ("(Bool.and true false)" |> roundtripCliScript) = "Bool.and true false" -// ("(PACKAGE.Darklang.Stdlib.Bool.and true false)" |> roundtripCliScript) = "PACKAGE.Darklang.Stdlib.Bool.and_v0 true false" -// ("(Stdlib.Bool.and true false)" |> roundtripCliScript) = "PACKAGE.Darklang.Stdlib.Bool.and_v0 true false" -// ("(Builtin.int64Add 1L 2L)" |> roundtripCliScript) = "Builtin.int64Add 1L 2L" - -// module FunctionDeclaration = -// // single 'normal' param -// ("let helloWorld (i: Int64): String = \"Hello world\"" |> roundtripCliScript) = "let helloWorld (i: Int64): String =\n \"Hello world\"" - -// ("let double2 (i: PACKAGE.Darklang.LanguageTools.ID_v0) : Int64 = i + i" -// |> roundtripCliScript) = "let double2 (i: PACKAGE.Darklang.LanguageTools.ID_v0): Int64 =\n (i) + (i)" - -// // () param -// ("let emptyString () : String = \"\"" |> roundtripCliScript) = "let emptyString (_: Unit): String =\n \"\"" - - -// // multiple params -// ("let isHigher (a: Int64) (b: Int64) : Bool = (Stdlib.Int64.greaterThan_v0 a b)" -// |> roundtripCliScript) = "let isHigher (a: Int64) (b: Int64): Bool =\n PACKAGE.Darklang.Stdlib.Int64.greaterThan_v0 a b" - - - -// module FnCalls = -// //package function call -// ("let sum (a : Int64) (b : Int64) : Int64 = (PACKAGE.Darklang.Stdlib.Int64.add a b)" -// |> roundtripCliScript) = "let sum (a: Int64) (b: Int64): Int64 =\n PACKAGE.Darklang.Stdlib.Int64.add_v0 a b" - - - -// module CliScript = -// // TODO the output here is a bit broken -// (""" -// type BookID = Int64 - -// let getTitle (bookId: BookID): String = -// let book = (Library.getBook bookId) -// (getNameFromBook book) - -// let curiousGeorgeBookId = 101L -// (Builtin.printLine (getTitle curiousGeorgeBookId)) - -// 0L -// """ -// |> roundtripCliScript) = """type BookID = -// Int64 - -// let getTitle (bookId: BookID): String = -// let book = -// Library.getBook bookId -// getNameFromBook book - -// let curiousGeorgeBookId = -// 101L -// Builtin.printLine getTitle curiousGeorgeBookId - -// 0L""" \ No newline at end of file + ("type MyBool = Bool" |> roundtripCliScript) = "type MyBool =\n Bool" + ("type MyInt8 = Int8" |> roundtripCliScript) = "type MyInt8 =\n Int8" + ("type MyUInt8 = UInt8" |> roundtripCliScript) = "type MyUInt8 =\n UInt8" + ("type MyInt16 = Int16" |> roundtripCliScript) = "type MyInt16 =\n Int16" + ("type MyUInt16 = UInt16" |> roundtripCliScript) = "type MyUInt16 =\n UInt16" + ("type MyInt32 = Int32" |> roundtripCliScript) = "type MyInt32 =\n Int32" + ("type MyUInt32 = UInt32" |> roundtripCliScript) = "type MyUInt32 =\n UInt32" + ("type MyInt64 = Int64" |> roundtripCliScript) = "type MyInt64 =\n Int64" + ("type MyUInt64 = UInt64" |> roundtripCliScript) = "type MyUInt64 =\n UInt64" + ("type MyInt128 = Int128" |> roundtripCliScript) = "type MyInt128 =\n Int128" + ("type MyUInt128 = UInt128" |> roundtripCliScript) = "type MyUInt128 =\n UInt128" + ("type MyFloat = Float" |> roundtripCliScript) = "type MyFloat =\n Float" + ("type MyChar = Char" |> roundtripCliScript) = "type MyChar =\n Char" + ("type MyString = String" |> roundtripCliScript) = "type MyString =\n String" + + ("type MyList = List" |> roundtripCliScript) = "type MyList =\n List" + ("type MyList = List>" |> roundtripCliScript) = "type MyList =\n List>" + ("type MyList = List" |> roundtripCliScript) = "type MyList =\n List" + + ("type MyDict = Dict" |> roundtripCliScript) = "type MyDict =\n Dict" + ("type MyDict = Dict" |> roundtripCliScript) = "type MyDict =\n Dict" + + ("type MyTuple2 = (String * Int64)" |> roundtripCliScript) = "type MyTuple2 =\n (String * Int64)" + ("type MyTuple3 = (String * Int64 * Bool)" |> roundtripCliScript) = "type MyTuple3 =\n (String * Int64 * Bool)" + ("type MyTuple = (String * Int64 * Bool * Unit)" |> roundtripCliScript) = "type MyTuple =\n (String * Int64 * Bool * Unit)" + // single-part qualified name + ("type ID = Test" |> roundtripCliScript) = "type ID =\n Test" + + // fully-qualified package name (multi-part) + ("type MyOption = PACKAGE.Darklang.Stdlib.Option.Option" |> roundtripCliScript) = "type MyOption =\n PACKAGE.Darklang.Stdlib.Option.Option_v0" + ("type MyOption = Stdlib.Option.Option" |> roundtripCliScript) = "type MyOption =\n PACKAGE.Darklang.Stdlib.Option.Option_v0" + + + module TypeDeclaration = + ("type SimpleAlias = Unit" |> roundtripCliScript) = "type SimpleAlias =\n Unit" + + // record type + ("type Person = {name: String}" |> roundtripCliScript) = "type Person =\n { name: String }" + + ("type Person = {name: String; age: Int64}" |> roundtripCliScript) = "type Person =\n { name: String\n age: Int64 }" + ("type Person = {name: String; age: Int64; hasPet: Bool}" |> roundtripCliScript) = "type Person =\n { name: String\n age: Int64\n hasPet: Bool }" + + ("type Person = {name: String; age: Int64; hasPet: Bool; pet: Pet}" + |> roundtripCliScript) = """type Person = + { name: String + age: Int64 + hasPet: Bool + pet: Pet }""" + + module Expr = + // units + ("()" |> roundtripCliScript) = "()" + + // bools + ("true" |> roundtripCliScript) = "true" + ("false" |> roundtripCliScript) = "false" + + // parens (disappear) + ("(true)" |> roundtripCliScript) = "true" + + // int literals + ("1y" |> roundtripCliScript) = "1y" + ("-1y" |> roundtripCliScript) = "-1y" + ("1uy" |> roundtripCliScript) = "1uy" + ("1s" |> roundtripCliScript) = "1s" + ("1us" |> roundtripCliScript) = "1us" + ("1l" |> roundtripCliScript) = "1l" + ("-1l" |> roundtripCliScript) = "-1l" + ("1ul" |> roundtripCliScript) = "1ul" + ("0L" |> roundtripCliScript) = "0L" + ("1900L" |> roundtripCliScript) = "1900L" + ("-1900L" |> roundtripCliScript) = "-1900L" + ("1UL" |> roundtripCliScript) = "1UL" + ("1Q" |> roundtripCliScript) = "1Q" + ("-1Q" |> roundtripCliScript) = "-1Q" + ("1Q" |> roundtripCliScript) = "1Q" + + // float literals + ("-1.0" |> roundtripCliScript) = "-1.0" + ("-1.5" |> roundtripCliScript) = "-1.5" + ("1.5" |> roundtripCliScript) = "1.5" + ("0.0" |> roundtripCliScript) = "0.0" + ("0.775" |> roundtripCliScript) = "0.775" + + // string literals + ("\"\"" |> roundtripCliScript) = "\"\"" + ("\"hello\"" |> roundtripCliScript) = "\"hello\"" + ("\"hello\\tworld\"" |> roundtripCliScript) = "\"hello\\tworld\"" + + // char literals + ("'a'" |> roundtripCliScript) = "'a'" + ("'\\n'" |> roundtripCliScript) = "'\\n'" + ("'\t'" |> roundtripCliScript) = "'\t'" + + // list literal + ("[]" |> roundtripCliScript) = "[]" + ("[\"hello\"]" |> roundtripCliScript) = "[\"hello\"]" + ("[1L; 2L]" |> roundtripCliScript) = "[1L; 2L]" + ("[1L; 2L; 3L;]" |> roundtripCliScript) = "[1L; 2L; 3L]" + ("[true; false; true; false]" |> roundtripCliScript) = "[true; false; true; false]" + ("[[1L; 2L]; [3L; 4L]]" |> roundtripCliScript) = "[[1L; 2L]; [3L; 4L]]" + + // dict literal + ("Dict { }" |> roundtripCliScript) = "Dict { }" + ("Dict { a = 1L }" |> roundtripCliScript) = "Dict { a = 1L }" + ("Dict { a = \"hello\"; b = \"test\" }" |> roundtripCliScript) = "Dict { a = \"hello\"; b = \"test\" }" + ("Dict { a = 1L; b = 2L; c = 3L }" |> roundtripCliScript) = "Dict { a = 1L; b = 2L; c = 3L }" + + // tuple literals + ("(1L, \"hello\")" |> roundtripCliScript) = "(1L, \"hello\")" + ("(1L, \"hello\", 2L)" |> roundtripCliScript) = "(1L, \"hello\", 2L)" + ("(1L, \"hello\", 2L, true)" |> roundtripCliScript) = "(1L, \"hello\", 2L, true)" + ("(1L, 2L + 3L, 4L)" |> roundtripCliScript) = "(1L, (2L) + (3L), 4L)" + + // record literal + ("Person {name =\"John\"} " |> roundtripCliScript) = "Person { name = \"John\" }" + ("Person {name =\"John\"; age = 30L} " |> roundtripCliScript) = "Person { name = \"John\"; age = 30L }" + ("Person {name =\"John\"; age = 30L; hasPet = true} " |> roundtripCliScript) = "Person { name = \"John\"; age = 30L; hasPet = true }" + + ("Person {name =\"John\"; age = 30L; hasPet = true; pet = Pet {name = \"Luna\"}} " + |> roundtripCliScript) = "Person { name = \"John\"; age = 30L; hasPet = true; pet = Pet { name = \"Luna\" } }" + + // variables and let bindings + ("assumedlyAVariableName" |> roundtripCliScript) = "assumedlyAVariableName" + // TODO: this is ugly + ("let x = 1L\n x" |> roundtripCliScript) = "let x =\n 1L\nx" + + // if expressions + ("if true then 1L" |> roundtripCliScript) = "if true then\n 1L" + ("if true then 1L else 2L" |> roundtripCliScript) = "if true then\n 1L\nelse\n 2L" + ("if a < b then 1L else if c > d then 2L" |> roundtripCliScript) = "if (a) < (b) then\n 1L\nelse if (c) > (d) then\n 2L" + ("if a < b then 1L else if c > d then 2L else 3L" |> roundtripCliScript) = "if (a) < (b) then\n 1L\nelse if (c) > (d) then\n 2L\nelse\n 3L" + + ("if true then\n 1L" |> roundtripCliScript) = "if true then\n 1L" + ("if true then\n 1L\nelse\n 2L" |> roundtripCliScript) = "if true then\n 1L\nelse\n 2L" + ("if true then\n a\nelse if false then\n c" |> roundtripCliScript) = "if true then\n a\nelse if false then\n c" + + ("if a > b then\n a\nelse if c > d then\n c\nelse d" |> roundtripCliScript) = "if (a) > (b) then\n a\nelse if (c) > (d) then\n c\nelse\n d" + + ("if true then\n\ta\nelse\n\tb" |> roundtripCliScript) = "if true then\n a\nelse\n b" + + ("""if true then + a +else if false then + c +else if true then + d""" + |> roundtripCliScript) = """if true then + a +else if false then + c +else if true then + d""" + + + ("""if true then + a +else if false then + c +else if true then + d +else + e""" + |> roundtripCliScript) = """if true then + a +else if false then + c +else if true then + d +else + e""" + + // else for inner if + ("""if a > b then + if c > d then + c + else + b""" + |> roundtripCliScript) = """if (a) > (b) then + if (c) > (d) then + c + else + b""" + + // else for outer if + ("""if a > b then + if c > d then + c +else + b""" + |> roundtripCliScript) = """if (a) > (b) then + if (c) > (d) then + c +else + b""" + + // nested if + ("""if a > b then + a +else + if c > d then + c + else + if e > f then + e + else + if g > h then + g + else + h""" + |> roundtripCliScript) = """if (a) > (b) then + a +else if (c) > (d) then + c +else if (e) > (f) then + e +else if (g) > (h) then + g +else + h""" + + + // fn calls + // TODO: these are ugly + ("1L + 2L" |> roundtripCliScript) = "(1L) + (2L)" + ("1L + b + 3L" |> roundtripCliScript) = "((1L) + (b)) + (3L)" + ("1L + 2L * 3L - 4L" |> roundtripCliScript) = "((1L) + ((2L) * (3L))) - (4L)" + ("1L > 2L" |> roundtripCliScript) = "(1L) > (2L)" + ("1L >= 2L" |> roundtripCliScript) = "(1L) >= (2L)" + ("1L < 2L" |> roundtripCliScript) = "(1L) < (2L)" + ("1L <= 2L" |> roundtripCliScript) = "(1L) <= (2L)" + ("1L == 2L" |> roundtripCliScript) = "(1L) == (2L)" + ("1L != 2L" |> roundtripCliScript) = "(1L) != (2L)" + ("1L ^ 2L" |> roundtripCliScript) = "(1L) ^ (2L)" + ("true && false" |> roundtripCliScript) = "(true) && (false)" + ("true || false" |> roundtripCliScript) = "(true) || (false)" + ("(and true false)" |> roundtripCliScript) = "and true false" + ("(Bool.and true false)" |> roundtripCliScript) = "Bool.and true false" + ("(PACKAGE.Darklang.Stdlib.Bool.and true false)" |> roundtripCliScript) = "PACKAGE.Darklang.Stdlib.Bool.and_v0 true false" + ("(Stdlib.Bool.and true false)" |> roundtripCliScript) = "PACKAGE.Darklang.Stdlib.Bool.and_v0 true false" + ("(Builtin.int64Add 1L 2L)" |> roundtripCliScript) = "Builtin.int64Add 1L 2L" + + module FunctionDeclaration = + // single 'normal' param + ("let helloWorld (i: Int64): String = \"Hello world\"" |> roundtripCliScript) = "let helloWorld (i: Int64): String =\n \"Hello world\"" + + ("let double2 (i: PACKAGE.Darklang.LanguageTools.ID_v0) : Int64 = i + i" + |> roundtripCliScript) = "let double2 (i: PACKAGE.Darklang.LanguageTools.ID_v0): Int64 =\n (i) + (i)" + + // () param + ("let emptyString () : String = \"\"" |> roundtripCliScript) = "let emptyString (_: Unit): String =\n \"\"" + + + // multiple params + ("let isHigher (a: Int64) (b: Int64) : Bool = (Stdlib.Int64.greaterThan_v0 a b)" + |> roundtripCliScript) = "let isHigher (a: Int64) (b: Int64): Bool =\n PACKAGE.Darklang.Stdlib.Int64.greaterThan_v0 a b" + + + + module FnCalls = + //package function call + ("let sum (a : Int64) (b : Int64) : Int64 = (PACKAGE.Darklang.Stdlib.Int64.add a b)" + |> roundtripCliScript) = "let sum (a: Int64) (b: Int64): Int64 =\n PACKAGE.Darklang.Stdlib.Int64.add_v0 a b" + + + + module CliScript = + // TODO the output here is a bit broken + (""" +type BookID = Int64 + +let getTitle (bookId: BookID): String = + let book = (Library.getBook bookId) + (getNameFromBook book) + +let curiousGeorgeBookId = 101L +(Builtin.printLine (getTitle curiousGeorgeBookId)) + +0L +""" + |> roundtripCliScript) = """type BookID = + Int64 + +let getTitle (bookId: BookID): String = + let book = + Library.getBook bookId + getNameFromBook book + +let curiousGeorgeBookId = + 101L +Builtin.printLine getTitle curiousGeorgeBookId + +0L""" \ No newline at end of file From 401854a62d58cfbfac23a397562b7055fe27f6c4 Mon Sep 17 00:00:00 2001 From: Stachu Korick Date: Sat, 20 Apr 2024 12:17:22 -0400 Subject: [PATCH 7/8] minor fixes --- backend/src/LibExecution/ProgramTypes.fs | 8 -------- backend/src/LibExecution/RuntimeTypes.fs | 17 ----------------- backend/src/LibParser/Canvas.fs | 2 ++ 3 files changed, 2 insertions(+), 25 deletions(-) diff --git a/backend/src/LibExecution/ProgramTypes.fs b/backend/src/LibExecution/ProgramTypes.fs index dd04e76edc..6845fff1c7 100644 --- a/backend/src/LibExecution/ProgramTypes.fs +++ b/backend/src/LibExecution/ProgramTypes.fs @@ -723,14 +723,6 @@ module UserType = description : string deprecated : Deprecation } - let fromPackageType (t : PackageType.T) : T = - { tlid = t.tlid - name = - { modules = t.name.modules; name = t.name.name; version = t.name.version } - declaration = t.declaration - description = t.description - deprecated = t.deprecated } - module UserConstant = type T = { tlid : tlid diff --git a/backend/src/LibExecution/RuntimeTypes.fs b/backend/src/LibExecution/RuntimeTypes.fs index f77339f867..af3b7b2353 100644 --- a/backend/src/LibExecution/RuntimeTypes.fs +++ b/backend/src/LibExecution/RuntimeTypes.fs @@ -1326,23 +1326,6 @@ module UserType = type T = { tlid : tlid; name : FQTypeName.UserProgram; declaration : TypeDeclaration.T } - let mapNameFromPackageType (t : FQTypeName.Package) : FQTypeName.UserProgram = - { modules = t.modules; name = t.name; version = t.version } - - let mapFromPackageType (t : PackageType.T) : T = - { tlid = gid () - name = mapNameFromPackageType t.name - declaration = t.declaration } - - let mapMapFromPackageType - (t : Map) - : Map = - t - |> Map.toList - |> List.map (fun (k, v) -> (mapNameFromPackageType k, mapFromPackageType v)) - |> Map - - module UserConstant = type T = { tlid : tlid; name : FQConstantName.UserProgram; body : Const } diff --git a/backend/src/LibParser/Canvas.fs b/backend/src/LibParser/Canvas.fs index 186110d97b..165a6c15dd 100644 --- a/backend/src/LibParser/Canvas.fs +++ b/backend/src/LibParser/Canvas.fs @@ -315,8 +315,10 @@ let parse [ "parsedAsFsharp", parsedAsFSharp ] None // whole file + // To WrittenTypes let module' = parseDecls decls + // To ProgramTypes -- with the 'new stuff' in context let updatedUserStuff : NR.UserStuff = { types = Set.union userStuff.types (module'.types |> List.map _.name |> Set) constants = From 0a7ecf983f944bb9b7a38a3296cd594ab670a68e Mon Sep 17 00:00:00 2001 From: Stachu Korick Date: Sat, 20 Apr 2024 12:55:51 -0400 Subject: [PATCH 8/8] misc name-resolution improvements --- backend/src/BuiltinCliHost/Libs/Cli.fs | 5 +- backend/src/LibParser/Canvas.fs | 44 +-- backend/src/LibParser/NameResolver.fs | 31 +-- backend/src/LibParser/Package.fs | 25 -- backend/src/LibParser/Parser.fs | 13 +- backend/src/LibParser/TestModule.fs | 49 +--- .../LibParser/WrittenTypesToProgramTypes.fs | 252 +++--------------- backend/src/LocalExec/Canvas.fs | 1 - backend/src/LocalExec/LoadPackagesFromDisk.fs | 2 - backend/tests/Tests/BwdServer.Tests.fs | 4 +- backend/tests/Tests/Canvas.Tests.fs | 1 - backend/tests/Tests/Cron.Tests.fs | 1 - backend/tests/Tests/HttpClient.Tests.fs | 1 - backend/tests/Tests/LibExecution.Tests.fs | 1 - backend/tests/Tests/Parser.Tests.fs | 1 - backend/tests/Tests/ProgramTypes.Tests.fs | 11 +- backend/tests/Tests/Queue.Tests.fs | 1 - .../tests/Tests/QueueSchedulingRules.Tests.fs | 1 - backend/tests/Tests/SqlCompiler.Tests.fs | 22 +- 19 files changed, 77 insertions(+), 389 deletions(-) diff --git a/backend/src/BuiltinCliHost/Libs/Cli.fs b/backend/src/BuiltinCliHost/Libs/Cli.fs index fc2bb996fc..c688fb011d 100644 --- a/backend/src/BuiltinCliHost/Libs/Cli.fs +++ b/backend/src/BuiltinCliHost/Libs/Cli.fs @@ -163,9 +163,8 @@ let fns : List = LibParser.Canvas.parse state.builtins state.packageManager - NR.HackPackageStuff.empty (NR.UserStuff.fromProgram state.program) - NR.OnMissing.Allow // Right? kinda surprising. + NR.OnMissing.Allow filename code |> Ply.map Ok @@ -244,7 +243,6 @@ let fns : List = LibParser.NameResolver.resolveFnName (state.builtins.fns |> Map.keys |> Set) state.packageManager - Set.empty (NR.UserStuff.fromProgram state.program).fns NR.OnMissing.Allow // OK? [] @@ -385,7 +383,6 @@ let fns : List = LibParser.NameResolver.resolveFnName (state.builtins.fns |> Map.keys |> Set) state.packageManager - Set.empty (NR.UserStuff.fromProgram state.program).fns NR.OnMissing.Allow // ok? [] diff --git a/backend/src/LibParser/Canvas.fs b/backend/src/LibParser/Canvas.fs index 165a6c15dd..d9901d4f69 100644 --- a/backend/src/LibParser/Canvas.fs +++ b/backend/src/LibParser/Canvas.fs @@ -223,7 +223,6 @@ let parseDecls (decls : List) : WTCanvasModule = let toPT (builtins : RT.Builtins) (pm : RT.PackageManager) - (hackPackageStuff : NR.HackPackageStuff) (userStuff : NR.UserStuff) (onMissing : NR.OnMissing) (m : WTCanvasModule) @@ -231,50 +230,31 @@ let toPT uply { let! types = m.types - |> Ply.List.mapSequentially ( - WT2PT.UserType.toPT pm hackPackageStuff userStuff onMissing m.name - ) + |> Ply.List.mapSequentially (WT2PT.UserType.toPT pm userStuff onMissing m.name) let! fns = m.fns |> Ply.List.mapSequentially ( - WT2PT.UserFunction.toPT - builtins - pm - hackPackageStuff - userStuff - onMissing - m.name + WT2PT.UserFunction.toPT builtins pm userStuff onMissing m.name ) let! constants = m.constants |> Ply.List.mapSequentially ( - WT2PT.UserConstant.toPT pm hackPackageStuff userStuff onMissing m.name + WT2PT.UserConstant.toPT pm userStuff onMissing m.name ) let! dbs = - m.dbs - |> Ply.List.mapSequentially ( - WT2PT.DB.toPT pm hackPackageStuff userStuff onMissing m.name - ) + m.dbs |> Ply.List.mapSequentially (WT2PT.DB.toPT pm userStuff onMissing m.name) let! handlers = m.handlers |> Ply.List.mapSequentially (fun (spec, expr) -> uply { let spec = WT2PT.Handler.Spec.toPT spec - let! expr = - WT2PT.Expr.toPT - builtins - pm - hackPackageStuff - userStuff - onMissing - m.name - expr + let! expr = WT2PT.Expr.toPT builtins pm userStuff onMissing m.name expr return (spec, expr) }) let! exprs = m.exprs |> Ply.List.mapSequentially ( - WT2PT.Expr.toPT builtins pm hackPackageStuff userStuff onMissing m.name + WT2PT.Expr.toPT builtins pm userStuff onMissing m.name ) return @@ -290,7 +270,6 @@ let toPT let parse (builtins : RT.Builtins) (pm : RT.PackageManager) - (hackPackageStuff : NR.HackPackageStuff) (userStuff : NR.UserStuff) (onMissing : NR.OnMissing) (filename : string) @@ -325,23 +304,16 @@ let parse Set.union userStuff.constants (module'.constants |> List.map _.name |> Set) fns = Set.union userStuff.fns (module'.fns |> List.map _.name |> Set) } - toPT - builtins - pm - hackPackageStuff - updatedUserStuff - onMissing // TODO: maybe this should be `OnMissing.Allow` -- the previous code had that... - module' + toPT builtins pm updatedUserStuff onMissing module' let parseFromFile (builtins : RT.Builtins) (pm : RT.PackageManager) - (hackPackageStuff : NR.HackPackageStuff) (userStuff : NR.UserStuff) (onMissing : NR.OnMissing) (filename : string) : Ply = filename |> System.IO.File.ReadAllText - |> parse builtins pm hackPackageStuff userStuff onMissing filename + |> parse builtins pm userStuff onMissing filename diff --git a/backend/src/LibParser/NameResolver.fs b/backend/src/LibParser/NameResolver.fs index 9d2e023a4d..89cd63104e 100644 --- a/backend/src/LibParser/NameResolver.fs +++ b/backend/src/LibParser/NameResolver.fs @@ -10,14 +10,6 @@ module RT = LibExecution.RuntimeTypes module NRE = LibExecution.NameResolutionError -type HackPackageStuff = - { types : Set - constants : Set - fns : Set } - - static member empty = { types = Set.empty; constants = Set.empty; fns = Set.empty } - - type UserStuff = { types : Set constants : Set @@ -98,13 +90,11 @@ let namesToTry let resolveTypeName (packageManager : RT.PackageManager) - (hackPackageTypes : Set) (userTypes : Set) (onMissing : OnMissing) (currentModule : List) (name : WT.Name) : Ply> = - let err errType names : PT.NameResolution = Error { nameType = NRE.Type; errorType = errType; names = names } @@ -122,17 +112,12 @@ let resolveTypeName uply { match! packageManager.getType rtName with | Some _found -> return Ok(PT.FQTypeName.FQTypeName.Package name) - | None -> - if Set.contains rtName hackPackageTypes then - return Ok(PT.FQTypeName.FQTypeName.Package name) - else - return notFoundError + | None -> return notFoundError } let tryResolve (name : GenericName) : Ply> = - // try UserProgram space first, then try package space uply { let (userProgram : PT.FQTypeName.UserProgram) = { modules = name.modules; name = name.name; version = name.version } @@ -180,7 +165,6 @@ let resolveTypeName let resolveConstantName (builtinConstants : Set) (packageManager : RT.PackageManager) - (hackPackageConstants : Set) (userConstants : Set) (onMissing : OnMissing) (currentModule : List) @@ -202,11 +186,7 @@ let resolveConstantName uply { match! packageManager.getConstant rtName with | Some _found -> return Ok(PT.FQConstantName.FQConstantName.Package name) - | None -> - if Set.contains rtName hackPackageConstants then - return Ok(PT.FQConstantName.FQConstantName.Package name) - else - return notFoundError + | None -> return notFoundError } let tryResolve @@ -267,7 +247,6 @@ let resolveConstantName let resolveFnName (builtinFns : Set) (packageManager : RT.PackageManager) - (hackPackageFns : Set) (userFns : Set) (onMissing : OnMissing) (currentModule : List) @@ -288,11 +267,7 @@ let resolveFnName uply { match! packageManager.getFn rtName with | Some _found -> return Ok(PT.FQFnName.FQFnName.Package name) - | None -> - if Set.contains rtName hackPackageFns then - return Ok(PT.FQFnName.FQFnName.Package name) - else - return notFoundError + | None -> return notFoundError } let tryResolve (name : GenericName) : Ply> = diff --git a/backend/src/LibParser/Package.fs b/backend/src/LibParser/Package.fs index afca309c6c..d729e2f010 100644 --- a/backend/src/LibParser/Package.fs +++ b/backend/src/LibParser/Package.fs @@ -100,7 +100,6 @@ let rec parseDecls let parse (builtins : RT.Builtins) (pm : RT.PackageManager) - (hackPackageStuff : NR.HackPackageStuff) (userStuff : NR.UserStuff) (onMissing : NR.OnMissing) (filename : string) @@ -131,34 +130,12 @@ let parse let constantNameToModules (p : PT.FQConstantName.Package) : List = p.owner :: p.modules - // TODO: I'm not sure if we actually need this here? - // we're doing two pases, right, so probably not? - // and if this is the only place we're setting that, then maybe the thing can be removed? idk. - let updatedHackPackageStuff : NR.HackPackageStuff = - let newTypes = - modul.types - |> List.map _.name - |> List.map PT2RT.FQTypeName.Package.toRT - |> Set - let newConstants = - modul.constants - |> List.map _.name - |> List.map PT2RT.FQConstantName.Package.toRT - |> Set - let newFns = - modul.fns |> List.map _.name |> List.map PT2RT.FQFnName.Package.toRT |> Set - - { types = Set.union hackPackageStuff.types newTypes - constants = Set.union hackPackageStuff.constants newConstants - fns = Set.union hackPackageStuff.fns newFns } - let! fns = modul.fns |> Ply.List.mapSequentially (fun fn -> WT2PT.PackageFn.toPT builtins pm - updatedHackPackageStuff userStuff onMissing (fnNameToModules fn.name) @@ -169,7 +146,6 @@ let parse |> Ply.List.mapSequentially (fun typ -> WT2PT.PackageType.toPT pm - hackPackageStuff userStuff onMissing (typeNameToModules typ.name) @@ -180,7 +156,6 @@ let parse |> Ply.List.mapSequentially (fun constant -> WT2PT.PackageConstant.toPT pm - hackPackageStuff userStuff onMissing (constantNameToModules constant.name) diff --git a/backend/src/LibParser/Parser.fs b/backend/src/LibParser/Parser.fs index 495f6c9b36..123fbe7ebc 100644 --- a/backend/src/LibParser/Parser.fs +++ b/backend/src/LibParser/Parser.fs @@ -23,7 +23,6 @@ let initialParse (filename : string) (code : string) : WT.Expr = let parsePTExpr (builtins : RT.Builtins) (pm : RT.PackageManager) - (hackPackageStuff : NR.HackPackageStuff) (userStuff : NR.UserStuff) (onMissing : NR.OnMissing) (filename : string) @@ -31,47 +30,43 @@ let parsePTExpr : Ply = code |> initialParse filename - |> WT2PT.Expr.toPT builtins pm hackPackageStuff userStuff onMissing [] + |> WT2PT.Expr.toPT builtins pm userStuff onMissing [] let parseSimple (builtins : RT.Builtins) (pm : RT.PackageManager) - (hackPackageStuff : NR.HackPackageStuff) (userStuff : NR.UserStuff) (onMissing : NR.OnMissing) (filename : string) (code : string) : Ply = - parsePTExpr builtins pm hackPackageStuff userStuff onMissing filename code + parsePTExpr builtins pm userStuff onMissing filename code let parseRTExpr (builtins : RT.Builtins) (pm : RT.PackageManager) - (hackPackageStuff : NR.HackPackageStuff) (userStuff : NR.UserStuff) (onMissing : NR.OnMissing) (filename : string) (code : string) : Ply = code - |> parsePTExpr builtins pm hackPackageStuff userStuff onMissing filename + |> parsePTExpr builtins pm userStuff onMissing filename |> Ply.map LibExecution.ProgramTypesToRuntimeTypes.Expr.toRT let parsePackageFile (builtins : RT.Builtins) (pm : RT.PackageManager) - (hackPackageStuff : NR.HackPackageStuff) (userStuff : NR.UserStuff) (onMissing : NR.OnMissing) (path : string) (contents : string) : Ply = uply { - let! pModule = - Package.parse builtins pm hackPackageStuff userStuff onMissing path contents + let! pModule = Package.parse builtins pm userStuff onMissing path contents return { types = pModule.types; constants = pModule.constants; fns = pModule.fns } } diff --git a/backend/src/LibParser/TestModule.fs b/backend/src/LibParser/TestModule.fs index 625be2c50d..2eac1e2a63 100644 --- a/backend/src/LibParser/TestModule.fs +++ b/backend/src/LibParser/TestModule.fs @@ -193,7 +193,6 @@ let parseFile (parsedAsFSharp : ParsedImplFileInput) : List = let toPT (builtins : RT.Builtins) (pm : RT.PackageManager) - (hackPackageStuff : NR.HackPackageStuff) (userStuff : NR.UserStuff) (onMissing : NR.OnMissing) (m : WTModule) @@ -202,51 +201,25 @@ let toPT let! fns = m.fns |> Ply.List.mapSequentially ( - WT2PT.UserFunction.toPT - builtins - pm - hackPackageStuff - userStuff - onMissing - m.name + WT2PT.UserFunction.toPT builtins pm userStuff onMissing m.name ) let! types = m.types - |> Ply.List.mapSequentially ( - WT2PT.UserType.toPT pm hackPackageStuff userStuff onMissing m.name - ) + |> Ply.List.mapSequentially (WT2PT.UserType.toPT pm userStuff onMissing m.name) let! constants = m.constants |> Ply.List.mapSequentially ( - WT2PT.UserConstant.toPT pm hackPackageStuff userStuff onMissing m.name + WT2PT.UserConstant.toPT pm userStuff onMissing m.name ) let! dbs = - m.dbs - |> Ply.List.mapSequentially ( - WT2PT.DB.toPT pm hackPackageStuff userStuff onMissing m.name - ) + m.dbs |> Ply.List.mapSequentially (WT2PT.DB.toPT pm userStuff onMissing m.name) let! (tests : List) = m.tests |> Ply.List.mapSequentially (fun test -> uply { - let! actual = - WT2PT.Expr.toPT - builtins - pm - hackPackageStuff - userStuff - onMissing - m.name - test.actual - let! expected = - WT2PT.Expr.toPT - builtins - pm - hackPackageStuff - userStuff - onMissing - m.name - test.expected + let exprToPT = WT2PT.Expr.toPT builtins pm userStuff onMissing m.name + let! actual = exprToPT test.actual + let! expected = exprToPT test.expected return { PTTest.actual = actual expected = expected @@ -271,7 +244,6 @@ let toPT let parseTestFile (builtins : RT.Builtins) (pm : RT.PackageManager) - (hackPackageStuff : NR.HackPackageStuff) (userStuff : NR.UserStuff) (onMissing : NR.OnMissing) (filename : string) @@ -297,9 +269,7 @@ let parseTestFile let! result = modules - |> Ply.List.mapSequentially ( - toPT builtins pm hackPackageStuff updatedUserStuff onMissing - ) + |> Ply.List.mapSequentially (toPT builtins pm updatedUserStuff onMissing) return result } @@ -307,7 +277,6 @@ let parseTestFile let parseSingleTestFromFile (builtins : RT.Builtins) (pm : RT.PackageManager) - (hackPackageStuff : NR.HackPackageStuff) (userStuff : NR.UserStuff) (onMissing : NR.OnMissing) (filename : string) @@ -320,7 +289,7 @@ let parseSingleTestFromFile |> singleExprFromImplFile |> parseTest - let mapExpr = WT2PT.Expr.toPT builtins pm hackPackageStuff userStuff onMissing [] + let mapExpr = WT2PT.Expr.toPT builtins pm userStuff onMissing [] let! actual = wtTest.actual |> mapExpr |> Ply.map PT2RT.Expr.toRT let! expected = wtTest.expected |> mapExpr |> Ply.map PT2RT.Expr.toRT diff --git a/backend/src/LibParser/WrittenTypesToProgramTypes.fs b/backend/src/LibParser/WrittenTypesToProgramTypes.fs index b61693090b..f4a9a94202 100644 --- a/backend/src/LibParser/WrittenTypesToProgramTypes.fs +++ b/backend/src/LibParser/WrittenTypesToProgramTypes.fs @@ -30,13 +30,12 @@ module InfixFnName = module TypeReference = let rec toPT (pm : RT.PackageManager) - (hackPackageStuff : NR.HackPackageStuff) (userStuff : NR.UserStuff) (onMissing : NR.OnMissing) (currentModule : List) (t : WT.TypeReference) : Ply = - let toPT = toPT pm hackPackageStuff userStuff onMissing currentModule + let toPT = toPT pm userStuff onMissing currentModule uply { match t with | WT.TUnit -> return PT.TUnit @@ -68,14 +67,7 @@ module TypeReference = | WT.TDict typ -> return! toPT typ |> Ply.map PT.TDict | WT.TCustomType(t, typeArgs) -> - let! t = - NR.resolveTypeName - pm - hackPackageStuff.types - userStuff.types - onMissing - currentModule - t + let! t = NR.resolveTypeName pm userStuff.types onMissing currentModule t let! typeArgs = Ply.List.mapSequentially toPT typeArgs return PT.TCustomType(t, typeArgs) @@ -139,7 +131,6 @@ module MatchPattern = module Expr = let resolveTypeName (pm : RT.PackageManager) - (hackPackageStuff : NR.HackPackageStuff) (userStuff : NR.UserStuff) (onMissing : NR.OnMissing) (currentModule : List) @@ -157,24 +148,17 @@ module Expr = ) | head :: tail -> let name = NEList.ofList head tail |> WT.Unresolved - NR.resolveTypeName - pm - hackPackageStuff.types - userStuff.types - onMissing - currentModule - name + NR.resolveTypeName pm userStuff.types onMissing currentModule name let rec toPT (builtins : RT.Builtins) (pm : RT.PackageManager) - (hackPackageStuff : NR.HackPackageStuff) (userStuff : NR.UserStuff) (onMissing : NR.OnMissing) (currentModule : List) (e : WT.Expr) : Ply = - let toPT = toPT builtins pm hackPackageStuff userStuff onMissing currentModule + let toPT = toPT builtins pm userStuff onMissing currentModule uply { match e with | WT.EChar(id, char) -> return PT.EChar(id, char) @@ -191,13 +175,7 @@ module Expr = | WT.EString(id, segments) -> let! segments = Ply.List.mapSequentially - (stringSegmentToPT - builtins - pm - hackPackageStuff - userStuff - onMissing - currentModule) + (stringSegmentToPT builtins pm userStuff onMissing currentModule) segments return PT.EString(id, segments) | WT.EFloat(id, sign, whole, fraction) -> @@ -210,7 +188,6 @@ module Expr = NR.resolveConstantName (builtins.constants |> Map.keys |> Set) pm - hackPackageStuff.constants userStuff.constants NR.OnMissing.Allow currentModule @@ -227,7 +204,6 @@ module Expr = NR.resolveFnName (builtins.fns |> Map.keys |> Set) pm - hackPackageStuff.fns userStuff.fns NR.OnMissing.Allow currentModule @@ -239,7 +215,6 @@ module Expr = NR.resolveConstantName (builtins.constants |> Map.keys |> Set) pm - hackPackageStuff.constants userStuff.constants onMissing currentModule @@ -249,7 +224,7 @@ module Expr = let! name = toPT name let! typeArgs = Ply.List.mapSequentially - (TypeReference.toPT pm hackPackageStuff userStuff onMissing currentModule) + (TypeReference.toPT pm userStuff onMissing currentModule) typeArgs let! args = Ply.NEList.mapSequentially toPT args @@ -259,7 +234,6 @@ module Expr = NR.resolveFnName (builtins.fns |> Map.keys |> Set) pm - hackPackageStuff.fns userStuff.fns NR.OnMissing.Allow currentModule @@ -301,13 +275,7 @@ module Expr = return PT.ETuple(id, first, second, theRest) | WT.ERecord(id, typeName, fields) -> let! typeName = - NR.resolveTypeName - pm - hackPackageStuff.types - userStuff.types - onMissing - currentModule - typeName + NR.resolveTypeName pm userStuff.types onMissing currentModule typeName let! fields = Ply.List.mapSequentially (fun (fieldName, fieldExpr) -> @@ -331,25 +299,12 @@ module Expr = let! expr1 = toPT expr1 let! rest = Ply.List.mapSequentially - (pipeExprToPT - builtins - pm - hackPackageStuff - userStuff - onMissing - currentModule) + (pipeExprToPT builtins pm userStuff onMissing currentModule) rest return PT.EPipe(pipeID, expr1, rest) | WT.EEnum(id, typeName, caseName, exprs) -> let! typeName = - resolveTypeName - pm - hackPackageStuff - userStuff - onMissing - currentModule - typeName - caseName + resolveTypeName pm userStuff onMissing currentModule typeName caseName let! exprs = Ply.List.mapSequentially toPT exprs return PT.EEnum(id, typeName, caseName, exprs) | WT.EMatch(id, mexpr, cases) -> @@ -396,7 +351,6 @@ module Expr = and stringSegmentToPT (builtins : RT.Builtins) (pm : RT.PackageManager) - (hackPackageStuff : NR.HackPackageStuff) (userStuff : NR.UserStuff) (onMissing : NR.OnMissing) (currentModule : List) @@ -405,19 +359,18 @@ module Expr = match segment with | WT.StringText text -> Ply(PT.StringText text) | WT.StringInterpolation expr -> - toPT builtins pm hackPackageStuff userStuff onMissing currentModule expr + toPT builtins pm userStuff onMissing currentModule expr |> Ply.map (fun interpolated -> PT.StringInterpolation interpolated) and pipeExprToPT (builtins : RT.Builtins) (pm : RT.PackageManager) - (hackPackageStuff : NR.HackPackageStuff) (userStuff : NR.UserStuff) (onMissing : NR.OnMissing) (currentModule : List) (pipeExpr : WT.PipeExpr) : Ply = - let toPT = toPT builtins pm hackPackageStuff userStuff onMissing currentModule + let toPT = toPT builtins pm userStuff onMissing currentModule uply { match pipeExpr with @@ -427,7 +380,6 @@ module Expr = NR.resolveFnName (builtins.fns |> Map.keys |> Set) pm - hackPackageStuff.fns userStuff.fns NR.OnMissing.Allow currentModule @@ -456,7 +408,6 @@ module Expr = NR.resolveFnName (builtins.fns |> Map.keys |> Set) pm - hackPackageStuff.fns userStuff.fns NR.OnMissing.Allow currentModule @@ -471,28 +422,20 @@ module Expr = NR.resolveFnName (builtins.fns |> Map.keys |> Set) pm - hackPackageStuff.fns userStuff.fns onMissing currentModule name let! typeArgs = Ply.List.mapSequentially - (TypeReference.toPT pm hackPackageStuff userStuff onMissing currentModule) + (TypeReference.toPT pm userStuff onMissing currentModule) typeArgs let! args = Ply.List.mapSequentially toPT args return PT.EPipeFnCall(id, fnName, typeArgs, args) | WT.EPipeEnum(id, typeName, caseName, fields) -> let! typeName = - resolveTypeName - pm - hackPackageStuff - userStuff - onMissing - currentModule - typeName - caseName + resolveTypeName pm userStuff onMissing currentModule typeName caseName let! fields = Ply.List.mapSequentially toPT fields return PT.EPipeEnum(id, typeName, caseName, fields) } @@ -500,13 +443,12 @@ module Expr = module Const = let rec toPT (pm : RT.PackageManager) - (hackPackageStuff : NR.HackPackageStuff) (userStuff : NR.UserStuff) (onMissing : NR.OnMissing) (currentModule : List) (c : WT.Const) : Ply = - let toPT = toPT pm hackPackageStuff userStuff onMissing currentModule + let toPT = toPT pm userStuff onMissing currentModule uply { match c with | WT.CUnit -> return PT.CUnit @@ -548,14 +490,7 @@ module Const = | WT.CEnum(typeName, caseName, fields) -> let! typeName = - Expr.resolveTypeName - pm - hackPackageStuff - userStuff - onMissing - currentModule - typeName - caseName + Expr.resolveTypeName pm userStuff onMissing currentModule typeName caseName let! fields = Ply.List.mapSequentially toPT fields return PT.CEnum(typeName, caseName, fields) } @@ -565,49 +500,32 @@ module TypeDeclaration = module RecordField = let toPT (pm : RT.PackageManager) - (hackPackageStuff : NR.HackPackageStuff) (userStuff : NR.UserStuff) (onMissing : NR.OnMissing) (currentModule : List) (f : WT.TypeDeclaration.RecordField) : Ply = uply { - let! typ = - TypeReference.toPT - pm - hackPackageStuff - userStuff - onMissing - currentModule - f.typ + let! typ = TypeReference.toPT pm userStuff onMissing currentModule f.typ return { name = f.name; typ = typ; description = f.description } } module EnumField = let toPT (pm : RT.PackageManager) - (hackPackageStuff : NR.HackPackageStuff) (userStuff : NR.UserStuff) (onMissing : NR.OnMissing) (currentModule : List) (f : WT.TypeDeclaration.EnumField) : Ply = uply { - let! typ = - TypeReference.toPT - pm - hackPackageStuff - userStuff - onMissing - currentModule - f.typ + let! typ = TypeReference.toPT pm userStuff onMissing currentModule f.typ return { typ = typ; label = f.label; description = f.description } } module EnumCase = let toPT (pm : RT.PackageManager) - (hackPackageStuff : NR.HackPackageStuff) (userStuff : NR.UserStuff) (onMissing : NR.OnMissing) (currentModule : List) @@ -616,7 +534,7 @@ module TypeDeclaration = uply { let! fields = Ply.List.mapSequentially - (EnumField.toPT pm hackPackageStuff userStuff onMissing currentModule) + (EnumField.toPT pm userStuff onMissing currentModule) c.fields return { name = c.name; fields = fields; description = c.description } } @@ -624,7 +542,6 @@ module TypeDeclaration = module Definition = let toPT (pm : RT.PackageManager) - (hackPackageStuff : NR.HackPackageStuff) (userStuff : NR.UserStuff) (onMissing : NR.OnMissing) (currentModule : List) @@ -633,27 +550,20 @@ module TypeDeclaration = uply { match d with | WT.TypeDeclaration.Alias typ -> - let! typ = - TypeReference.toPT - pm - hackPackageStuff - userStuff - onMissing - currentModule - typ + let! typ = TypeReference.toPT pm userStuff onMissing currentModule typ return PT.TypeDeclaration.Alias typ | WT.TypeDeclaration.Record fields -> let! fields = Ply.NEList.mapSequentially - (RecordField.toPT pm hackPackageStuff userStuff onMissing currentModule) + (RecordField.toPT pm userStuff onMissing currentModule) fields return PT.TypeDeclaration.Record fields | WT.TypeDeclaration.Enum cases -> let! cases = Ply.NEList.mapSequentially - (EnumCase.toPT pm hackPackageStuff userStuff onMissing currentModule) + (EnumCase.toPT pm userStuff onMissing currentModule) cases return PT.TypeDeclaration.Enum cases } @@ -661,21 +571,13 @@ module TypeDeclaration = let toPT (pm : RT.PackageManager) - (hackPackageStuff : NR.HackPackageStuff) (userStuff : NR.UserStuff) (onMissing : NR.OnMissing) (currentModule : List) (d : WT.TypeDeclaration.T) : Ply = uply { - let! def = - Definition.toPT - pm - hackPackageStuff - userStuff - onMissing - currentModule - d.definition + let! def = Definition.toPT pm userStuff onMissing currentModule d.definition return { typeParams = d.typeParams; definition = def } } @@ -684,7 +586,6 @@ module TypeDeclaration = module PackageType = let toPT (pm : RT.PackageManager) - (hackPackageStuff : NR.HackPackageStuff) (userStuff : NR.UserStuff) (onMissing : NR.OnMissing) (currentModule : List) @@ -692,13 +593,7 @@ module PackageType = : Ply = uply { let! declaration = - TypeDeclaration.toPT - pm - hackPackageStuff - userStuff - onMissing - currentModule - pt.declaration + TypeDeclaration.toPT pm userStuff onMissing currentModule pt.declaration return { name = pt.name description = pt.description @@ -711,15 +606,13 @@ module PackageType = module PackageConstant = let toPT (pm : RT.PackageManager) - (hackPackageStuff : NR.HackPackageStuff) (userStuff : NR.UserStuff) (onMissing : NR.OnMissing) (currentModule : List) (c : WT.PackageConstant.T) : Ply = uply { - let! body = - Const.toPT pm hackPackageStuff userStuff onMissing currentModule c.body + let! body = Const.toPT pm userStuff onMissing currentModule c.body return { name = c.name description = c.description @@ -734,28 +627,19 @@ module PackageFn = module Parameter = let toPT (pm : RT.PackageManager) - (hackPackageStuff : NR.HackPackageStuff) (userStuff : NR.UserStuff) (onMissing : NR.OnMissing) (currentModule : List) (p : WT.PackageFn.Parameter) : Ply = uply { - let! typ = - TypeReference.toPT - pm - hackPackageStuff - userStuff - onMissing - currentModule - p.typ + let! typ = TypeReference.toPT pm userStuff onMissing currentModule p.typ return { name = p.name; typ = typ; description = p.description } } let toPT (builtins : RT.Builtins) (pm : RT.PackageManager) - (hackPackageStuff : NR.HackPackageStuff) (userStuff : NR.UserStuff) (onMissing : NR.OnMissing) (currentModule : List) @@ -764,25 +648,11 @@ module PackageFn = uply { let! parameters = Ply.NEList.mapSequentially - (Parameter.toPT pm hackPackageStuff userStuff onMissing currentModule) + (Parameter.toPT pm userStuff onMissing currentModule) fn.parameters let! returnType = - TypeReference.toPT - pm - hackPackageStuff - userStuff - onMissing - currentModule - fn.returnType - let! body = - Expr.toPT - builtins - pm - hackPackageStuff - userStuff - onMissing - currentModule - fn.body + TypeReference.toPT pm userStuff onMissing currentModule fn.returnType + let! body = Expr.toPT builtins pm userStuff onMissing currentModule fn.body return { name = fn.name @@ -801,7 +671,6 @@ module PackageFn = module UserType = let toPT (pm : RT.PackageManager) - (hackPackageStuff : NR.HackPackageStuff) (userStuff : NR.UserStuff) (onMissing : NR.OnMissing) (currentModule : List) @@ -809,13 +678,7 @@ module UserType = : Ply = uply { let! declaration = - TypeDeclaration.toPT - pm - hackPackageStuff - userStuff - onMissing - currentModule - t.declaration + TypeDeclaration.toPT pm userStuff onMissing currentModule t.declaration return { tlid = gid () name = t.name @@ -828,15 +691,13 @@ module UserType = module UserConstant = let toPT (pm : RT.PackageManager) - (hackPackageStuff : NR.HackPackageStuff) (userStuff : NR.UserStuff) (onMissing : NR.OnMissing) (currentModule : List) (c : WT.UserConstant.T) : Ply = uply { - let! body = - Const.toPT pm hackPackageStuff userStuff onMissing currentModule c.body + let! body = Const.toPT pm userStuff onMissing currentModule c.body return { tlid = gid () name = c.name @@ -849,21 +710,13 @@ module UserConstant = module DB = let toPT (pm : RT.PackageManager) - (hackPackageStuff : NR.HackPackageStuff) (userStuff : NR.UserStuff) (onMissing : NR.OnMissing) (currentModule : List) (db : WT.DB.T) : Ply = uply { - let! typ = - TypeReference.toPT - pm - hackPackageStuff - userStuff - onMissing - currentModule - db.typ + let! typ = TypeReference.toPT pm userStuff onMissing currentModule db.typ return { tlid = gid (); name = db.name; version = db.version; typ = typ } } @@ -871,28 +724,19 @@ module UserFunction = module Parameter = let toPT (pm : RT.PackageManager) - (hackPackageStuff : NR.HackPackageStuff) (userStuff : NR.UserStuff) (onMissing : NR.OnMissing) (currentModule : List) (p : WT.UserFunction.Parameter) : Ply = uply { - let! typ = - TypeReference.toPT - pm - hackPackageStuff - userStuff - onMissing - currentModule - p.typ + let! typ = TypeReference.toPT pm userStuff onMissing currentModule p.typ return { name = p.name; typ = typ; description = p.description } } let toPT (builtins : RT.Builtins) (pm : RT.PackageManager) - (hackPackageStuff : NR.HackPackageStuff) (userStuff : NR.UserStuff) (onMissing : NR.OnMissing) (currentModule : List) @@ -901,25 +745,12 @@ module UserFunction = uply { let! parameters = Ply.NEList.mapSequentially - (Parameter.toPT pm hackPackageStuff userStuff onMissing currentModule) + (Parameter.toPT pm userStuff onMissing currentModule) f.parameters + let! returnType = - TypeReference.toPT - pm - hackPackageStuff - userStuff - onMissing - currentModule - f.returnType - let! body = - Expr.toPT - builtins - pm - hackPackageStuff - userStuff - onMissing - currentModule - f.body + TypeReference.toPT pm userStuff onMissing currentModule f.returnType + let! body = Expr.toPT builtins pm userStuff onMissing currentModule f.body return { tlid = gid () @@ -956,21 +787,12 @@ module Handler = let toPT (builtins : RT.Builtins) (pm : RT.PackageManager) - (hackPackageStuff : NR.HackPackageStuff) (userStuff : NR.UserStuff) (onMissing : NR.OnMissing) (currentModule : List) (h : WT.Handler.T) : Ply = uply { - let! ast = - Expr.toPT - builtins - pm - hackPackageStuff - userStuff - onMissing - currentModule - h.ast + let! ast = Expr.toPT builtins pm userStuff onMissing currentModule h.ast return { tlid = gid (); ast = ast; spec = Spec.toPT h.spec } } diff --git a/backend/src/LocalExec/Canvas.fs b/backend/src/LocalExec/Canvas.fs index a8b15b419e..f731055a0c 100644 --- a/backend/src/LocalExec/Canvas.fs +++ b/backend/src/LocalExec/Canvas.fs @@ -86,7 +86,6 @@ let loadFromDisk LibParser.Canvas.parseFromFile Builtins.accessibleByCanvas pm - NR.HackPackageStuff.empty NR.UserStuff.empty NR.OnMissing.ThrowError $"{canvasDir}/{config.Main}.dark" diff --git a/backend/src/LocalExec/LoadPackagesFromDisk.fs b/backend/src/LocalExec/LoadPackagesFromDisk.fs index 7fd10ee4f6..08c18dafa4 100644 --- a/backend/src/LocalExec/LoadPackagesFromDisk.fs +++ b/backend/src/LocalExec/LoadPackagesFromDisk.fs @@ -32,7 +32,6 @@ let load (builtins : RT.Builtins) : Ply = LibParser.Parser.parsePackageFile builtins RT.PackageManager.Empty - NR.HackPackageStuff.empty NR.UserStuff.empty NR.OnMissing.Allow path @@ -47,7 +46,6 @@ let load (builtins : RT.Builtins) : Ply = LibParser.Parser.parsePackageFile builtins (inMemPackageManagerFromPackages packages) - NR.HackPackageStuff.empty NR.UserStuff.empty NR.OnMissing.ThrowError path diff --git a/backend/tests/Tests/BwdServer.Tests.fs b/backend/tests/Tests/BwdServer.Tests.fs index adba0c7c4f..61ccea37d8 100644 --- a/backend/tests/Tests/BwdServer.Tests.fs +++ b/backend/tests/Tests/BwdServer.Tests.fs @@ -49,7 +49,6 @@ let parse code = LibParser.Parser.parsePTExpr localBuiltIns packageManager - NR.HackPackageStuff.empty NR.UserStuff.empty NR.OnMissing.ThrowError "BwdServer.Tests.fs" @@ -206,8 +205,7 @@ let setupTestCanvas (testName : string) (test : Test) : Task test.handlers |> Ply.List.mapSequentially (fun handler -> uply { - let! source = - parse handler.code + let! source = parse handler.code let spec = match handler.version with diff --git a/backend/tests/Tests/Canvas.Tests.fs b/backend/tests/Tests/Canvas.Tests.fs index 3608a02d4e..abc6f2bb8b 100644 --- a/backend/tests/Tests/Canvas.Tests.fs +++ b/backend/tests/Tests/Canvas.Tests.fs @@ -23,7 +23,6 @@ let parse (code : string) : Task = LibParser.Parser.parseSimple localBuiltIns packageManager - NR.HackPackageStuff.empty NR.UserStuff.empty NR.OnMissing.ThrowError "tests.canvas.fs" diff --git a/backend/tests/Tests/Cron.Tests.fs b/backend/tests/Tests/Cron.Tests.fs index 240cd8efaf..b1d336037b 100644 --- a/backend/tests/Tests/Cron.Tests.fs +++ b/backend/tests/Tests/Cron.Tests.fs @@ -19,7 +19,6 @@ let p (code : string) : Task = LibParser.Parser.parseSimple localBuiltIns packageManager - NR.HackPackageStuff.empty NR.UserStuff.empty NR.OnMissing.ThrowError "cron.tests.fs" diff --git a/backend/tests/Tests/HttpClient.Tests.fs b/backend/tests/Tests/HttpClient.Tests.fs index 60dd6d602c..04eeed277b 100644 --- a/backend/tests/Tests/HttpClient.Tests.fs +++ b/backend/tests/Tests/HttpClient.Tests.fs @@ -90,7 +90,6 @@ let parseTest test = LibParser.TestModule.parseSingleTestFromFile localBuiltIns packageManager - NR.HackPackageStuff.empty NR.UserStuff.empty NR.OnMissing.ThrowError test diff --git a/backend/tests/Tests/LibExecution.Tests.fs b/backend/tests/Tests/LibExecution.Tests.fs index 8cf756f44e..5dbd6caf60 100644 --- a/backend/tests/Tests/LibExecution.Tests.fs +++ b/backend/tests/Tests/LibExecution.Tests.fs @@ -244,7 +244,6 @@ let fileTests () : Test = LibParser.TestModule.parseTestFile localBuiltIns packageManager - NR.HackPackageStuff.empty NR.UserStuff.empty NR.OnMissing.Allow fileName diff --git a/backend/tests/Tests/Parser.Tests.fs b/backend/tests/Tests/Parser.Tests.fs index df0c1281c5..d561509a0a 100644 --- a/backend/tests/Tests/Parser.Tests.fs +++ b/backend/tests/Tests/Parser.Tests.fs @@ -19,7 +19,6 @@ let exprRTs = LibParser.Parser.parseRTExpr localBuiltIns packageManager - NR.HackPackageStuff.empty NR.UserStuff.empty NR.OnMissing.Allow "parser.tests.fs" diff --git a/backend/tests/Tests/ProgramTypes.Tests.fs b/backend/tests/Tests/ProgramTypes.Tests.fs index dad115fb54..5e7d5551f8 100644 --- a/backend/tests/Tests/ProgramTypes.Tests.fs +++ b/backend/tests/Tests/ProgramTypes.Tests.fs @@ -25,12 +25,11 @@ let testPipesToRuntimeTypes = let! actual = "value.age |> (-) 2L |> (+) value.age |> (<) 3L" |> LibParser.Parser.parseRTExpr - localBuiltIns - packageManager - NR.HackPackageStuff.empty - NR.UserStuff.empty - NR.OnMissing.ThrowError - "programTypes.tests.fs" + localBuiltIns + packageManager + NR.UserStuff.empty + NR.OnMissing.ThrowError + "programTypes.tests.fs" |> Ply.toTask let expected = diff --git a/backend/tests/Tests/Queue.Tests.fs b/backend/tests/Tests/Queue.Tests.fs index 6578d57f4f..ebd38c3195 100644 --- a/backend/tests/Tests/Queue.Tests.fs +++ b/backend/tests/Tests/Queue.Tests.fs @@ -29,7 +29,6 @@ let p (code : string) : Task = LibParser.Parser.parsePTExpr localBuiltIns packageManager - NR.HackPackageStuff.empty NR.UserStuff.empty NR.OnMissing.ThrowError "Queue.Tests.fs" diff --git a/backend/tests/Tests/QueueSchedulingRules.Tests.fs b/backend/tests/Tests/QueueSchedulingRules.Tests.fs index e8033c30ff..53166dedb3 100644 --- a/backend/tests/Tests/QueueSchedulingRules.Tests.fs +++ b/backend/tests/Tests/QueueSchedulingRules.Tests.fs @@ -21,7 +21,6 @@ let p (code : string) : Task = LibParser.Parser.parsePTExpr localBuiltIns packageManager - NR.HackPackageStuff.empty NR.UserStuff.empty NR.OnMissing.ThrowError "queueschedulingrules.fs" diff --git a/backend/tests/Tests/SqlCompiler.Tests.fs b/backend/tests/Tests/SqlCompiler.Tests.fs index 87fd3d12ed..7b347b5013 100644 --- a/backend/tests/Tests/SqlCompiler.Tests.fs +++ b/backend/tests/Tests/SqlCompiler.Tests.fs @@ -19,24 +19,20 @@ let p (code : string) : Task = LibParser.Parser.parseRTExpr localBuiltIns packageManager - NR.HackPackageStuff.empty NR.UserStuff.empty NR.OnMissing.ThrowError "sqlcompiler.tests.fs" code |> Ply.toTask -let parse - (userFns: List) - (code : string) - : Task = +let parse (userFns : List) (code : string) : Task = LibParser.Parser.parseRTExpr localBuiltIns packageManager - NR.HackPackageStuff.empty { NR.UserStuff.empty with fns = Set userFns } NR.OnMissing.ThrowError - "sqlcompiler.tests.fs" code + "sqlcompiler.tests.fs" + code |> Ply.toTask let compile @@ -167,8 +163,7 @@ let inlineWorksAtRoot = Map.empty Map.empty let fns = ExecutionState.availableFunctions state - let! expr = - p "let y = 5 in let x = 6 in (3 + (let x = 7 in y))" + let! expr = p "let y = 5 in let x = 6 in (3 + (let x = 7 in y))" let! expected = p "3 + 5" let! result = (C.inline' fns "value" Map.empty expr) |> Ply.toTask @@ -268,7 +263,7 @@ let inlineWorksWithUserFunctions = let! expr = parse - [PT.FQFnName.userProgram [] "userAdd" 0] + [ PT.FQFnName.userProgram [] "userAdd" 0 ] "let a = 1 in let b = 9 in let c = userAdd 6 4 in (p.height == c) && (p.age == b)" let! expected = p "p.height == (6 + 4) && p.age == 9" @@ -309,7 +304,7 @@ let inlineWorksWithPackageAndUserFunctions = let! expr = parse - [PT.FQFnName.userProgram [] "userAnd" 0] + [ PT.FQFnName.userProgram [] "userAnd" 0 ] "userAnd user.human (PACKAGE.Darklang.Stdlib.Int64.lessThan_v0 user.height (PACKAGE.Darklang.Stdlib.Int64.add height 1))" let! expected = p "user.human && (user.height < (height + 1))" @@ -346,9 +341,10 @@ let inlineFunctionArguments = Map.add userAdd.name userAdd existingFunctions.userProgram let fns = { existingFunctions with userProgram = updatedUserProgram } - let userFns = [PT.FQFnName.userProgram [] "userAdd" 0] + let userFns = [ PT.FQFnName.userProgram [] "userAdd" 0 ] - let! expr = parse userFns "let a = 1 in let b = 9 in (p.height == userAdd 6 (b - 4))" + let! expr = + parse userFns "let a = 1 in let b = 9 in (p.height == userAdd 6 (b - 4))" let! expected = parse userFns "p.height == 6 + (9 - 4)" let! result = (C.inline' fns "value" Map.empty expr) |> Ply.toTask