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
2 changes: 1 addition & 1 deletion Naggum.Backend/Reader.fs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ let string =
let normalChar = satisfy (fun c -> c <> '\"')
between (pstring "\"") (pstring "\"") (manyChars normalChar) |>> (fun str -> str :> obj) |>> Object

let symChars = (anyOf "+-*/=<>!?.") //chars that are valid in the symbol name
let symChars = (anyOf "+-*/=<>!?._") //chars that are valid in the symbol name
let symbol = (many1Chars (letter <|> digit <|> symChars)) |>> Symbol
let atom = (pnumber <|> string <|> symbol) |>> Atom
let listElement = choice [ atom; list ]
Expand Down
23 changes: 9 additions & 14 deletions Naggum.Compiler/FormGenerator.fs
Original file line number Diff line number Diff line change
Expand Up @@ -59,19 +59,19 @@ type SequenceGenerator(context:Context,typeBuilder:TypeBuilder,seq:SExp list, gf
List.map (fun (sexp) -> List.head ((gf.MakeGenerator context sexp).ReturnTypes())) seq

type BodyGenerator(context : Context,
methodBuilder : MethodBuilder,
resultType : Type,
body : SExp list,
gf : IGeneratorFactory) =
let rec genBody (ilGen : ILGenerator) (body : SExp list) =
match body with
| [] ->
ilGen.Emit(OpCodes.Ldnull)
if resultType <> typeof<Void> then
ilGen.Emit(OpCodes.Ldnull)
| [last] ->
let gen = gf.MakeGenerator context last
let stackType = List.head <| gen.ReturnTypes ()
let returnType = methodBuilder.ReturnType
gen.Generate ilGen
match (stackType, returnType) with
match (stackType, resultType) with
| (s, r) when s = typeof<Void> && r = typeof<Void> -> ()
| (s, r) when s = typeof<Void> && r <> typeof<Void> -> ilGen.Emit OpCodes.Ldnull
| (s, r) when s <> typeof<Void> && r = typeof<Void> -> ilGen.Emit OpCodes.Pop
Expand All @@ -86,18 +86,13 @@ type BodyGenerator(context : Context,
interface IGenerator with
member __.Generate ilGen =
genBody ilGen body
member this.ReturnTypes () =
member __.ReturnTypes () =
match body with
|[] -> [typeof<System.Void>]
|somelist ->
let tail_type = (gf.MakeGenerator context (List.rev body |> List.head)).ReturnTypes()
if tail_type = [typeof<System.Void>] then
[typeof<obj>]
else tail_type
| [] -> [typeof<System.Void>]
| _ -> (gf.MakeGenerator context (List.rev body |> List.head)).ReturnTypes()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lol, doesn't List really have last or something like that? %)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you, that's a good question. I'm almost sure that List module had no such function back the days of F# 2.0. But now it actually has! So I'll review the code and use it where possible. I'll create a separate issue for that.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool!


type LetGenerator(context : Context,
typeBuilder : TypeBuilder,
methodBuilder : MethodBuilder,
resultType : Type,
bindings:SExp,
body : SExp list,
gf : IGeneratorFactory) =
Expand All @@ -118,7 +113,7 @@ type LetGenerator(context : Context,
ilGen.Emit (OpCodes.Stloc,local)
| other -> failwithf "In let bindings: Expected: (name (form))\nGot: %A\n" other
| other -> failwithf "In let form: expected: list of bindings\nGot: %A" other
let bodyGen = new BodyGenerator (scope_subctx, methodBuilder, body, gf) :> IGenerator
let bodyGen = new BodyGenerator (scope_subctx, resultType, body, gf) :> IGenerator
bodyGen.Generate ilGen
ilGen.EndScope()
member this.ReturnTypes () =
Expand Down
16 changes: 6 additions & 10 deletions Naggum.Compiler/GeneratorFactory.fs
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,11 @@ type GeneratorFactory(typeBuilder : TypeBuilder,
| [Symbol "if"; condition; if_true] -> // reduced if form
new ReducedIfGenerator(context,typeBuilder,condition,if_true,this) :> IGenerator
| Symbol "let" :: bindings :: body -> // let form
new LetGenerator(context,
typeBuilder,
methodBuilder,
bindings,
body,
this) :> IGenerator
upcast new LetGenerator(context,
typeof<Void>,
bindings,
body,
this)
| [Symbol "quote"; quotedExp] ->
new QuoteGenerator(context,typeBuilder,quotedExp,this) :> IGenerator
| Symbol "new" :: Symbol typeName :: args ->
Expand Down Expand Up @@ -102,10 +101,7 @@ type GeneratorFactory(typeBuilder : TypeBuilder,
new SequenceGenerator(context,typeBuilder,seq,(this :> IGeneratorFactory))

member private this.makeBodyGenerator(context: Context,body:SExp list) =
new BodyGenerator(context,
methodBuilder,
body,
(this :> IGeneratorFactory))
new BodyGenerator(context, methodBuilder.ReturnType, body, this)

interface IGeneratorFactory with
member this.MakeGenerator context sexp =
Expand Down
4 changes: 2 additions & 2 deletions Naggum.Compiler/Naggum.Compiler.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
<WarningLevel>3</WarningLevel>
<PlatformTarget>AnyCPU</PlatformTarget>
<DocumentationFile>bin\Debug\Naggum.Compiler.XML</DocumentationFile>
<StartArguments>..\tests\test.naggum</StartArguments>
<StartArguments>..\..\..\tests\test.naggum</StartArguments>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
Expand Down Expand Up @@ -105,4 +105,4 @@
<Target Name="AfterBuild">
</Target>
-->
</Project>
</Project>
4 changes: 2 additions & 2 deletions Naggum.Test/CompilerTest.fs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ type CompilerTest() =
static let testExtension = "naggum"
static let resultExtension = "result"
static let executableExtension = "exe"

static let directory = Path.Combine ("..", "..", "..", "tests")
static let filenames = [@"comment"; @"test"]
static let filenames = [@"comment"; @"test"; "let-funcall"]

static member private RunTest testName =
let basePath = Path.Combine(directory, testName)
Expand Down
2 changes: 2 additions & 0 deletions Naggum.sln
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Test programs", "Test progr
ProjectSection(SolutionItems) = preProject
tests\comment.naggum = tests\comment.naggum
tests\comment.result = tests\comment.result
tests\let-funcall.naggum = tests\let-funcall.naggum
tests\let-funcall.result = tests\let-funcall.result
tests\test.naggum = tests\test.naggum
tests\test.result = tests\test.result
EndProjectSection
Expand Down
12 changes: 12 additions & 0 deletions tests/let-funcall.naggum
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
(defun test-let ()
(System.Console.Write "Let: ")
(let ((ok "OK"))
(System.Console.WriteLine ok)))
(System.Console.WriteLine "Naggum test suite")

(let ((thread (System.Threading.Thread.get_CurrentThread))
(culture (System.Globalization.CultureInfo.get_InvariantCulture)))
(System.Console.WriteLine "Setting up an environment...")
(call set_CurrentCulture thread culture))

(test-let)
3 changes: 3 additions & 0 deletions tests/let-funcall.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Naggum test suite
Setting up an environment...
Let: OK
5 changes: 5 additions & 0 deletions tests/test.naggum
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@

(System.Console.WriteLine "Naggum test suite")

(let ((thread (System.Threading.Thread.get_CurrentThread))
(culture (System.Globalization.CultureInfo.get_InvariantCulture)))
(System.Console.WriteLine "Setting up an environment...")
(call set_CurrentCulture thread culture))

(test-funcall "OK")
(test-conditionals)
(test-let)
Expand Down
1 change: 1 addition & 0 deletions tests/test.result
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
Naggum test suite
Setting up an environment...
Functions: OK
Conditionals:
Reduced if: OK
Expand Down