From 1a7c1360306c2ca2e9e502bb050e4acb73c8afac Mon Sep 17 00:00:00 2001 From: Ocean Date: Tue, 3 Sep 2024 14:14:04 +0000 Subject: [PATCH 1/7] Fill in some missing fromDT cases --- backend/src/LibExecution/ProgramTypesToDarkTypes.fs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/backend/src/LibExecution/ProgramTypesToDarkTypes.fs b/backend/src/LibExecution/ProgramTypesToDarkTypes.fs index 348ebcb348..aeff78b978 100644 --- a/backend/src/LibExecution/ProgramTypesToDarkTypes.fs +++ b/backend/src/LibExecution/ProgramTypesToDarkTypes.fs @@ -921,6 +921,9 @@ module Expr = Exception.raiseInternal "Invalid record update" [ "update", update ]) PT.ERecordUpdate(uint64 id, fromDT record, updates) + | DEnum(_, _, [], "EConstant", [ DInt64 id; name ]) -> + PT.EConstant(uint64 id, NameResolution.fromDT FQConstantName.fromDT name) + | e -> Exception.raiseInternal "Invalid Expr" [ "e", e ] @@ -987,6 +990,7 @@ module Const = | DEnum(_, _, [], "CBool", [ DBool b ]) -> PT.Const.CBool b | DEnum(_, _, [], "CString", [ DString s ]) -> PT.Const.CString s | DEnum(_, _, [], "CChar", [ DChar c ]) -> PT.Const.CChar c + | DEnum(_, _, [], "CChar", [ DString c ]) -> PT.Const.CChar c | DEnum(_, _, [], "CFloat", [ sign; DString w; DString f ]) -> PT.Const.CFloat(Sign.fromDT sign, w, f) | DEnum(_, _, [], "CUnit", []) -> PT.Const.CUnit From 71870186ea33adbd6eefd24b4d1eee1f9a798433 Mon Sep 17 00:00:00 2001 From: Ocean Date: Tue, 3 Sep 2024 14:14:59 +0000 Subject: [PATCH 2/7] Fix name resolver for Builtin constants --- packages/darklang/languageTools/nameResolver.dark | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/darklang/languageTools/nameResolver.dark b/packages/darklang/languageTools/nameResolver.dark index 53cbfa0d87..f12d5ef07d 100644 --- a/packages/darklang/languageTools/nameResolver.dark +++ b/packages/darklang/languageTools/nameResolver.dark @@ -171,14 +171,14 @@ module Darklang = |> Stdlib.String.join "." if owner == "Builtin" && modules == [] then - if builtinThingExists nameForLookup then + if builtinThingExists name.name then (ProgramTypes.FQConstantName.Builtin { name = name.name version = name.version }) |> ProgramTypes.FQConstantName.FQConstantName.Builtin |> Stdlib.Result.Result.Ok else - Error() + Stdlib.Result.Result.Error() else let find = pm.findConstant From 5b53880336ebd1ce530ecdf1fedc406c8d750aff Mon Sep 17 00:00:00 2001 From: Ocean Date: Tue, 3 Sep 2024 14:15:59 +0000 Subject: [PATCH 3/7] Refactor parsePipeEnum and parseMPEnum functions --- .../languageTools/parser/matchPattern.dark | 7 +++- .../languageTools/parser/pipeExpr.dark | 39 ++++++------------- 2 files changed, 18 insertions(+), 28 deletions(-) diff --git a/packages/darklang/languageTools/parser/matchPattern.dark b/packages/darklang/languageTools/parser/matchPattern.dark index e81998c38c..b111c68f2e 100644 --- a/packages/darklang/languageTools/parser/matchPattern.dark +++ b/packages/darklang/languageTools/parser/matchPattern.dark @@ -256,7 +256,12 @@ module Darklang = (findNodeByFieldName node "enum_fields") |> Stdlib.Option.map (fun enumFieldsNode -> enumFieldsNode.children - |> Stdlib.List.map (fun pat -> parseMatchPattern pat) + |> Stdlib.List.chunkBySize 2L + |> Builtin.unwrap + |> Stdlib.List.map (fun contentSymbolPair -> + match contentSymbolPair with + | [ contentNode; symbol ] -> parseMatchPattern contentNode + | [ contentNode ] -> parseMatchPattern contentNode) |> Stdlib.Result.collect) |> Stdlib.Option.withDefault ([] |> Stdlib.Result.Result.Ok) diff --git a/packages/darklang/languageTools/parser/pipeExpr.dark b/packages/darklang/languageTools/parser/pipeExpr.dark index a67b56dbeb..8913db1cad 100644 --- a/packages/darklang/languageTools/parser/pipeExpr.dark +++ b/packages/darklang/languageTools/parser/pipeExpr.dark @@ -105,33 +105,18 @@ module Darklang = let parsePipeEnum (node: ParsedNode) : Stdlib.Result.Result = - let typeNameNode = findField node "type_name" - let symbolDotNode = findField node "symbol_dot" - let caseNameNode = findField node "case_name" - - let enumFieldsNode = - (findNodeByFieldName node "enum_fields") - |> Stdlib.Option.map (fun enumFieldsNode -> - enumFieldsNode.children - |> Stdlib.List.map (fun fieldNode -> Expr.parse fieldNode) - |> Stdlib.Result.collect) - - |> Stdlib.Option.withDefault (Stdlib.Result.Result.Ok []) - - match typeNameNode, symbolDotNode, caseNameNode, enumFieldsNode with - | Ok typeNameNode, Ok symbolDotNode, Ok caseNameNode, Ok enumFieldsNode -> - let typeName = typeNameNode.text |> Stdlib.String.split "." - - (WrittenTypes.PipeExpr.EPipeEnum( - node.range, - (typeNameNode.range, typeName), - (caseNameNode.range, caseNameNode.text), - enumFieldsNode, - symbolDotNode.range - )) - |> Stdlib.Result.Result.Ok - - | _ -> createUnparseableError node + baseParseEnum + Expr.parse + node + (fun (range, typeName, caseName, enumFields, symbolDot) -> + (WrittenTypes.PipeExpr.EPipeEnum( + range, + typeName, + caseName, + enumFields, + symbolDot + )) + |> Stdlib.Result.Result.Ok) let parsePipeFnCall From 3b16b0b65558cd00049c4de0dbc4d827f1a30f88 Mon Sep 17 00:00:00 2001 From: Ocean Date: Tue, 3 Sep 2024 14:18:29 +0000 Subject: [PATCH 4/7] Change QualifiedConstOrFn.toPT to return a Result type --- .../languageTools/writtenTypesToProgramTypes.dark | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/packages/darklang/languageTools/writtenTypesToProgramTypes.dark b/packages/darklang/languageTools/writtenTypesToProgramTypes.dark index e06050f17c..e06cb6eee0 100644 --- a/packages/darklang/languageTools/writtenTypesToProgramTypes.dark +++ b/packages/darklang/languageTools/writtenTypesToProgramTypes.dark @@ -62,7 +62,7 @@ module Darklang = (owner: String) (currentModule: List) (c: WrittenTypes.QualifiedConstantOrFnIdentifier) - : ConstOrFn = + : Stdlib.Result.Result> = let nameToResolve = Stdlib.List.append (Stdlib.List.map c.modules (fun (id, _) -> id.name)) @@ -85,10 +85,10 @@ module Darklang = (WrittenTypes.Name.Unresolved(c.range, nameToResolve)) match isFn with - | Ok _ -> isFn |> ConstOrFn.Fn + | Ok _ -> isFn |> ConstOrFn.Fn |> Stdlib.Result.Result.Ok | Error _ -> match isConstant with - | Ok _ -> isConstant |> ConstOrFn.Const + | Ok _ -> isConstant |> ConstOrFn.Const |> Stdlib.Result.Result.Ok | Error _ -> isConstant module Fn = @@ -501,8 +501,10 @@ module Darklang = Identifiers.QualifiedConstOrFn.toPT onMissing pm owner currentModule id match constantOrFn with - | Const c -> ProgramTypes.Expr.EConstant(gid (), c) - | Fn f -> ProgramTypes.Expr.EFnName(gid (), f) + | Ok(Const c) -> ProgramTypes.Expr.EConstant(gid (), c) + | Ok(Fn f) -> ProgramTypes.Expr.EFnName(gid (), f) + | Error _ -> + ProgramTypes.Expr.EVariable (gid ()) constantOrFn.constantOrFn.name | EFieldAccess(_, expr, (_, fieldName), _) -> ProgramTypes.Expr.EFieldAccess( From 268456a5bf6b7a99753d25d6d37a4342b7b56f04 Mon Sep 17 00:00:00 2001 From: Ocean Date: Tue, 3 Sep 2024 14:26:01 +0000 Subject: [PATCH 5/7] Handle empty vars in field access, dictionaries, and lambdas + fix handling backticks in dictionaries --- backend/tests/Tests/NewParser.Tests.fs | 2 +- .../darklang/languageTools/parser/core.dark | 19 +++++++++++++++++-- .../darklang/languageTools/parser/expr.dark | 12 ++++++++++-- 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/backend/tests/Tests/NewParser.Tests.fs b/backend/tests/Tests/NewParser.Tests.fs index 81b99b810a..aeab97707c 100644 --- a/backend/tests/Tests/NewParser.Tests.fs +++ b/backend/tests/Tests/NewParser.Tests.fs @@ -617,7 +617,7 @@ let exprs = t "dict with double_backtick_identifier" "Dict { ``Content-Length`` = 1L }" - "Dict { ``Content-Length`` = 1L }" + "Dict { Content-Length = 1L }" [] [] [] diff --git a/packages/darklang/languageTools/parser/core.dark b/packages/darklang/languageTools/parser/core.dark index 4b54e92239..fea58085df 100644 --- a/packages/darklang/languageTools/parser/core.dark +++ b/packages/darklang/languageTools/parser/core.dark @@ -45,6 +45,9 @@ module Darklang = let getText (node: ParsedNode) : String = node.text let getRange (node: ParsedNode) : Range = node.range + let emptyVar = "___" + let nameOrBlank (v: String) : String = if v == emptyVar then "" else v + let findNodeByFieldName (node: ParsedNode) (fieldName: String) @@ -228,7 +231,13 @@ module Darklang = | [ dictPairNode; _separator ] -> let keyNode = findAndParseRequired dictPairNode "key" (fun node -> - (node.range, Parser.getText node) |> Stdlib.Result.Result.Ok) + match node.typ with + | "double_backtick_identifier" -> + let key = node.text |> Stdlib.String.slice 2L -2L + (node.range, key) |> Stdlib.Result.Result.Ok + | _ -> + (node.range, nameOrBlank (Parser.getText node)) + |> Stdlib.Result.Result.Ok) let symbolEqualsNode = findField dictPairNode "symbol_equals" @@ -242,7 +251,13 @@ module Darklang = | [ dictPairNode ] -> let keyNode = findAndParseRequired dictPairNode "key" (fun node -> - (node.range, Parser.getText node) |> Stdlib.Result.Result.Ok) + match node.typ with + | "double_backtick_identifier" -> + let key = node.text |> Stdlib.String.slice 2L -2L + (node.range, key) |> Stdlib.Result.Result.Ok + | _ -> + (node.range, nameOrBlank (Parser.getText node)) + |> Stdlib.Result.Result.Ok) let symbolEqualsNode = findField dictPairNode "symbol_equals" diff --git a/packages/darklang/languageTools/parser/expr.dark b/packages/darklang/languageTools/parser/expr.dark index e7477c71fa..81fc9fb0f4 100644 --- a/packages/darklang/languageTools/parser/expr.dark +++ b/packages/darklang/languageTools/parser/expr.dark @@ -490,7 +490,7 @@ module Darklang = (WrittenTypes.Expr.EFieldAccess( node.range, expr, - (field.range, field.text), + (field.range, nameOrBlank field.text), symbolDot.range )) |> Stdlib.Result.Result.Ok @@ -597,8 +597,15 @@ module Darklang = )) |> Stdlib.Result.Result.Ok) - | _ -> createUnparseableError child + | _ -> createUnparseableError node + // Helper function for parseLambda + let skipEmptyVar (node: List) : List = + node + |> Stdlib.List.filter (fun c -> + match c.typ with + | "let_pattern" when c.text == "___" -> false + | _ -> true) let parseLambda (node: ParsedNode) @@ -609,6 +616,7 @@ module Darklang = match findField node "pats" with | Ok paramsNode -> paramsNode.children + |> skipEmptyVar |> Stdlib.List.map (fun pat -> parseLetPattern pat) |> Stdlib.Result.collect From 3ede8fc16540a8effeb259f62493a901c1948aaf Mon Sep 17 00:00:00 2001 From: Ocean Date: Tue, 3 Sep 2024 15:34:15 +0000 Subject: [PATCH 6/7] Add a CLEANUP comment + minor fixes --- backend/src/LibExecution/ProgramTypesToDarkTypes.fs | 1 - .../darklang/languageTools/writtenTypesToProgramTypes.dark | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/src/LibExecution/ProgramTypesToDarkTypes.fs b/backend/src/LibExecution/ProgramTypesToDarkTypes.fs index aeff78b978..c9678ef30e 100644 --- a/backend/src/LibExecution/ProgramTypesToDarkTypes.fs +++ b/backend/src/LibExecution/ProgramTypesToDarkTypes.fs @@ -989,7 +989,6 @@ module Const = | DEnum(_, _, [], "CUInt128", [ DUInt128 i ]) -> PT.Const.CUInt128 i | DEnum(_, _, [], "CBool", [ DBool b ]) -> PT.Const.CBool b | DEnum(_, _, [], "CString", [ DString s ]) -> PT.Const.CString s - | DEnum(_, _, [], "CChar", [ DChar c ]) -> PT.Const.CChar c | DEnum(_, _, [], "CChar", [ DString c ]) -> PT.Const.CChar c | DEnum(_, _, [], "CFloat", [ sign; DString w; DString f ]) -> PT.Const.CFloat(Sign.fromDT sign, w, f) diff --git a/packages/darklang/languageTools/writtenTypesToProgramTypes.dark b/packages/darklang/languageTools/writtenTypesToProgramTypes.dark index e06cb6eee0..0fa803aa9c 100644 --- a/packages/darklang/languageTools/writtenTypesToProgramTypes.dark +++ b/packages/darklang/languageTools/writtenTypesToProgramTypes.dark @@ -504,7 +504,8 @@ module Darklang = | Ok(Const c) -> ProgramTypes.Expr.EConstant(gid (), c) | Ok(Fn f) -> ProgramTypes.Expr.EFnName(gid (), f) | Error _ -> - ProgramTypes.Expr.EVariable (gid ()) constantOrFn.constantOrFn.name + // CLEANUP: Rethink this solution. It was added to allow failure during the first pass of parsing, where names aren't yet resolved + ProgramTypes.Expr.EVariable (gid ()) id.constantOrFn.name | EFieldAccess(_, expr, (_, fieldName), _) -> ProgramTypes.Expr.EFieldAccess( From 939ecc89acab6d574c5a5fd2cd111f46027ecf17 Mon Sep 17 00:00:00 2001 From: Ocean Date: Tue, 3 Sep 2024 16:03:04 +0000 Subject: [PATCH 7/7] Small fix in Const.toDT fn --- backend/src/LibExecution/ProgramTypesToDarkTypes.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/LibExecution/ProgramTypesToDarkTypes.fs b/backend/src/LibExecution/ProgramTypesToDarkTypes.fs index c9678ef30e..73fdbb068c 100644 --- a/backend/src/LibExecution/ProgramTypesToDarkTypes.fs +++ b/backend/src/LibExecution/ProgramTypesToDarkTypes.fs @@ -949,7 +949,7 @@ module Const = | PT.Const.CUInt128 i -> "CUInt128", [ DUInt128 i ] | PT.Const.CFloat(sign, w, f) -> "CFloat", [ Sign.toDT sign; DString w; DString f ] - | PT.Const.CChar c -> "CChar", [ DChar c ] + | PT.Const.CChar c -> "CChar", [ DString c ] | PT.Const.CString s -> "CString", [ DString s ] | PT.Const.CTuple(first, second, theRest) ->