Skip to content

Instantly share code, notes, and snippets.

@ebb
Created April 5, 2018 20:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ebb/9a63d312cb97502def036e7f02d45004 to your computer and use it in GitHub Desktop.
Save ebb/9a63d312cb97502def036e7f02d45004 to your computer and use it in GitHub Desktop.
Block
Let config (parse_command_line)
In
Let {paths packages} (parse_packages config.root_path)
In
Let program (compile packages)
In
(emit config.root_path paths program)
Where
Define (parse_command_line)
Let usage "usage: 84 <program>"
In
Let {}
When [OS.argc != 2]
(OS.die usage)
End
In
Let root_path (OS.argv 1)
In
Let config {: root_path}
In
config
Define (parse_packages root_path)
Let STRING_SET (SEARCH.SET STRING.compare)
In
Define (parse_file path)
Let file_name (STRING.append path ".84")
In
Let text
Let file (OS.file_open file_name)
In
Let text (OS.file_read_all file)
Do (OS.file_close file)
In
text
In
Match (PARSE.file text)
| 'succeed.expr expr
| 'fail.{message i}
Begin
(SYNTAX_ERROR.show file_name text message i)
(OS.die "Compilation failed.")
End
;
Define (push_paths stack filter paths)
(LIST.reduce paths {stack filter}
Func {{stack filter} path}
Match (STRING_SET.search filter path)
| 'just._ {stack filter}
| 'nothing {[path & stack] (STRING_SET.insert filter path)}
;)
In
Let packages
Let packages 'nil
Let stack [root_path & 'nil]
Let filter (STRING_SET.new [root_path & 'nil])
In
Iterate {packages stack filter}
Match stack
| 'nil packages
| 'cons.{path stack}
Let expr (parse_file path)
In
Let imports (PACKAGE.gather_imports expr)
In
Let package {: path : imports : expr}
Let {stack filter} (push_paths stack filter imports)
In
(Continue [package & packages] stack filter)
;
In
Let packages (PACKAGE.sort_by_dependence packages)
In
Let paths (LIST.map packages [Func package package.path])
In
{paths packages}
Define (compile packages)
Let exprs (LIST.map packages [Func package package.expr])
In
Let exprs
(LIST.map exprs
[COMPILE.elaborate_recursion >> COMPILE.collect_free_variables])
In
Let modules (COMPILE.lift_functions exprs)
In
Let packages
(LIST.map (LIST.zip packages modules)
Func {package {init functions}}
{
: path package.path
: imports package.imports
: init
: functions
})
In
Let program (COMPILE.collect_constants packages)
In
Let program (C.elaborate program)
In
program
Define (emit root_path paths program)
Let c_file (OS.file_create (STRING.append root_path ".c"))
Let d_file (OS.file_create (STRING.append root_path ".c.d"))
In
Let {}
Let w (BUFIO.new_writer d_file 1024)
In
Begin
(BUFIO.write_all w (STRING.append root_path ".c:"))
(LIST.for_each paths
Func path
(BUFIO.write_all w
(STRING.concat [Right " " & path & ".84" & 'nil])))
(BUFIO.write_all w "\n")
(BUFIO.flush w)
End
Let {}
Let w (BUFIO.new_writer c_file [1024 * 1024])
In
Define (write string)
(BUFIO.write w string 0 (STRING.length string))
In
Begin
(C.emit program write)
(BUFIO.flush w)
End
In
Begin
(OS.file_close c_file)
(OS.file_close d_file)
End
Where
Let BUFIO Package "bufio"
Let C Package "c"
Let COMPILE Package "compile"
Let LIST Package "list"
Let OS Package "os"
Let PACKAGE Package "package"
Let PARSE Package "parse"
Let SEARCH Package "search"
Let STDIO Package "stdio"
Let STRING Package "string"
Let SYNTAX_ERROR Package "syntax_error"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment