diff --git a/backend/src/BuiltinCli/Libs/Output.fs b/backend/src/BuiltinCli/Libs/Output.fs index 6c0c5e73cf..a6f8ebcc37 100644 --- a/backend/src/BuiltinCli/Libs/Output.fs +++ b/backend/src/BuiltinCli/Libs/Output.fs @@ -42,24 +42,6 @@ let fns : List = | _ -> incorrectArgs ()) sqlSpec = NotQueryable previewable = Impure - deprecated = NotDeprecated } - - - { name = fn "debug" 0 - typeParams = [] - parameters = - [ Param.make "value" (TVariable "a") "The value to be printed." - Param.make "label" TString "The label to be printed." ] - returnType = TVariable "a" - description = "Prints the given to the standard output" - fn = - (function - | _, _, [ value; DString label ] -> - print $"DEBUG: {label} - {value}" - Ply value - | _ -> incorrectArgs ()) - sqlSpec = NotQueryable - previewable = Impure deprecated = NotDeprecated } ] diff --git a/backend/src/BuiltinExecution/Libs/LanguageTools.fs b/backend/src/BuiltinExecution/Libs/LanguageTools.fs index 0432ae693a..e93ce120e2 100644 --- a/backend/src/BuiltinExecution/Libs/LanguageTools.fs +++ b/backend/src/BuiltinExecution/Libs/LanguageTools.fs @@ -19,8 +19,39 @@ let typ FQTypeName.fqPackage "Darklang" ([ "LanguageTools" ] @ addlModules) name version +let typeNameToStr = DvalReprDeveloper.typeName + let fns : List = - [ { name = fn "languageToolsAllBuiltinFns" 0 + [ { name = fn "languageToolsAllBuiltinConstants" 0 + typeParams = [] + parameters = [ Param.make "unit" TUnit "" ] + returnType = TList(TCustomType(Ok(typ [] "BuiltinConstant" 0), [])) + description = + "Returns a list of the Builtin constants (usually not to be accessed directly)." + fn = + (function + | state, _, [ DUnit ] -> + let constTypeName = typ [] "BuiltinConstant" 0 + + let consts = + state.builtins.constants + |> Map.toList + |> List.map (fun (key, data) -> + let fields = + [ "name", DString(FQConstantName.builtinToString key) + "description", DString data.description + "returnType", DString(typeNameToStr data.typ) ] + + DRecord(constTypeName, constTypeName, [], Map fields)) + + DList(VT.customType constTypeName [], consts) |> Ply + | _ -> incorrectArgs ()) + sqlSpec = NotQueryable + previewable = Impure + deprecated = NotDeprecated } + + + { name = fn "languageToolsAllBuiltinFns" 0 typeParams = [] parameters = [ Param.make "unit" TUnit "" ] returnType = TList(TCustomType(Ok(typ [] "BuiltinFunction" 0), [])) @@ -29,7 +60,6 @@ let fns : List = fn = (function | state, _, [ DUnit ] -> - let typeNameToStr = LibExecution.DvalReprDeveloper.typeName let fnParamTypeName = typ [] "BuiltinFunctionParameter" 0 let fnTypeName = typ [] "BuiltinFunction" 0 diff --git a/backend/src/BuiltinExecution/Libs/NoModule.fs b/backend/src/BuiltinExecution/Libs/NoModule.fs index a89b58b66b..eca6782a87 100644 --- a/backend/src/BuiltinExecution/Libs/NoModule.fs +++ b/backend/src/BuiltinExecution/Libs/NoModule.fs @@ -423,7 +423,26 @@ let fns : List = sqlSpec = NotQueryable previewable = Pure - deprecated = NotDeprecated } ] + deprecated = NotDeprecated } + + + { name = fn "debug" 0 + typeParams = [] + parameters = + [ Param.make "label" TString "The label to be printed." + Param.make "value" (TVariable "a") "The value to be printed." ] + returnType = TUnit + description = "Prints the given to the standard output" + fn = + (function + | _, _, [ DString label; value ] -> + // TODO: call upon the Dark equivalent fn instead of rlying on DvalReprDeveloper + print $"DEBUG: {label} - {DvalReprDeveloper.toRepr value}" + Ply DUnit + | _ -> incorrectArgs ()) + sqlSpec = NotQueryable + previewable = Impure + deprecated = NotDeprecated }] let builtins = LibExecution.Builtin.make [] fns diff --git a/backend/src/LibExecution/RuntimeTypes.fs b/backend/src/LibExecution/RuntimeTypes.fs index c2c81a6a3b..7c91b3a1e1 100644 --- a/backend/src/LibExecution/RuntimeTypes.fs +++ b/backend/src/LibExecution/RuntimeTypes.fs @@ -94,7 +94,6 @@ module FQTypeName = let packageToString (s : Package) : string = - debuG "here" s let name = ("PACKAGE" :: s.owner :: s.modules @ [ s.name ]) |> String.concat "." if s.version = 0 then name else $"{name}_v{s.version}" diff --git a/backend/src/LibParser/Canvas.fs b/backend/src/LibParser/Canvas.fs index 45c7f9d03a..49a14bff5e 100644 --- a/backend/src/LibParser/Canvas.fs +++ b/backend/src/LibParser/Canvas.fs @@ -17,7 +17,8 @@ open Utils open ParserException type WTCanvasModule = - { name : List + { owner: string + name : List types : List constants : List dbs : List @@ -26,8 +27,9 @@ type WTCanvasModule = handlers : List exprs : List } -let emptyRootWTModule canvasName = - { name = ["Canvas"; canvasName] +let emptyRootWTModule owner canvasName = + { owner = owner + name = [ "Canvas"; canvasName ] types = [] constants = [] dbs = [] @@ -87,7 +89,6 @@ let (|SimpleAttribute|_|) (attr : SynAttribute) = /// 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 - (owner : string) (m : WTCanvasModule) (letBinding : SynBinding) : WTCanvasModule = @@ -109,7 +110,7 @@ let parseLetBinding WT.ELet(gid (), FS2WT.LetPattern.fromSynPat pat, expr, WT.EUnit(gid ())) { m with exprs = m.exprs @ [ newExpr ] } | Some _ -> - let newFn = FS2WT.PackageFn.fromSynBinding owner m.name letBinding + let newFn = FS2WT.PackageFn.fromSynBinding m.owner m.name letBinding { m with fns = newFn :: m.fns } | [ attr ] -> @@ -174,7 +175,6 @@ module UserDB = (Some typeDef.Range) let parseTypeDefn - (owner : string) (m : WTCanvasModule) (typeDefn : SynTypeDefn) : WTCanvasModule = @@ -190,7 +190,7 @@ let parseTypeDefn if isDB then [ UserDB.fromSynTypeDefn typeDefn ], [] else - [], [ FS2WT.PackageType.fromSynTypeDefn owner m.name typeDefn ] + [], [ FS2WT.PackageType.fromSynTypeDefn m.owner m.name typeDefn ] { m with types = m.types @ newTypes; dbs = m.dbs @ newDBs } @@ -210,15 +210,19 @@ let parseTypeDefn /// or as DBs (i.e. with `[] DBName = Type`) /// - ? expressions are parsed as init commands (not currently supported) /// - anything else fails -let parseDecls (owner : string) (canvasName: string) (decls : List) : WTCanvasModule = +let parseDecls + (owner : string) + (canvasName : string) + (decls : List) + : WTCanvasModule = List.fold (fun m decl -> match decl with | SynModuleDecl.Let(_, bindings, _) -> - List.fold (fun m b -> parseLetBinding owner m b) m bindings + List.fold (fun m b -> parseLetBinding m b) m bindings | SynModuleDecl.Types(defns, _) -> - List.fold (fun m d -> parseTypeDefn owner m d) m defns + List.fold (fun m d -> parseTypeDefn m d) m defns | SynModuleDecl.Expr(expr, _) -> { m with exprs = m.exprs @ [ FS2WT.Expr.fromSynExpr expr ] } @@ -228,7 +232,7 @@ let parseDecls (owner : string) (canvasName: string) (decls : List Ply.List.mapSequentially (WT2PT.PackageType.toPT pm onMissing m.name) + |> Ply.List.mapSequentially (WT2PT.PackageType.toPT pm onMissing (m.owner :: m.name)) let! constants = m.constants - |> Ply.List.mapSequentially (WT2PT.PackageConstant.toPT pm onMissing m.name) + |> Ply.List.mapSequentially (WT2PT.PackageConstant.toPT pm onMissing (m.owner :: m.name)) - let! dbs = m.dbs |> Ply.List.mapSequentially (WT2PT.DB.toPT pm onMissing m.name) + let! dbs = m.dbs |> Ply.List.mapSequentially (WT2PT.DB.toPT pm onMissing (m.owner :: m.name)) let! fns = m.fns - |> Ply.List.mapSequentially (WT2PT.PackageFn.toPT builtins pm onMissing m.name) + |> Ply.List.mapSequentially (WT2PT.PackageFn.toPT builtins pm onMissing (m.owner :: 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 onMissing m.name expr + let! expr = WT2PT.Expr.toPT builtins pm onMissing (m.owner :: m.name) expr return (spec, expr) }) let! exprs = m.exprs - |> Ply.List.mapSequentially (WT2PT.Expr.toPT builtins pm onMissing m.name) + |> Ply.List.mapSequentially (WT2PT.Expr.toPT builtins pm onMissing (m.owner :: m.name)) return { types = types @@ -278,12 +282,12 @@ let toPT let parse (owner : string) - (canvasName: string) + (canvasName : string) (builtins : RT.Builtins) (pm : RT.PackageManager) (onMissing : NR.OnMissing) (filename : string) - (source: string) + (source : string) : Ply = uply { @@ -320,5 +324,7 @@ let parse (result.fns |> List.map PT2RT.PackageFn.toRT) // Now, parse again, but with the names in context (so fewer are marked as unresolved) - return! toPT builtins pm onMissing moduleWT + let! result = toPT builtins pm onMissing moduleWT + + return result } diff --git a/backend/src/LibParser/NameResolver.fs b/backend/src/LibParser/NameResolver.fs index fe61094273..d27014c2ab 100644 --- a/backend/src/LibParser/NameResolver.fs +++ b/backend/src/LibParser/NameResolver.fs @@ -53,6 +53,9 @@ type GenericName = { modules : List; name : string; version : int } /// - Darklang.Option.Option /// - Option.Option /// , in that order (most specific first). +/// +/// TODO?: accept an Option of the _owner_ as well. +/// I think that'll be useful in many contexts to help resolve names... let namesToTry (currentModule : List) (given : GenericName) diff --git a/backend/src/LibParser/Package.fs b/backend/src/LibParser/Package.fs index 102179eb93..cd99c304b4 100644 --- a/backend/src/LibParser/Package.fs +++ b/backend/src/LibParser/Package.fs @@ -92,7 +92,8 @@ let rec parseDecls constants = m.constants @ nestedDecls.constants } - | _ -> Exception.raiseInternal $"Unsupported declaration" [ "decl", decl ]) + | _ -> + Exception.raiseInternal $"Unsupported declaration" [ "decl", decl ]) emptyWTModule decls diff --git a/backend/src/LocalExec/LoadPackagesFromDisk.fs b/backend/src/LocalExec/LoadPackagesFromDisk.fs index 6016186e93..cff35f99f1 100644 --- a/backend/src/LocalExec/LoadPackagesFromDisk.fs +++ b/backend/src/LocalExec/LoadPackagesFromDisk.fs @@ -29,6 +29,7 @@ let load (builtins : RT.Builtins) : Ply = filesWithContents // TODO: parallelize |> Ply.List.mapSequentially (fun (path, contents) -> + //debuG "parsing" path LibParser.Parser.parsePackageFile builtins RT.PackageManager.empty diff --git a/backend/testfiles/execution/stdlib/list.dark b/backend/testfiles/execution/stdlib/list.dark index 3a1cb9e6f0..c7cf26b388 100644 --- a/backend/testfiles/execution/stdlib/list.dark +++ b/backend/testfiles/execution/stdlib/list.dark @@ -502,4 +502,10 @@ Stdlib.List.chunkBySize_v0 [ 1L; 2L; 3L; 4L ] 0L = Stdlib.Result.Result.Error Stdlib.List.ChunkBySizeError.SizeMustBeGreaterThanZero Stdlib.List.chunkBySize_v0 [ 1L; 2L; 3L; 4L ] -1L = Stdlib.Result.Result.Error - Stdlib.List.ChunkBySizeError.SizeMustBeGreaterThanZero \ No newline at end of file + Stdlib.List.ChunkBySizeError.SizeMustBeGreaterThanZero + + +Stdlib.List.splitLast [] = Stdlib.Option.Option.None +Stdlib.List.splitLast [ 1L ] = Stdlib.Option.Option.Some (([], 1L)) +Stdlib.List.splitLast [ 1L; 2L ] = Stdlib.Option.Option.Some (([ 1L ], 2L)) +Stdlib.List.splitLast [ 1L; 2L; 3L ] = Stdlib.Option.Option.Some (([ 1L; 2L ], 3L)) \ No newline at end of file diff --git a/backend/testfiles/execution/stdlib/parser.dark b/backend/testfiles/execution/stdlib/parser.dark index d3dd4c466b..8c655207dd 100644 --- a/backend/testfiles/execution/stdlib/parser.dark +++ b/backend/testfiles/execution/stdlib/parser.dark @@ -155,6 +155,11 @@ module TextToTextRoundtripping = let prettyPrintCliScript (parsedFile: PACKAGE.Darklang.LanguageTools.WrittenTypes.ParsedFile) : String = + let owner = "Tests" + let modules = [] + + let onMissing = PACKAGE.Darklang.LanguageTools.NameResolver.OnMissing.Allow + let script = match parsedFile with | CliScript script -> script @@ -164,19 +169,23 @@ module TextToTextRoundtripping = match typeOrFn with | Type typeDecl -> let prettyPrinted = - (PACKAGE.Darklang.LanguageTools.NameResolver.empty ()) - |> PACKAGE.Darklang.LanguageTools.WrittenTypesToProgramTypes.TypeDeclaration.toUserTypePT - typeDecl - |> PACKAGE.Darklang.PrettyPrinter.ProgramTypes.userType + (PACKAGE.Darklang.LanguageTools.WrittenTypesToProgramTypes.TypeDeclaration.toPackageTypePT + onMissing + owner + modules + typeDecl) + |> PACKAGE.Darklang.PrettyPrinter.ProgramTypes.packageType acc |> Stdlib.List.push prettyPrinted | Function fnDecl -> let prettyPrinted = - (PACKAGE.Darklang.LanguageTools.NameResolver.empty ()) - |> PACKAGE.Darklang.LanguageTools.WrittenTypesToProgramTypes.FunctionDeclaration.toUserFnPT - fnDecl - |> PACKAGE.Darklang.PrettyPrinter.ProgramTypes.userFunction + (PACKAGE.Darklang.LanguageTools.WrittenTypesToProgramTypes.FunctionDeclaration.toPackageFnPT + onMissing + owner + modules + fnDecl) + |> PACKAGE.Darklang.PrettyPrinter.ProgramTypes.packageFn acc |> Stdlib.List.push prettyPrinted)) |> Stdlib.List.reverse @@ -184,9 +193,9 @@ module TextToTextRoundtripping = let exprsPart = // List (Stdlib.List.fold script.exprsToEval [] (fun acc expr -> let prettyPrinted = - (PACKAGE.Darklang.LanguageTools.NameResolver.empty ()) - |> PACKAGE.Darklang.LanguageTools.WrittenTypesToProgramTypes.Expr.toPT - expr + (PACKAGE.Darklang.LanguageTools.WrittenTypesToProgramTypes.Expr.toPT + onMissing + expr) |> PACKAGE.Darklang.PrettyPrinter.ProgramTypes.expr acc |> Stdlib.List.push prettyPrinted)) @@ -206,121 +215,121 @@ 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)" + // 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" + ("type MyOption = Stdlib.Option.Option" |> roundtripCliScript) = "type MyOption =\n PACKAGE.Darklang.Stdlib.Option.Option" + + + 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\" }" @@ -330,147 +339,147 @@ module TextToTextRoundtripping = // ("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" + // 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 true false" + ("(Stdlib.Bool.and true false)" |> roundtripCliScript) = "PACKAGE.Darklang.Stdlib.Bool.and 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) : Int64 = i + i" + |> roundtripCliScript) = "let double2 (i: PACKAGE.Darklang.LanguageTools.ID): 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 a b)" + |> roundtripCliScript) = "let isHigher (a: Int64) (b: Int64): Bool =\n PACKAGE.Darklang.Stdlib.Int64.greaterThan 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 a b" diff --git a/backend/testfiles/execution/stdlib/string.dark b/backend/testfiles/execution/stdlib/string.dark index 88f2ad252d..3bccda1d31 100644 --- a/backend/testfiles/execution/stdlib/string.dark +++ b/backend/testfiles/execution/stdlib/string.dark @@ -506,6 +506,7 @@ module ToList = module Split = + Stdlib.String.split "hello world" "notfound" = [ "hello world" ] Stdlib.String.split "hello😄world" "😄" = [ "hello"; "world" ] Stdlib.String.split "hello&&&&world" "&&&&" = [ "hello"; "world" ] Stdlib.String.split "hello34564world34564sun" "😄" = [ "hello34564world34564sun" ] diff --git a/backend/tests/Tests/Parser.Tests.fs b/backend/tests/Tests/Parser.Tests.fs index d213c7d0e4..1d168f0b9b 100644 --- a/backend/tests/Tests/Parser.Tests.fs +++ b/backend/tests/Tests/Parser.Tests.fs @@ -12,6 +12,7 @@ module PT2RT = LibExecution.ProgramTypesToRuntimeTypes module NR = LibParser.NameResolver let id = 0UL // since we're ignoring IDs, just use the same one everywhere + let exprRTs = let t name testStr expectedExpr = testTask name { @@ -29,7 +30,7 @@ let exprRTs = testList - "Parser tests" + "Exprs" // TODO: order these by simplicity, and add more tests [ // First, let's start with some simple ones @@ -118,6 +119,31 @@ let exprRTs = ) )) ] -//let canvases +let packageFiles = + let t name testStr expected = + testTask name { + let! actual = + LibParser.Parser.parsePackageFile + localBuiltIns + packageManager + NR.OnMissing.Allow + "parser.tests.fs" + testStr + |> Ply.toTask + + return Expect.equal actual expected name + } + + + testList + "Packages" + // TODO: order these by simplicity, and add more tests + [ + // First, let's start with some simple ones + // that don't have any dependencies. + t + "nested module" + "module A.B.C\ntype MyType = Int64" + { types = []; constants = []; fns = [] } ] -let tests = testList "Parser" [ exprRTs ] +let tests = testList "Parser" [ exprRTs; packageFiles ] diff --git a/packages/darklang/cli/cli.dark b/packages/darklang/cli/cli.dark index 8d5a885f0e..cdd484fff7 100644 --- a/packages/darklang/cli/cli.dark +++ b/packages/darklang/cli/cli.dark @@ -61,7 +61,7 @@ module Darklang = (args: List) : Int64 = if Stdlib.List.member_v0 flags "wip-parser" then - let nameResolver = LanguageTools.NameResolver.empty () + let onMissing = LanguageTools.NameResolver.OnMissing.Allow let args = args @@ -75,7 +75,7 @@ module Darklang = | CliScript script -> script.exprsToEval) |> Stdlib.List.flatten |> Stdlib.List.map (fun arg -> - LanguageTools.WrittenTypesToProgramTypes.Expr.toPT nameResolver arg) + LanguageTools.WrittenTypesToProgramTypes.Expr.toPT onMissing arg) match Builtin.cliExecuteFunctionWithNewParser fnName args with | Ok result -> diff --git a/packages/darklang/dark-packages.dark b/packages/darklang/dark-packages.dark index f486c78eb7..61ffef5f36 100644 --- a/packages/darklang/dark-packages.dark +++ b/packages/darklang/dark-packages.dark @@ -26,16 +26,10 @@ module Darklang = let parseVersion (name: String) : (String * Int64) = - let parts = Stdlib.String.split name "_v" - let name = (Stdlib.List.head parts) |> Builtin.unwrap - - let version = - (Stdlib.List.last parts) - |> Builtin.unwrap - |> Builtin.int64Parse - |> Builtin.unwrap - - (name, version) + match Stdlib.String.split name "_v" with + | [ name ] -> (name, 0L) + | [ name; version ] -> + (name, version |> Builtin.int64Parse |> Builtin.unwrap)) let parseName (name: String) : GenericName = diff --git a/packages/darklang/internal.dark b/packages/darklang/internal.dark index 8559674c97..06c0b9679e 100644 --- a/packages/darklang/internal.dark +++ b/packages/darklang/internal.dark @@ -19,11 +19,8 @@ module Darklang = /// A program on a canvas type Program = { id: Uuid - types: List - fns: List // TODO: - //constants: List //dbs: List //httpHandlers: List } diff --git a/packages/darklang/languageTools/common.dark b/packages/darklang/languageTools/common.dark index c09d7f2e8b..c138337c52 100644 --- a/packages/darklang/languageTools/common.dark +++ b/packages/darklang/languageTools/common.dark @@ -16,4 +16,10 @@ module Darklang = { name: String description: String parameters: List - returnType: String } \ No newline at end of file + returnType: String } + + /// A Darklang builtin constant + type BuiltinConstant = + { name: String + description: String + ``type``: String } \ No newline at end of file diff --git a/packages/darklang/languageTools/nameResolver.dark b/packages/darklang/languageTools/nameResolver.dark index 5f3cafa5dc..8ca60ca7b5 100644 --- a/packages/darklang/languageTools/nameResolver.dark +++ b/packages/darklang/languageTools/nameResolver.dark @@ -1,407 +1,323 @@ -// CLEANUP : there is room for refactoring here to reduce duplicated code module Darklang = module LanguageTools = module NameResolver = - type NameResolutionSettings = { allowError: Bool } - - - let empty () : NameResolver.NameResolutionSettings = - NameResolver.NameResolutionSettings { allowError = true } - + /// If a name is not found, should we raise an error? + /// + /// sometimes when parsing, we're not sure whether something is: + /// - a variable + /// - or something else, like a constant or fn. + /// During these times, and others, we wantto allow errors, 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) + (result: ProgramTypes.NameResolution<'a>) + : ProgramTypes.NameResolution<'a> = + result + |> Stdlib.Result.mapError (fun err -> + match onMissing with + | ThrowError -> err // TODO: something + | Allow -> err) + + + type GenericName = + { modules: List + name: String + version: Int64 } + + /// 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 - (given: List) - (modules: List) - : List> = - match modules with - | [] -> [ given ] - | _ -> - let rest = Stdlib.List.dropLast modules - let current = Stdlib.List.append modules given - Stdlib.List.append [ current ] (namesToTry given rest) - + (currentModule: List) + (given: GenericName) + : List = + let addl = + match given.modules with + | "Stdlib" :: _ -> + [ { given with + modules = Stdlib.List.append [ "Darklang" ] given.modules } ] + | "PACKAGE" :: owner :: modules -> + [ { given with + modules = Stdlib.List.append [ owner ] modules } ] + | _ -> [] + + Stdlib.List.append (namesToTryHelper currentModule given) addl + + // TODO we can do this without a helper function, + // by removing the recursion and using a fold. + let namesToTryHelper + (modulesToPrepend: List) + (given: GenericName) + : List = + match Stdlib.List.splitLast modulesToPrepend with + | None -> [ given ] + | Some(allButLast, _last) -> + let newNameToTry = + { given with + modules = Stdlib.List.append modulesToPrepend given.modules } + + Stdlib.List.append [ newNameToTry ] (namesToTryHelper allButLast) module TypeName = - - // TODO: rename this - let resolveNameTypeName - (parser: String -> Stdlib.Result.Result) + let err + (errType: RuntimeErrors.NameResolution.ErrorType) (names: List) - (packageThingExists: String -> Bool) - (nameErrorType: LanguageTools.RuntimeErrors.NameResolution.NameType) - : LanguageTools.ProgramTypes.NameResolution = - let modules = Stdlib.List.dropLast names - let name = Stdlib.List.last names + : ProgramTypes.NameResolution = + (LanguageTools.RuntimeErrors.NameResolution.Error + { nameType = LanguageTools.RuntimeErrors.NameResolution.NameType.Type + errorType = + LanguageTools.RuntimeErrors.NameResolution.ErrorType.InvalidPackageName + names = names }) + |> Stdlib.Result.Result.Error + + + let tryResolve + (name: GenericName) + : Stdlib.Result.Result = + match name.modules with + | [] -> Stdlib.Result.Result.Error() + | owner :: modules -> + let nameForLookup = + (Stdlib.List.flatten [ name.modules; [ name.name ] ]) + |> Stdlib.String.join "." + + match PackageManager.Type.byName nameForLookup with + | Ok _found -> + (ProgramTypes.FQTypeName.Package + { owner = owner + modules = modules + name = name.name + version = name.version }) + |> ProgramTypes.FQTypeName.FQTypeName.Package + |> Stdlib.Result.Result.Ok + | Error _ -> Stdlib.Result.Result.Error() + + let resolve + (onMissing: OnMissing) + (currentModule: List) + (name: WrittenTypes.Name) + : ProgramTypes.NameResolution = match name with - | None -> - Stdlib.Result.Result.Error( - LanguageTools.RuntimeErrors.NameResolution.Error - { errorType = - LanguageTools.RuntimeErrors.NameResolution.ErrorType.InvalidPackageName - nameType = nameErrorType - names = names } - ) - | Some name -> - match modules with - | "Stdlib" :: otherModules -> - let name = (parser name) |> Builtin.unwrap - - let fqName = - [ "Darklang"; "Stdlib" ] - |> Stdlib.List.append otherModules - |> Stdlib.List.append [ name ] - |> Stdlib.String.join "." - - let packageThingExists = packageThingExists fqName - - if packageThingExists then - Stdlib.Result.Result.Ok( - (ProgramTypes.FQTypeName.Package - { owner = "Darklang" - modules = Stdlib.List.append [ "Stdlib" ] otherModules - name = name - version = 0L }) - |> ProgramTypes.FQTypeName.FQTypeName.Package - ) - else - Stdlib.Result.Result.Error( - LanguageTools.RuntimeErrors.NameResolution.Error - { errorType = - LanguageTools.RuntimeErrors.NameResolution.ErrorType.NotFound - nameType = nameErrorType - names = Stdlib.List.append otherModules [ name ] } - ) - - | "PACKAGE" :: owner :: modules -> - - let name = (parser name) |> Builtin.unwrap - - let fqName = - [ owner ] - |> Stdlib.List.append modules - |> Stdlib.List.append [ name ] - |> Stdlib.String.join "." - - let packageThingExists = packageThingExists fqName - - if packageThingExists then - Stdlib.Result.Result.Ok( - (ProgramTypes.FQTypeName.Package - { owner = owner - modules = modules - name = name - version = 0L }) - |> ProgramTypes.FQTypeName.FQTypeName.Package - ) - else - Stdlib.Result.Result.Error( - LanguageTools.RuntimeErrors.NameResolution.Error - { errorType = - LanguageTools.RuntimeErrors.NameResolution.ErrorType.NotFound - nameType = nameErrorType - names = Stdlib.List.append modules [ name ] } - ) - - | modules -> - // TODO : check if user program exists - Stdlib.Result.Result.Ok( - (ProgramTypes.FQTypeName.UserProgram + // TODO remodel things appropriately so this is not needed + | KnownBuiltin(_name, _version) -> "Builtin types don't exist" // TODO: error + + | Unresolved(_range, given) -> + let modules = Stdlib.List.dropLast given + let name = Stdlib.List.last given + + // TODO: handle versions... (parse out the _v[n] part if present) + match name with + | None -> + err RuntimeErrors.NameResolution.ErrorType.InvalidPackageName given + | Some name -> + let genericName = + GenericName { modules = modules name = name - version = 0L }) - |> ProgramTypes.FQTypeName.FQTypeName.UserProgram - ) + version = 0L } + let result = + Stdlib.List.fold + (namesToTry currentModule genericName) + (err RuntimeErrors.NameResolution.ErrorType.NotFound given) + (fun currentResult nameToTry -> + match currentResult with + | Ok _ -> currentResult + | Error _ -> + match tryResolve nameToTry with + | Error() -> currentResult + | Ok success -> Stdlib.Result.Result.Ok success) + + throwIfRelevant onMissing result - let resolveTypeName - (parser: String -> Stdlib.Result.Result) - (nameErrorType: LanguageTools.RuntimeErrors.NameResolution.NameType) - (packageThingExists: String -> Bool) - (allowError: Bool) - (currentModule: List) - (name: LanguageTools.WrittenTypes.Name) - : LanguageTools.ProgramTypes.NameResolution = - match name with - | Unresolved(_, given) -> - let result = - Stdlib.List.fold - (NameResolver.namesToTry given currentModule) - - (Stdlib.Result.Result.Error( - LanguageTools.RuntimeErrors.NameResolution.Error - { nameType = nameErrorType - errorType = - LanguageTools.RuntimeErrors.NameResolution.ErrorType.NotFound - names = given } - )) - - (fun currentResult pathToTry -> - match currentResult with - | Ok _ -> currentResult - | Error _ -> - let newResult = - resolveNameTypeName - parser - pathToTry - packageThingExists - nameErrorType - - match newResult with - | Ok _ -> newResult - | Error _ -> currentResult) - - match result with - | Ok result -> Stdlib.Result.Result.Ok result - | Error err -> - if allowError then - Stdlib.Result.Result.Error err - else - Stdlib.Result.Result.Error "TODO: Raise exception" - | _ -> Stdlib.Result.Result.Error "TODO : builtin and user program" + module ConstantName = + let err + (errType: RuntimeErrors.NameResolution.ErrorType) + (names: List) + : ProgramTypes.NameResolution = + (LanguageTools.RuntimeErrors.NameResolution.Error + { nameType = LanguageTools.RuntimeErrors.NameResolution.NameType.Constant + errorType = errType + names = names }) + |> Stdlib.Result.Result.Error - let packageTypeExists (typeName: String) : Bool = - (LanguageTools.PackageManager.Type.byName typeName) |> Stdlib.Result.isOk + let builtinThingExists (name: String) : Bool = + (Builtin.languageToolsAllBuiltinConstants ()) + |> Stdlib.List.findFirst (fun f -> f.name == name) + |> Stdlib.Option.isSome - let maybeResolve - (resolver: NameResolver.NameResolutionSettings) - (currentModule: List) - (name: LanguageTools.WrittenTypes.Name) - : LanguageTools.ProgramTypes.NameResolution = + let tryResolve + (name: GenericName) + : Stdlib.Result.Result = + match name.modules with + | [] -> Stdlib.Result.Result.Error() + | owner :: modules -> + let nameForLookup = + (Stdlib.List.flatten [ name.modules; [ name.name ] ]) + |> Stdlib.String.join "." + + if owner == "Builtin" && modules == [] then + if builtinThingExists nameForLookup then + (ProgramTypes.FQConstantName.Builtin { name = name.name; version = name.version }) + |> ProgramTypes.FQConstantName.FQConstantName.Builtin + |> Stdlib.Result.Result.Ok + else + Error() + else + match PackageManager.Constant.byName nameForLookup with + | Ok _found -> + (ProgramTypes.FQConstantName.Package + { owner = owner + modules = modules + name = name.name + version = name.version }) + |> ProgramTypes.FQConstantName.FQConstantName.Package + |> Stdlib.Result.Result.Ok + | Error _ -> Stdlib.Result.Result.Error() - resolveTypeName - LanguageTools.Parser.parseName - LanguageTools.RuntimeErrors.NameResolution.NameType.Type - TypeName.packageTypeExists - currentModule - true - name let resolve - (resolver: NameResolver.NameResolutionSettings) + (onMissing: OnMissing) (currentModule: List) - (name: LanguageTools.WrittenTypes.Name) - : LanguageTools.ProgramTypes.NameResolution = - resolveTypeName - LanguageTools.Parser.parseName - LanguageTools.RuntimeErrors.NameResolution.NameType.Type - TypeName.packageTypeExists - resolver.allowError - currentModule - name - - - - module FnName = - - // helper fuctions for the resolve function - // TODO: rename this - let resolveNameFnName - (parser: String -> Stdlib.Result.Result) - (names: List) - (packageThingExists: String -> Bool) - (builtinThingExists: String -> Bool) - (nameErrorType: LanguageTools.RuntimeErrors.NameResolution.NameType) - : LanguageTools.ProgramTypes.NameResolution = - let modules = Stdlib.List.dropLast names - let name = Stdlib.List.last names - + (name: WrittenTypes.Name) + : ProgramTypes.NameResolution = match name with - | None -> - Stdlib.Result.Result.Error( - LanguageTools.RuntimeErrors.NameResolution.Error - { errorType = - LanguageTools.RuntimeErrors.NameResolution.ErrorType.InvalidPackageName - nameType = nameErrorType - names = names } - ) - | Some name -> - match modules with - | "Stdlib" :: otherModules -> - let name = (parser name) |> Builtin.unwrap - - let fqName = - [ "Darklang"; "Stdlib" ] - |> Stdlib.List.append otherModules - |> Stdlib.List.append [ name ] - |> Stdlib.String.join "." - - let packageThingExists = packageThingExists fqName - - if packageThingExists then - Stdlib.Result.Result.Ok( - (ProgramTypes.FQFnName.Package - { owner = "Darklang" - modules = Stdlib.List.append [ "Stdlib" ] otherModules - name = name - version = 0L }) - |> ProgramTypes.FQFnName.FQFnName.Package - ) - else - Stdlib.Result.Result.Error( - LanguageTools.RuntimeErrors.NameResolution.Error - { errorType = - LanguageTools.RuntimeErrors.NameResolution.ErrorType.NotFound - nameType = nameErrorType - names = Stdlib.List.append otherModules [ name ] } - ) - - | "PACKAGE" :: owner :: modules -> - let name = (parser name) |> Builtin.unwrap - - let fqName = - [ owner ] - |> Stdlib.List.append modules - |> Stdlib.List.append [ name ] - |> Stdlib.String.join "." - - let packageThingExists = packageThingExists fqName - - if packageThingExists then - Stdlib.Result.Result.Ok( - (ProgramTypes.FQFnName.Package - { owner = owner - modules = modules - name = name - version = 0L }) - |> ProgramTypes.FQFnName.FQFnName.Package - ) - else - Stdlib.Result.Result.Error( - LanguageTools.RuntimeErrors.NameResolution.Error - { errorType = - LanguageTools.RuntimeErrors.NameResolution.ErrorType.NotFound - nameType = nameErrorType - names = Stdlib.List.append modules [ name ] } - ) - - | [ "Builtin" ] -> - let builtinName = name - - let builtinExists = builtinThingExists builtinName - - if builtinExists then - let builtIn = - (ProgramTypes.FQFnName.Builtin { name = name; version = 0L }) - - Stdlib.Result.Result.Ok( - builtIn |> ProgramTypes.FQFnName.FQFnName.Builtin - ) - - else - Stdlib.Result.Result.Error( - LanguageTools.RuntimeErrors.NameResolution.Error - { errorType = - LanguageTools.RuntimeErrors.NameResolution.ErrorType.NotFound - nameType = nameErrorType - names = [ name ] } - ) - - | modules -> - // TODO : check if user program exists - Stdlib.Result.Result.Ok( - (ProgramTypes.FQFnName.UserProgram + // TODO remodel things appropriately so this is not needed + | KnownBuiltin(_name, _version) -> "Builtin types don't exist" // TODO: error + + | Unresolved(_range, given) -> + let modules = Stdlib.List.dropLast given + let name = Stdlib.List.last given + + // TODO: handle versions... (parse out the _v[n] part if present) + match name with + | None -> + err RuntimeErrors.NameResolution.ErrorType.InvalidPackageName given + | Some name -> + let genericName = + GenericName { modules = modules name = name - version = 0L }) - |> ProgramTypes.FQFnName.FQFnName.UserProgram - ) - + version = 0L } - let resolveFnName - (parser: String -> Stdlib.Result.Result) - (nameErrorType: LanguageTools.RuntimeErrors.NameResolution.NameType) - (packageThingExists: String -> Bool) - (builtinThingExists: String -> Bool) - (allowError: Bool) - (currentModule: List) - (name: LanguageTools.WrittenTypesToProgramTypes.Name) - : LanguageTools.ProgramTypes.NameResolution = + let result = + Stdlib.List.fold + (namesToTry currentModule genericName) + (err RuntimeErrors.NameResolution.ErrorType.NotFound given) + (fun currentResult nameToTry -> + match currentResult with + | Ok _ -> currentResult + | Error _ -> + match tryResolve nameToTry with + | Error() -> currentResult + | Ok success -> Stdlib.Result.Result.Ok success) - match name with - | Unresolved given -> - let result = - Stdlib.List.fold - (NameResolver.namesToTry given currentModule) - - (Stdlib.Result.Result.Error( - LanguageTools.RuntimeErrors.NameResolution.Error - { nameType = nameErrorType - errorType = - LanguageTools.RuntimeErrors.NameResolution.ErrorType.NotFound - names = given } - )) - - (fun currentResult pathToTry -> - match currentResult with - | Ok _ -> currentResult - | Error _ -> - let newResult = - resolveNameFnName - parser - pathToTry - packageThingExists - builtinThingExists - nameErrorType - - match newResult with - | Ok _ -> newResult - | Error _ -> currentResult) - - match result with - | Ok result -> Stdlib.Result.Result.Ok result - | Error err -> - if allowError then - Stdlib.Result.Result.Error err - else - Stdlib.Result.Result.Error "TODO: Raise exception" + throwIfRelevant onMissing result - | _ -> Stdlib.Result.Result.Error "TODO : builtin and user program" - let packageFnExists (fnName: String) : Bool = - (LanguageTools.PackageManager.Function.byName fnName) |> Stdlib.Result.isOk + module FnName = + let err + (errType: RuntimeErrors.NameResolution.ErrorType) + (names: List) + : ProgramTypes.NameResolution = + (LanguageTools.RuntimeErrors.NameResolution.Error + { nameType = LanguageTools.RuntimeErrors.NameResolution.NameType.Function + errorType = errType + names = names }) + |> Stdlib.Result.Result.Error - let builtinThingExists (fnName: String) : Bool = + let builtinThingExists (name: String) : Bool = (Builtin.languageToolsAllBuiltinFns ()) - |> Stdlib.List.findFirst (fun f -> f.name == fnName) + |> Stdlib.List.findFirst (fun f -> f.name == name) |> Stdlib.Option.isSome - let maybeResolve - (resolver: NameResolver.NameResolutionSettings) - (currentModule: List) - (name: LanguageTools.WrittenTypesToProgramTypes.Name) - : LanguageTools.ProgramTypes.NameResolution = - - resolveFnName - LanguageTools.Parser.parseName - LanguageTools.RuntimeErrors.NameResolution.NameType.Function - FnName.packageFnExists - FnName.builtinThingExists - currentModule - true - name + let tryResolve + (name: GenericName) + : Stdlib.Result.Result = + match name.modules with + | [] -> Stdlib.Result.Result.Error() + | owner :: modules -> + let nameForLookup = + (Stdlib.List.flatten [ name.modules; [ name.name ] ]) + |> Stdlib.String.join "." + + if owner == "Builtin" && modules == [] then + if builtinThingExists nameForLookup then + (ProgramTypes.FQFnName.Builtin { name = name.name; version = name.version }) + |> ProgramTypes.FQFnName.FQFnName.Builtin + |> Stdlib.Result.Result.Ok + else + Error() + else + match PackageManager.Function.byName nameForLookup with + | Ok _found -> + (ProgramTypes.FQFnName.Package + { owner = owner + modules = modules + name = name.name + version = name.version }) + |> ProgramTypes.FQFnName.FQFnName.Package + |> Stdlib.Result.Result.Ok + | Error _ -> Stdlib.Result.Result.Error() + let resolve - (resolver: NameResolver.NameResolutionSettings) + (onMissing: OnMissing) (currentModule: List) - (name: LanguageTools.WrittenTypesToProgramTypes.Name) - : LanguageTools.ProgramTypes.NameResolution = - - resolveFnName - LanguageTools.Parser.parseName - LanguageTools.RuntimeErrors.NameResolution.NameType.Function - FnName.packageFnExists - FnName.builtinThingExists - resolver.allowError - currentModule - name \ No newline at end of file + (name: WrittenTypes.Name) + : ProgramTypes.NameResolution = + match name with + // TODO remodel things appropriately so this is not needed + | KnownBuiltin(_name, _version) -> "Builtin types don't exist" // TODO: error + + | Unresolved(_range, given) -> + let modules = Stdlib.List.dropLast given + let name = Stdlib.List.last given + + // TODO: handle versions... (parse out the _v[n] part if present) + match name with + | None -> + err RuntimeErrors.NameResolution.ErrorType.InvalidPackageName given + | Some name -> + let genericName = + GenericName + { modules = modules + name = name + version = 0L } + + let result = + Stdlib.List.fold + (namesToTry currentModule genericName) + (err RuntimeErrors.NameResolution.ErrorType.NotFound given) + (fun currentResult nameToTry -> + match currentResult with + | Ok _ -> currentResult + | Error _ -> + match tryResolve nameToTry with + | Error() -> currentResult + | Ok success -> Stdlib.Result.Result.Ok success) + + throwIfRelevant onMissing result diff --git a/packages/darklang/languageTools/packageManager.dark b/packages/darklang/languageTools/packageManager.dark index 05aba17d43..81383b9175 100644 --- a/packages/darklang/languageTools/packageManager.dark +++ b/packages/darklang/languageTools/packageManager.dark @@ -95,6 +95,9 @@ module Darklang = // else // (FetchError.Not200 response) |> Stdlib.Result.Result.Error + + // TODO: this type signature is totally wrong, + // yet we're not complaining in the runtime type-checker? let byName (typeName: String) : Stdlib.Result.Result = @@ -146,6 +149,31 @@ module Darklang = | e -> Stdlib.Result.Result.Error e + module Constant = + // let getAll (baseUrl: String) : String = "TODO" + + // let getByTlid (baseUrl: String) (tlid: String) : String = "TODO" + + let byName + (fnName: String) + : Stdlib.Result.Result = + let fn = + Stdlib.HttpClient.request + "GET" + $"{baseUrl ()}/constant/by-name/{fnName}" + [] + [] + + let statusCode = + fn + |> Stdlib.Result.map (fun response -> response.statusCode) + |> Builtin.unwrap + + match statusCode with + | 200L -> Stdlib.Result.Result.Ok fn + | e -> Stdlib.Result.Result.Error e + + // let getByFullyQualifiedName (baseUrl: String) (name: String) : String = // "TODO" diff --git a/packages/darklang/languageTools/programTypes.dark b/packages/darklang/languageTools/programTypes.dark index a73ff698d8..0511c3515d 100644 --- a/packages/darklang/languageTools/programTypes.dark +++ b/packages/darklang/languageTools/programTypes.dark @@ -13,18 +13,10 @@ module Darklang = name: String version: Int64 } - /// Part of the user's program (eg canvas or cli) - type UserProgram = - { modules: List - name: String - version: Int64 } + type FQTypeName = Package of Package - type FQTypeName = - | Package of Package - | UserProgram of UserProgram - - module FQFnName = + module FQConstantName = type Builtin = { name: String; version: Int64 } type Package = @@ -33,18 +25,12 @@ module Darklang = name: String version: Int64 } - type UserProgram = - { modules: List - name: String - version: Int64 } - - type FQFnName = + type FQConstantName = | Builtin of Builtin | Package of Package - | UserProgram of UserProgram - module FQConstantName = + module FQFnName = type Builtin = { name: String; version: Int64 } type Package = @@ -53,15 +39,11 @@ module Darklang = name: String version: Int64 } - type UserProgram = - { modules: List - name: String - version: Int64 } - - type FQConstantName = + type FQFnName = | Builtin of Builtin | Package of Package - | UserProgram of UserProgram + + type NameResolution<'a> = @@ -397,76 +379,54 @@ module Darklang = definition: Definition } - module Handler = - type CronInterval = - | EveryDay - | EveryWeek - | EveryFortnight - | EveryHour - | Every12Hours - | EveryMinute - - type Spec = - | HTTP of route: String * method: String - | Worker of name: String - | Cron of name: String * interval: CronInterval - | REPL of name: String - - type Handler = { tlid: TLID; ast: Expr; spec: Spec } - - - type DB = + // Package space + type PackageType = { tlid: TLID - name: String - version: Int64 - typ: TypeReference } + id: Uuid + name: FQTypeName.Package + declaration: TypeDeclaration.TypeDeclaration + description: String + deprecated: Deprecation } - /// A type that a User defined within a Canvas - type UserType = + type PackageConstant = { tlid: TLID - name: FQTypeName.UserProgram + id: Uuid + name: FQConstantName.Package + body: Const description: String - declaration: TypeDeclaration.TypeDeclaration - deprecated: Deprecation } + deprecated: Deprecation } - module UserFunction = + + module PackageFn = type Parameter = { name: String typ: TypeReference description: String } - type UserFunction = + type PackageFn = { tlid: TLID - name: FQFnName.UserProgram + id: Uuid + name: FQFnName.Package + body: Expr typeParams: List parameters: List returnType: TypeReference description: String - deprecated: Deprecation - body: Expr } - - type UserConstant = - { tlid: TLID - name: FQConstantName.UserProgram - description: String - deprecated: Deprecation - body: Const } + deprecated: Deprecation } + type Packages = + { types: List + constants: List + fns: List } - // module Toplevel = - // type T = - // | TLHandler of Handler.Handler - // | TLDB of DB - // | TLFunction of UserFunction.UserFunction - // | TLType of UserType.T - // let toTLID (tl : T) : tlid = - // match tl with - // | TLHandler h -> h.tlid - // | TLDB db -> db.tlid - // | TLFunction f -> f.tlid - // | TLType t -> t.tlid + // User/Canvas space + type DB = + { tlid: TLID + name: String + version: Int64 + typ: TypeReference } type Secret = @@ -475,41 +435,30 @@ module Darklang = version: Int64 } - type PackageType = - { tlid: TLID - id: Uuid - name: FQTypeName.Package - declaration: TypeDeclaration.TypeDeclaration - description: String - deprecated: Deprecation } + module Handler = + type CronInterval = + | EveryDay + | EveryWeek + | EveryFortnight + | EveryHour + | Every12Hours + | EveryMinute - module PackageFn = - type Parameter = - { name: String - typ: TypeReference - description: String } + type Spec = + | HTTP of route: String * method: String + | Worker of name: String + | Cron of name: String * interval: CronInterval + | REPL of name: String - type PackageFn = - { tlid: TLID - id: Uuid - name: FQFnName.Package - body: Expr - typeParams: List - parameters: List - returnType: TypeReference - description: String - deprecated: Deprecation } + type Handler = { tlid: TLID; ast: Expr; spec: Spec } - type PackageConstant = - { tlid: TLID - id: Uuid - name: FQConstantName.Package - body: Const - description: String - deprecated: Deprecation } +// module Toplevel = +// type T = +// | TLDB of DB +// | TLHandler of Handler.Handler - type Packages = - { types: List - constants: List - fns: List } \ No newline at end of file +// let toTLID (tl : T) : tlid = +// match tl with +// | TLDB db -> db.tlid +// | TLHandler h -> h.tlid \ No newline at end of file diff --git a/packages/darklang/languageTools/runtimeTypes.dark b/packages/darklang/languageTools/runtimeTypes.dark index f70e34550b..c808a98d35 100644 --- a/packages/darklang/languageTools/runtimeTypes.dark +++ b/packages/darklang/languageTools/runtimeTypes.dark @@ -13,14 +13,7 @@ module Darklang = name: String version: Int64 } - type UserProgram = - { modules: List - name: String - version: Int64 } - - type FQTypeName = - | Package of Package - | UserProgram of UserProgram + type FQTypeName = Package of Package module FQFnName = @@ -32,15 +25,9 @@ module Darklang = name: String version: Int64 } - type UserProgram = - { modules: List - name: String - version: Int64 } - type FQFnName = | Builtin of Builtin | Package of Package - | UserProgram of UserProgram /// A Fully-Qualified Constant Name @@ -54,15 +41,9 @@ module Darklang = name: String version: Int64 } - type UserProgram = - { modules: List - name: String - version: Int64 } - type FQConstantName = | Builtin of Builtin | Package of Package - | UserProgram of UserProgram type NameResolution<'a> = Stdlib.Result.Result<'a, RuntimeError> diff --git a/packages/darklang/languageTools/writtenTypesToProgramTypes.dark b/packages/darklang/languageTools/writtenTypesToProgramTypes.dark index 32065f3ae9..a805b8dff0 100644 --- a/packages/darklang/languageTools/writtenTypesToProgramTypes.dark +++ b/packages/darklang/languageTools/writtenTypesToProgramTypes.dark @@ -8,7 +8,6 @@ module Darklang = let gtlid () : UInt64 = Stdlib.UInt64.random 0UL 9223372036854775807UL - type Name = Unresolved of List module Identifiers = module Type = @@ -16,50 +15,43 @@ module Darklang = module QualifiedType = let toPT - (resolver: NameResolver.NameResolutionSettings) + (onMissing: NameResolver.OnMissing) (i: WrittenTypes.QualifiedTypeIdentifier) - : ProgramTypes.FQTypeName.FQTypeName = - let currentModule = Stdlib.List.map i.modules (fun (m, _) -> m.name) - let nametoResolve = [ i.typ.name ] - - let resolvedName = - NameResolver.TypeName.resolve - resolver - currentModule - (WrittenTypes.Name.Unresolved(i.range, nametoResolve)) + : ProgramTypes.NameResolution = + let nameToResolve = + Stdlib.List.append + (Stdlib.List.map i.modules (fun (m, _) -> m.name)) + [ i.typ.name ] + + NameResolver.TypeName.resolve + onMissing + [] + (WrittenTypes.Name.Unresolved(i.range, nameToResolve)) - match resolvedName with - | Ok n -> n - // TODO: Handle errors properly - | Error e -> $"TODO: handle error {e}" module Fn = let toPT (fn: WrittenTypes.FnIdentifier) : String = fn.name module QualifiedFn = let toPT - (resolver: NameResolver.NameResolutionSettings) + (onMissing: NameResolver.OnMissing) (i: WrittenTypes.QualifiedFnIdentifier) - : ProgramTypes.FQFnName.FQFnName = - let modules = Stdlib.List.map i.modules (fun (m, _) -> m.name) - let nametoResolve = [ i.fn.name ] - - let resolvedName = - NameResolver.FnName.resolve - resolver - modules - (WrittenTypesToProgramTypes.Name.Unresolved nametoResolve) - - match resolvedName with - | Ok name -> name - // TODO: Handle errors properly - | Error e -> $"TODO: handle error {e}" + : ProgramTypes.NameResolution = + let nameToResolve = + Stdlib.List.append + (Stdlib.List.map i.modules (fun (m, _) -> m.name)) + [ i.fn.name ] + + NameResolver.FnName.resolve + onMissing + [] + (WrittenTypes.Name.Unresolved(i.range, nameToResolve)) module TypeReference = module Builtin = let toPT - (resolver: NameResolver.NameResolutionSettings) + (onMissing: NameResolver.OnMissing) (t: WrittenTypes.TypeReference.Builtin) : ProgramTypes.TypeReference = match t with @@ -79,21 +71,21 @@ module Darklang = | TChar _range -> ProgramTypes.TypeReference.TChar | TString _range -> ProgramTypes.TypeReference.TString | TList(_range, _, _, typ, _) -> - let typ = TypeReference.toPT resolver typ + let typ = TypeReference.toPT onMissing typ ProgramTypes.TypeReference.TList(typ) | TDict(_range, _, _, valueType, _) -> - let valueType = TypeReference.toPT resolver valueType + let valueType = TypeReference.toPT onMissing valueType ProgramTypes.TypeReference.TDict valueType | TTuple(_range, firstType, _, secondType, restTypes, _, _) -> - let firstType = TypeReference.toPT resolver firstType - let secondType = TypeReference.toPT resolver secondType + let firstType = TypeReference.toPT onMissing firstType + let secondType = TypeReference.toPT onMissing secondType let restTypes = Stdlib.List.map restTypes (fun (_, t) -> - TypeReference.toPT resolver t) + TypeReference.toPT onMissing t) ProgramTypes.TypeReference.TTuple(firstType, secondType, restTypes) @@ -102,16 +94,16 @@ module Darklang = let toPT - (resolver: NameResolver.NameResolutionSettings) + (onMissing: NameResolver.OnMissing) (t: WrittenTypes.TypeReference.TypeReference) : ProgramTypes.TypeReference = match t with - | Builtin b -> Builtin.toPT resolver b + | Builtin b -> Builtin.toPT onMissing b | QualifiedName qn -> - let typeName = Identifiers.QualifiedType.toPT resolver qn + let typeName = Identifiers.QualifiedType.toPT onMissing qn ProgramTypes.TypeReference.TCustomType( - Stdlib.Result.Result.Ok typeName, + typeName, [] ) @@ -119,57 +111,62 @@ module Darklang = module TypeDeclaration = module RecordField = let toPT - (resolver: NameResolver.NameResolutionSettings) + (onMissing: NameResolver.OnMissing) (f: WrittenTypes.TypeDeclaration.RecordField) : ProgramTypes.TypeDeclaration.RecordField = let name = f.name |> Stdlib.Tuple2.second ProgramTypes.TypeDeclaration.RecordField { name = name - typ = TypeReference.toPT resolver f.typ + typ = TypeReference.toPT onMissing f.typ description = "" } module Definition = let toPT - (resolver: NameResolver.NameResolutionSettings) + (onMissing: NameResolver.OnMissing) (d: WrittenTypes.TypeDeclaration.Definition) : ProgramTypes.TypeDeclaration.Definition = match d with | Alias typ -> - let typ = TypeReference.toPT resolver typ - + let typ = TypeReference.toPT onMissing typ ProgramTypes.TypeDeclaration.Definition.Alias typ + | Enum _cases -> "TODO" + | Record fields -> let fields = - Stdlib.List.map fields (fun f -> RecordField.toPT resolver f) + Stdlib.List.map fields (fun f -> RecordField.toPT onMissing f) ProgramTypes.TypeDeclaration.Definition.Record fields let toPT - (resolver: NameResolver.NameResolutionSettings) + (onMissing: NameResolver.OnMissing) (d: WrittenTypes.TypeDeclaration.TypeDeclaration) : ProgramTypes.TypeDeclaration.TypeDeclaration = - let def = Definition.toPT resolver d.definition + let def = Definition.toPT onMissing d.definition ProgramTypes.TypeDeclaration.TypeDeclaration { typeParams = []; definition = def } - let toUserTypePT - (resolver: NameResolver.NameResolutionSettings) + let toPackageTypePT + (onMissing: NameResolver.OnMissing) + (owner: String) + (modules: List) (d: WrittenTypes.TypeDeclaration.TypeDeclaration) - : ProgramTypes.UserType = - ProgramTypes.UserType + : ProgramTypes.PackageType = + ProgramTypes.PackageType { tlid = gtlid () + id = Stdlib.Uuid.generate () name = - ProgramTypes.FQTypeName.UserProgram - { modules = [] + ProgramTypes.FQTypeName.Package + { owner = owner + modules = modules name = d.name.name version = 0L } description = "" - declaration = toPT resolver d + declaration = toPT onMissing d deprecated = ProgramTypes.Deprecation.NotDeprecated } @@ -216,7 +213,7 @@ module Darklang = let toPT - (resolver: NameResolver.NameResolutionSettings) + (onMissing: NameResolver.OnMissing) (e: WrittenTypes.Expr) : ProgramTypes.Expr = match e with @@ -251,29 +248,29 @@ module Darklang = | EList(_, contents, _, _) -> ProgramTypes.Expr.EList( gid (), - Stdlib.List.map contents (fun (expr, _) -> toPT resolver expr) + Stdlib.List.map contents (fun (expr, _) -> toPT onMissing expr) ) | EDict(_, contents, _, _, _) -> ProgramTypes.Expr.EDict( gid (), - Stdlib.List.map contents (fun (_, k, v) -> (k, toPT resolver v)) + Stdlib.List.map contents (fun (_, k, v) -> (k, toPT onMissing v)) ) | ETuple(_, first, _, second, rest, _, _) -> - let first = toPT resolver first - let second = toPT resolver second - let rest = Stdlib.List.map rest (fun (_, e) -> toPT resolver e) + let first = toPT onMissing first + let second = toPT onMissing second + let rest = Stdlib.List.map rest (fun (_, e) -> toPT onMissing e) ProgramTypes.Expr.ETuple(gid (), first, second, rest) | ERecord(_, typeName, fields, _, _) -> - let typeName = NameResolver.TypeName.resolve resolver [] typeName + let typeName = NameResolver.TypeName.resolve onMissing [] typeName let fields = Stdlib.List.map fields (fun (_, name, typeName) -> let fieldName = name |> Stdlib.Tuple2.second - (fieldName, toPT resolver typeName)) + (fieldName, toPT onMissing typeName)) ProgramTypes.Expr.ERecord(gid (), typeName, fields) @@ -282,20 +279,20 @@ module Darklang = ProgramTypes.Expr.ELet( gid (), LetPattern.toPT pat, - toPT resolver rhs, - toPT resolver body + toPT onMissing rhs, + toPT onMissing body ) | EVariable(_, var) -> ProgramTypes.Expr.EVariable (gid ()) var | EIf(_, cond, thenExpr, elseExpr, _, _, _) -> let elseExpr = - elseExpr |> Stdlib.Option.map (fun es -> Expr.toPT resolver es) + elseExpr |> Stdlib.Option.map (fun es -> Expr.toPT onMissing es) ProgramTypes.Expr.EIf( gid (), - toPT resolver cond, - toPT resolver thenExpr, + toPT onMissing cond, + toPT onMissing thenExpr, elseExpr ) @@ -306,60 +303,65 @@ module Darklang = ProgramTypes.Expr.EInfix( gid (), infix, - toPT resolver left, - toPT resolver right + toPT onMissing left, + toPT onMissing right ) | EFnCall(_, fnName, args, _, _) -> - let fnName = Identifiers.QualifiedFn.toPT resolver fnName + let fnName = Identifiers.QualifiedFn.toPT onMissing fnName let fnNameExpr = - ProgramTypes.Expr.EFnName(gid (), Stdlib.Result.Result.Ok fnName) + ProgramTypes.Expr.EFnName(gid (), fnName) ProgramTypes.Expr.EApply( gid (), fnNameExpr, [], - Stdlib.List.map args (fun a -> toPT resolver a) + Stdlib.List.map args (fun a -> toPT onMissing a) ) module FunctionDeclaration = module Parameter = - let toUserFnParamPT - (resolver: NameResolver.NameResolutionSettings) + let toPackageFnParamPT + (onMissing: NameResolver.OnMissing) (p: WrittenTypes.FnDeclaration.Parameter) - : ProgramTypes.UserFunction.Parameter = + : ProgramTypes.PackageFn.Parameter = match p with | Unit p -> - ProgramTypes.UserFunction.Parameter + ProgramTypes.PackageFn.Parameter { name = "_" // TODO ok? typ = ProgramTypes.TypeReference.TUnit description = "" } | Normal p -> - ProgramTypes.UserFunction.Parameter + ProgramTypes.PackageFn.Parameter { name = p.name.name - typ = TypeReference.toPT resolver p.typ + typ = TypeReference.toPT onMissing p.typ description = "" } - let toUserFnPT - (resolver: NameResolver.NameResolutionSettings) + let toPackageFnPT + (onMissing: NameResolver.OnMissing) + (owner: String) + (modules: List) (fn: WrittenTypes.FnDeclaration.FnDeclaration) - : ProgramTypes.UserFunction.UserFunction = - ProgramTypes.UserFunction.UserFunction + : ProgramTypes.PackageFn.PackageFn = + ProgramTypes.PackageFn.PackageFn { tlid = gtlid () + id = Stdlib.Uuid.generate () name = - ProgramTypes.FQFnName.UserProgram - { modules = [] + ProgramTypes.FQFnName.Package + { owner = owner + modules = modules name = fn.name.name version = 0L } typeParams = [] parameters = fn.parameters - |> Stdlib.List.map (fun p -> Parameter.toUserFnParamPT resolver p) - returnType = TypeReference.toPT resolver fn.returnType + |> Stdlib.List.map (fun p -> + Parameter.toPackageFnParamPT onMissing p) + returnType = TypeReference.toPT onMissing fn.returnType description = "" deprecated = ProgramTypes.Deprecation.NotDeprecated - body = Expr.toPT resolver fn.body } \ No newline at end of file + body = Expr.toPT onMissing fn.body } \ No newline at end of file diff --git a/packages/darklang/prettyPrinter/programTypes.dark b/packages/darklang/prettyPrinter/programTypes.dark index da4ca7c923..cc91014c14 100644 --- a/packages/darklang/prettyPrinter/programTypes.dark +++ b/packages/darklang/prettyPrinter/programTypes.dark @@ -47,53 +47,12 @@ module Darklang = $"PACKAGE.{p.owner}.{modulesPart}.{namePart}{versionPart}" - module UserProgram = - - let atDefinition - // TODO: take in just typ and version - modules should have already been dealt with - (u: LanguageTools.ProgramTypes.FQTypeName.UserProgram) - : String = - match u.modules with - | [] -> - let namePart = u.name - - let versionPart = - if u.version == 0L then - "" - else - $"_v{Stdlib.Int64.toString u.version}" - - $"{namePart}{versionPart}" - | _ -> "(UserTypeName.atDefinition unexpected nonempty u.modules)" - - let fullForReference - (u: LanguageTools.ProgramTypes.FQTypeName.UserProgram) - : String = - let modulesPart = - match u.modules with - | [] -> "" - | modules -> - modules |> Stdlib.String.join "." |> (fun parts -> $"{parts}.") - - let namePart = u.name - - let versionPart = - if u.version == 0L then - "" - else - $"_v{Stdlib.Int64.toString u.version}" - - $"{modulesPart}{namePart}{versionPart}" - - let atDefinition (t: LanguageTools.ProgramTypes.FQTypeName.FQTypeName) : String = match t with | Package p -> PrettyPrinter.ProgramTypes.FQTypeName.Package.atDefinition p - | UserProgram u -> - PrettyPrinter.ProgramTypes.FQTypeName.UserProgram.atDefinition u let fullForReference (t: LanguageTools.ProgramTypes.FQTypeName.FQTypeName) @@ -101,8 +60,6 @@ module Darklang = match t with | Package p -> PrettyPrinter.ProgramTypes.FQTypeName.Package.fullForReference p - | UserProgram u -> - PrettyPrinter.ProgramTypes.FQTypeName.UserProgram.fullForReference u module FQConstantName = @@ -151,43 +108,6 @@ module Darklang = $"PACKAGE.{p.owner}.{modulesPart}.{namePart}{versionPart}" - module UserProgram = - let atDefinition - // TODO: take in just typ and version - modules should have already been dealt with - (u: LanguageTools.ProgramTypes.FQConstantName.UserProgram) - : String = - match u.modules with - | [] -> - let namePart = u.name - - let versionPart = - if u.version == 0L then - "" - else - $"_v{Stdlib.Int64.toString u.version}" - - $"{namePart}{versionPart}" - | _ -> "(UserTypeName.atDefinition unexpected nonempty u.modules)" - - let fullForReference - (u: LanguageTools.ProgramTypes.FQConstantName.UserProgram) - : String = - let modulesPart = - match u.modules with - | [] -> "" - | modules -> - modules |> Stdlib.String.join "." |> (fun parts -> $"{parts}.") - - let namePart = u.name - - let versionPart = - if u.version == 0L then - "" - else - $"_v{Stdlib.Int64.toString u.version}" - - $"{modulesPart}{namePart}{versionPart}" - let atDefinition (t: LanguageTools.ProgramTypes.FQConstantName.FQConstantName) @@ -197,8 +117,6 @@ module Darklang = PrettyPrinter.ProgramTypes.FQConstantName.Builtin.fullForReference b | Package p -> PrettyPrinter.ProgramTypes.FQConstantName.Package.atDefinition p - | UserProgram u -> - PrettyPrinter.ProgramTypes.FQConstantName.UserProgram.atDefinition u let fullForReference (t: LanguageTools.ProgramTypes.FQConstantName.FQConstantName) @@ -208,8 +126,6 @@ module Darklang = PrettyPrinter.ProgramTypes.FQConstantName.Builtin.fullForReference b | Package p -> PrettyPrinter.ProgramTypes.FQConstantName.Package.fullForReference p - | UserProgram u -> - PrettyPrinter.ProgramTypes.FQConstantName.UserProgram.fullForReference u module FQFnName = @@ -262,51 +178,11 @@ module Darklang = $"PACKAGE.{p.owner}.{modulesPart}.{namePart}{versionPart}" - module UserProgram = - - let atDefinition - // TODO: take in just typ and version - modules should have already been dealt with - (u: LanguageTools.ProgramTypes.FQFnName.UserProgram) - : String = - match u.modules with - | [] -> - let versionPart = - if u.version == 0L then - "" - else - $"_v{Stdlib.Int64.toString u.version}" - - $"{u.name}{versionPart}" - | _ -> "(UserTypeName.atDefinition unexpected nonempty u.modules)" - - - let fullForReference - (u: LanguageTools.ProgramTypes.FQFnName.UserProgram) - : String = - let modulesPart = - match u.modules with - | [] -> "" - | modules -> - modules |> Stdlib.String.join "." |> (fun parts -> $"{parts}.") - - let namePart = u.name - - let versionPart = - if u.version == 0L then - "" - else - $"_v{Stdlib.Int64.toString u.version}" - - $"{modulesPart}{namePart}{versionPart}" - - let atDefinition (t: LanguageTools.ProgramTypes.FQFnName.FQFnName) : String = match t with | Builtin _b -> "why are you trying to print a stdlib type name _definition_?" | Package p -> PrettyPrinter.ProgramTypes.FQFnName.Package.atDefinition p - | UserProgram u -> - PrettyPrinter.ProgramTypes.FQFnName.UserProgram.atDefinition u let fullForReference (t: LanguageTools.ProgramTypes.FQFnName.FQFnName) @@ -316,8 +192,6 @@ module Darklang = PrettyPrinter.ProgramTypes.FQFnName.Builtin.fullForReference b | Package p -> PrettyPrinter.ProgramTypes.FQFnName.Package.fullForReference p - | UserProgram u -> - PrettyPrinter.ProgramTypes.FQFnName.UserProgram.fullForReference u let typeReference (t: LanguageTools.ProgramTypes.TypeReference) : String = @@ -985,67 +859,48 @@ module Darklang = $"type {db.name}{versionPart} = {typPart}" - let userType (userType: LanguageTools.ProgramTypes.UserType) : String = - let namePart = - PrettyPrinter.ProgramTypes.FQTypeName.UserProgram.atDefinition - userType.name - let typeParamPart = - match userType.declaration.typeParams with - | [] -> "" - | _ -> - userType.declaration.typeParams - |> Stdlib.List.map (fun typeParam -> $"'{typeParam}") - |> Stdlib.String.join ", " - |> fun parts -> $"<{parts}>" - let defPart = PrettyPrinter.ProgramTypes.customType userType.declaration + // module Toplevel = + // type T = + // | TLHandler of Handler.Handler + // | TLDB of DB - $"type {namePart}{typeParamPart} =\n{PrettyPrinter.indent defPart}" + // let secret (s: Stdlib.Secret.T) : String = + // let versionPart = if s.version == 0 then "" else $"_v{Stdlib.Int64.toString s.version}" - module UserFunction = - let parameter - (p: LanguageTools.ProgramTypes.UserFunction.Parameter) - : String = - // TODO: handle `description` - let typPart = PrettyPrinter.ProgramTypes.typeReference p.typ + // $"let {s.name}{versionPart} = \"*****\"" - $"({p.name}: {typPart})" - let userFunction - (u: LanguageTools.ProgramTypes.UserFunction.UserFunction) - : String = - // TODO: do something with description and deprecated - // TODO: shouldn't there be modules here somewhere? + let packageType (p: LanguageTools.ProgramTypes.PackageType) : String = + // TODO: take care of deprecated and description let namePart = - PrettyPrinter.ProgramTypes.FQFnName.UserProgram.atDefinition u.name - - let typeParamsPart = Stdlib.String.join u.typeParams " " + PrettyPrinter.ProgramTypes.FQTypeName.Package.atDefinition p.name - let paramsPart = - Stdlib.String.join - (Stdlib.List.map u.parameters (fun p -> - PrettyPrinter.ProgramTypes.UserFunction.parameter p)) - " " + let typeParamPart = + match p.declaration.typeParams with + | [] -> "" + | _ -> + p.declaration.typeParams + |> Stdlib.List.map (fun typeParam -> $"'{typeParam}") + |> Stdlib.String.join ", " + |> fun parts -> $"<{parts}>" - let retPart = PrettyPrinter.ProgramTypes.typeReference u.returnType + let defPart = + (PrettyPrinter.ProgramTypes.customType p.declaration) + |> PrettyPrinter.indent - let bodyPart = PrettyPrinter.ProgramTypes.expr u.body - $"let {namePart}{typeParamsPart} {paramsPart}: {retPart} =\n{PrettyPrinter.indent bodyPart}" + $"type {namePart}{typeParamPart} =\n{defPart}" - // module Toplevel = - // type T = - // | TLHandler of Handler.Handler - // | TLDB of DB - // | TLFunction of UserFunction.UserFunction - // | TLType of UserType.T + let packageConstant (p: LanguageTools.ProgramTypes.PackageConstant) : String = + let namePart = + PrettyPrinter.ProgramTypes.FQConstantName.Package.atDefinition p.name - // let secret (s: Stdlib.Secret.T) : String = - // let versionPart = if s.version == 0 then "" else $"_v{Stdlib.Int64.toString s.version}" + let bodyPart = PrettyPrinter.ProgramTypes.constant p.body - // $"let {s.name}{versionPart} = \"*****\"" + $"let {namePart} = {bodyPart}" module PackageFn = @@ -1055,7 +910,7 @@ module Darklang = let packageFn (p: LanguageTools.ProgramTypes.PackageFn.PackageFn) : String = // TODO: handle `deprecated`, `description` - let namePart = PrettyPrinter.ProgramTypes.FnName.Package.atDefinition p.name + let namePart = PrettyPrinter.ProgramTypes.FQFnName.Package.atDefinition p.name let typeParamPart = match p.typeParams with @@ -1076,34 +931,4 @@ module Darklang = let bodyPart = PrettyPrinter.ProgramTypes.expr p.body - $"let {namePart}{typeParamPart} {paramPart} : {retPart} =\n{PrettyPrinter.indent bodyPart}" - - - let packageType (p: LanguageTools.ProgramTypes.PackageType) : String = - // TODO: take care of deprecated and description - let namePart = - PrettyPrinter.ProgramTypes.FQTypeName.Package.atDefinition p.name - - let typeParamPart = - match p.declaration.typeParams with - | [] -> "" - | _ -> - p.declaration.typeParams - |> Stdlib.List.map (fun typeParam -> $"'{typeParam}") - |> Stdlib.String.join ", " - |> fun parts -> $"<{parts}>" - - let defPart = - (PrettyPrinter.ProgramTypes.customType p.declaration) - |> PrettyPrinter.indent - - $"type {namePart}{typeParamPart} =\n{defPart}" - - - let packageConstant (p: LanguageTools.ProgramTypes.PackageConstant) : String = - let namePart = - PrettyPrinter.ProgramTypes.FQConstantName.Package.atDefinition p.name - - let bodyPart = PrettyPrinter.ProgramTypes.constant p.body - - $"let {namePart} = {bodyPart}" \ No newline at end of file + $"let {namePart}{typeParamPart} {paramPart}: {retPart} =\n{PrettyPrinter.indent bodyPart}" \ No newline at end of file diff --git a/packages/darklang/prettyPrinter/runtimeTypes.dark b/packages/darklang/prettyPrinter/runtimeTypes.dark index e1529df58b..91a57ed6e3 100644 --- a/packages/darklang/prettyPrinter/runtimeTypes.dark +++ b/packages/darklang/prettyPrinter/runtimeTypes.dark @@ -22,30 +22,10 @@ module Darklang = $"PACKAGE.{p.owner}.{modulesPart}.{namePart}{versionPart}" - let userProgram - (u: LanguageTools.RuntimeTypes.FQTypeName.UserProgram) - : String = - let modulesPart = - match u.modules with - | [] -> "" - | modules -> - modules |> Stdlib.String.join "." |> (fun parts -> $"{parts}.") - - let namePart = u.name - - let versionPart = - if u.version == 0L then - "" - else - $"_v{Stdlib.Int64.toString u.version}" - - $"{modulesPart}{namePart}{versionPart}" - // TODO rename to fqtypeName? let typeName (t: LanguageTools.RuntimeTypes.FQTypeName.FQTypeName) : String = match t with | Package p -> FQTypeName.package p - | UserProgram u -> FQTypeName.userProgram u module FQConstantName = @@ -73,25 +53,6 @@ module Darklang = $"PACKAGE.{p.owner}.{modulesPart}.{namePart}{versionPart}" - let userProgram - (u: LanguageTools.RuntimeTypes.FQConstantName.UserProgram) - : String = - let modulesPart = - match u.modules with - | [] -> "" - | modules -> - modules |> Stdlib.String.join "." |> (fun parts -> $"{parts}.") - - let namePart = u.name - - let versionPart = - if u.version == 0L then - "" - else - $"_v{Stdlib.Int64.toString u.version}" - - $"{modulesPart}{namePart}{versionPart}" - // TODO rename to fqconstantName? let constantName (t: LanguageTools.RuntimeTypes.FQConstantName.FQConstantName) @@ -99,7 +60,6 @@ module Darklang = match t with | Builtin b -> FQConstantName.builtIn b | Package p -> FQConstantName.package p - | UserProgram u -> FQConstantName.userProgram u module FQFnName = @@ -127,31 +87,12 @@ module Darklang = $"PACKAGE.{p.owner}.{modulesPart}.{namePart}{versionPart}" - let userProgram - (u: LanguageTools.RuntimeTypes.FQFnName.UserProgram) - : String = - let modulesPart = - match u.modules with - | [] -> "" - | modules -> - modules |> Stdlib.String.join "." |> (fun parts -> $"{parts}.") - - let namePart = u.name - - let versionPart = - if u.version == 0L then - "" - else - $"_v{Stdlib.Int64.toString u.version}" - - $"{modulesPart}{namePart}{versionPart}" // TODO rename to fqfnName? let fnName (t: LanguageTools.RuntimeTypes.FQFnName.FQFnName) : String = match t with | Builtin b -> FQFnName.builtIn b | Package p -> FQFnName.package p - | UserProgram u -> FQFnName.userProgram u let typeReference (t: LanguageTools.RuntimeTypes.TypeReference) : String = match t with diff --git a/packages/darklang/stdlib/canvas.dark b/packages/darklang/stdlib/canvas.dark index a3b4073e4c..834888a331 100644 --- a/packages/darklang/stdlib/canvas.dark +++ b/packages/darklang/stdlib/canvas.dark @@ -1,7 +1,5 @@ module Darklang = module Canvas = type Program = - { types: List - dbs: List - fns: List + { dbs: List handlers: List } \ No newline at end of file diff --git a/packages/darklang/stdlib/list.dark b/packages/darklang/stdlib/list.dark index df14bc9a72..19671dd3be 100644 --- a/packages/darklang/stdlib/list.dark +++ b/packages/darklang/stdlib/list.dark @@ -479,4 +479,10 @@ module Darklang = Stdlib.Result.Result.Error Stdlib.List.ChunkBySizeError.SizeMustBeGreaterThanZero else - Stdlib.Result.Result.Ok(Stdlib.List.chunkBySizeHelper size list []) \ No newline at end of file + Stdlib.Result.Result.Ok(Stdlib.List.chunkBySizeHelper size list []) + + + let splitLast (l : List<'a>) : Stdlib.Option.Option * 'a> = + match reverse l with + | [] -> Stdlib.Option.Option.None + | head :: tail -> Stdlib.Option.Option.Some((reverse tail, head)) \ No newline at end of file