Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions IronKernel.Tests/CliTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,34 @@ let ``managed artifact runs without Kernel source or runtime compilation`` () =
finally
Directory.Delete(root, true)

[<Fact>]
let ``managed artifact preserves exponent-form double literals`` () =
let root = Path.Combine(Path.GetTempPath(), "ironkernel-managed-exponent-" + Guid.NewGuid().ToString("N"))
let script = Path.Combine(root, "exponent.ikr")
let output = Path.Combine(root, "publish")
Directory.CreateDirectory(root) |> ignore
try
File.WriteAllText(script, "1e20")
let artifact =
match compileFileToManagedArtifact Minimal script output with
| Choice1Of2 error -> failwith (showError error)
| Choice2Of2 path -> path

let startInfo = ProcessStartInfo("dotnet")
startInfo.UseShellExecute <- false
startInfo.RedirectStandardError <- true
startInfo.RedirectStandardOutput <- true
startInfo.ArgumentList.Add artifact
use child = Process.Start startInfo
let stdout = child.StandardOutput.ReadToEnd()
let stderr = child.StandardError.ReadToEnd()
child.WaitForExit()
Assert.Equal(0, child.ExitCode)
Assert.Equal("<obj 1E+20 : Double>", stdout.Trim())
Assert.Equal("", stderr.Trim())
finally
Directory.Delete(root, true)

[<Fact>]
let ``managed artifact supports definitions and lazy conditionals`` () =
let root = Path.Combine(Path.GetTempPath(), "ironkernel-managed-control-flow-" + Guid.NewGuid().ToString("N"))
Expand Down
15 changes: 13 additions & 2 deletions IronKernel/StaticCompiler.fs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,18 @@ module StaticCompiler =

let private quote (value: string) = Text.Json.JsonSerializer.Serialize(value, stringLiteralOptions)

let private doubleLiteral (value: double) =
if Double.IsNaN value then "System.Double.NaN"
elif Double.IsPositiveInfinity value then "System.Double.PositiveInfinity"
elif Double.IsNegativeInfinity value then "System.Double.NegativeInfinity"
else
let literal = value.ToString("R", CultureInfo.InvariantCulture)
if literal.Contains('.') then literal
else
let exponentIndex = literal.IndexOfAny([|'E'; 'e'|])
if exponentIndex >= 0 then literal.Insert(exponentIndex, ".0")
else literal + ".0"

let private sequenceOptions values =
let mutable result = Some []
for value in List.rev values do
Expand Down Expand Up @@ -50,8 +62,7 @@ module StaticCompiler =
| Obj (:? float32 as value) ->
Some("Obj(box " + value.ToString("R", CultureInfo.InvariantCulture) + "f)")
| Obj (:? double as value) ->
let literal = value.ToString("R", CultureInfo.InvariantCulture)
Some("Obj(box " + (if literal.Contains('.') then literal else literal + ".0") + ")")
Some("Obj(box " + doubleLiteral value + ")")
| Vector values ->
values
|> Array.map emitValue
Expand Down
Loading