diff --git a/backend/src/LibExecution/ProgramTypesToDarkTypes.fs b/backend/src/LibExecution/ProgramTypesToDarkTypes.fs index 348ebcb348..73fdbb068c 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 ] @@ -946,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) -> @@ -986,7 +989,7 @@ 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) | DEnum(_, _, [], "CUnit", []) -> PT.Const.CUnit 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/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 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 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 diff --git a/packages/darklang/languageTools/writtenTypesToProgramTypes.dark b/packages/darklang/languageTools/writtenTypesToProgramTypes.dark index e06050f17c..0fa803aa9c 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,11 @@ 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 _ -> + // 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(