Skip to content

Commit

Permalink
"4:55pm. Right now I am dwelling in my thoughts.
Browse files Browse the repository at this point in the history
The next step here is really to just make use of the prepass. I have everything I need to put it into action. At this point I can also start thinking how to follow through with the results into the peval and codegen.

5pm. I could stop here for the day, but let me just do one more thing. Let me put this to use.

```fs
    let build_file (s : SupervisorState) module_target =
        match inputs s module_target with
        | Ok x ->
            let a,b = package.Run(x)

            failwith "TODO"
        | Error _ -> failwith "TODO"
```

Let me start with this.

Where should I put the package stream? I am not sure. I'll leave this decision for later. If I can't decide, I'll just shunt it into the `SupervisorState`. It is not important right now.

Let me just sketch out this function. First thing's first - I need to take care of the error cases for the return of run.

```fs
    let build_file (s : SupervisorState) module_target =
        match inputs s module_target with
        | Ok x ->
            let a,b = package.Run(x)
            match a with
            | Some x -> // TODO: Don't forget the inner error.
                failwith "TOOD"
            | None -> failwith "TODO"
        | Error _ -> failwith "TODO"
```

I'll leave these as TODOs. What I really want to see is whether I am missing some inputs to the peval function.

```fs
let peval (env : TopEnv) (x : E) =
```

```fs
type TopEnv = {
    prototypes_instances : Dictionary<GlobalId * GlobalId, E>
    nominals : Dictionary<GlobalId, Nominal>
    }
```

```fs
type Nominal = {|body : T; id : GlobalId; name : string|} ConsedNode // TODO: When doing incremental compilation, make the `body` field a weak reference.
```

Let me take a short break here.

5:35pm. I am back.

```fs
type PrepassPackageEnv = {
    prototypes_instances : Map<int, Map<GlobalId * GlobalId,E>>
    nominals : Map<int, Map<GlobalId,{|body : T; name : string|}>>
    term : Map<string,E>
    ty : Map<string,T>
    has_errors : bool
    }
```

Based on this, I can easily produce the inputs. Just turn it into a top env to merge all the package instances and then move from there.

...Let me turn off the router. I really want to call it a day, but let me do just one more thing.

```fs
    let build_file (s : SupervisorState) module_target =
        match inputs s module_target with
        | Ok x ->
            let a,b = package.Run(x)
            match a with
            | Some x ->
                x >>- fun x ->
                    if x.has_errors then Error "There are type errors in at least one module."
                    else
                        failwith ""
            | None -> Job.result (Error "Cannot find the target module.")
        | Error x -> Job.result (Error x)
```

Don't want to throw exceptions for this.

Now let me get the inputs. First let me get the main.

6:05pm. Done with lunch.

```fs
    let build_file (s : SupervisorState) module_target =
        match inputs s module_target with
        | Ok x ->
            let a,b = package.Run(x) // TODO: Take care of the stream.
            match a with
            | Some x ->
                x >>- fun x ->
                    if x.has_errors then Error "There are type errors in at least one module."
                    else
                        match Map.tryFind "main" x.term with
                        | Some main ->
                            let top_env = package_to_top x
                            let prototypes_instances = Dictionary(top_env.prototypes_instances)
                            let nominals =
                                let t = HashConsing.HashConsTable()
                                let d = Dictionary()
                                top_env.nominals |> Map.iter (fun k v -> d.Add(k, t.Add {|v with id=k|}))
                                d
                            Ok(PartEval.Main.peval {prototypes_instances=prototypes_instances; nominals=nominals} main)
                        | None -> Error <| sprintf "Cannot find the main function in module. Path: %s" module_target
            | None -> Job.result (Error <| sprintf "Cannot find the target module. Path: %s" module_target)
        | Error x -> Job.result (Error x)
```

I'll close the day with this. This actually typechecks.

Tomorrow, I will follow through with this into codegen and deal with that package stream. Then once I have that, I'll actually be able to compile Spiral code. That would be impressive wouldn't it?

Once I get to that point I'll be able to start testing.

Right now, the typechecker and the prepass are in very good shape as far as their efficiency and composability are concerned.

I did an A grade job there. The build file and partial evaluation that is tied to it do have a lot of optimization work left for them. But as per plan I will leave that for future versions of Spiral that have a lot of code needing to be compiled for them.

For the prepass I could just reuse the typechecking machinery, but peval will require new things.

It is far more important that I test everything out produce some quality libraries first. Optimizing peval will be tough, but I'll be able to do it if I can allocate a few week to it."
  • Loading branch information
mrakgr committed Dec 2, 2020
1 parent 12008f7 commit a5b9c90
Showing 1 changed file with 25 additions and 44 deletions.
69 changes: 25 additions & 44 deletions The Spiral Language v0.2 (typechecking)/Supervisor.fs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,30 @@ module Prepass =
let a = Map(order)
let b = Seq.map fst order
Ok(a,b,package_target)
with :? PackageInputsException as e -> Error e.Data
with :? PackageInputsException as e -> Error e.Data0

let build_file (s : SupervisorState) module_target =
match inputs s module_target with
| Ok x ->
let a,b = package.Run(x) // TODO: Take care of the stream.
match a with
| Some x ->
x >>- fun x ->
if x.has_errors then Error "There are type errors in at least one module."
else
match Map.tryFind "main" x.term with
| Some main ->
let top_env = package_to_top x
let prototypes_instances = Dictionary(top_env.prototypes_instances)
let nominals =
let t = HashConsing.HashConsTable()
let d = Dictionary()
top_env.nominals |> Map.iter (fun k v -> d.Add(k, t.Add {|v with id=k|}))
d
Ok(PartEval.Main.peval {prototypes_instances=prototypes_instances; nominals=nominals} main)
| None -> Error <| sprintf "Cannot find the main function in module. Path: %s" module_target
| None -> Job.result (Error <| sprintf "Cannot find the target module. Path: %s" module_target)
| Error x -> Job.result (Error x)

type LoadResult =
| LoadModule of package_dir: string * path: RString * Result<TokRes * ParserRes Promise * ModuleStream,string>
Expand Down Expand Up @@ -426,46 +449,4 @@ let main _ =
use __ = queue_server.ReceiveReady.Subscribe(fun x -> x.Queue.Dequeue() |> server.SendMultipartMessage)

poller.Run()
0

open Spiral.PartEval
open Spiral.PartEval.Prepass

//type PrepassFileHierarchy =
// | File of path: RString * name: string option * FilledTop list
// | Directory of name: string * PrepassFileHierarchy list

//let prepass_compile (package_ids : PersistentHashMap<string,int>)
// (packages : Map<string, {|links : Map<string,{|name : string|}>; files : PrepassFileHierarchy list |}>)
// (package_order : string seq) =
// Seq.fold (fun package_envs package_name ->
// let package_id = package_ids.[package_name]
// let package = packages.[package_name]
// let package_env = package.links |> Map.fold (fun s k v -> in_module v.name (union s (Map.find k package_envs))) package_env_default

// let rec elem (top_env, module_id) = function
// | ValidatedFileHierarchy.File((_,path),name,_) ->
// let r = results.[path]
// let _,top_env_adds =
// List.fold (fun (top_env, top_env_adds) x ->
// match (prepass package_id module_id top_env).filled_top x with
// | AOpen adds -> Prepass.union adds top_env, top_env_adds
// | AInclude adds -> Prepass.union adds top_env, Prepass.union adds top_env_adds
// ) (top_env, top_env_empty) r
// let top_env_adds =
// match name with
// | None -> top_env_adds
// | Some name -> Prepass.in_module name top_env_adds
// (module_id+1), top_env_adds
// | ValidatedFileHierarchy.Directory(name,l) ->
// let _,module_id,top_env_adds = list (top_env,module_id) l
// module_id, top_env_adds
// and list (top_env,module_id) l =
// List.fold (fun (top_env,module_id,top_env_adds) x ->
// let module_id, top_env_adds' = elem (top_env, module_id) x
// Prepass.union top_env_adds' top_env, module_id, Prepass.union top_env_adds' top_env_adds
// ) (top_env,module_id,top_env_empty) l

// let _,_,top_env_adds = list (package_to_top package_env,0) package.files
// Map.add package_name (top_to_package package_id top_env_adds package_env) package_envs
// ) Map.empty package_order
0

0 comments on commit a5b9c90

Please sign in to comment.