Skip to content

Commit

Permalink
Copy external imports around
Browse files Browse the repository at this point in the history
  • Loading branch information
dusty-phillips committed Aug 27, 2024
1 parent 9b13594 commit caf1e11
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 1 deletion.
2 changes: 2 additions & 0 deletions src/compiler.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@ pub fn compile_module(glance_module: glance.Module) -> String {

pub fn compile_program(program: program.GleamProgram) -> program.CompiledProgram {
program.CompiledProgram(
source_directory: program.source_directory,
main_module: dict.get(program.modules, program.main_module)
|> result.try(fn(mod) { mod.functions |> has_main_function })
|> result.replace(program.main_module |> string.drop_right(6))
|> option.from_result,
modules: program.modules
|> dict.map_values(fn(_key, value) { compile_module(value) }),
external_import_files: program.external_import_files,
)
}

Expand Down
36 changes: 35 additions & 1 deletion src/compiler/program.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,24 @@ import gleam/dict
import gleam/list
import gleam/option
import gleam/result
import gleam/set
import simplifile

pub type GleamProgram {
GleamProgram(
source_directory: String,
main_module: String,
modules: dict.Dict(String, glance.Module),
external_import_files: set.Set(String),
)
}

pub type CompiledProgram {
CompiledProgram(
source_directory: String,
main_module: option.Option(String),
modules: dict.Dict(String, String),
external_import_files: set.Set(String),
)
}

Expand All @@ -40,7 +44,12 @@ pub fn load_program(
|> result.try(fn(_) { find_entrypoint(source_directory) })
|> result.try(fn(entrypoint) {
load_module(
GleamProgram(source_directory, entrypoint, dict.new()),
GleamProgram(
source_directory,
entrypoint,
dict.new(),
external_import_files: set.new(),
),
entrypoint,
)
})
Expand Down Expand Up @@ -109,5 +118,30 @@ fn add_module(
GleamProgram(
..program,
modules: dict.insert(program.modules, module_path, module_contents),
external_import_files: set.union(
python_external_modules(module_contents.functions),
program.external_import_files,
),
)
}

fn python_external_modules(
functions: List(glance.Definition(glance.Function)),
) -> set.Set(String) {
list.filter_map(functions, fn(definition) {
list.find_map(definition.attributes, identify_python_external_attribute)
})
|> set.from_list
}

fn identify_python_external_attribute(
attribute: glance.Attribute,
) -> Result(String, Nil) {
case attribute {
glance.Attribute(
"external",
[glance.Variable("python"), glance.String(module), ..],
) -> Ok(module <> ".py")
_ -> Error(Nil)
}
}
2 changes: 2 additions & 0 deletions src/errors.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ pub type Error {
FileWriteError(path: String, error: simplifile.FileError)
DeleteError(path: String, error: simplifile.FileError)
MkdirError(path: String, error: simplifile.FileError)
CopyFileError(src: String, dst: String, error: simplifile.FileError)
GlanceParseError(error: glance.Error, module: String, contents: String)
}

Expand All @@ -20,6 +21,7 @@ pub fn format_error(error: Error) -> String {
FileWriteError(filename, _) -> "Unable to write " <> filename
DeleteError(filename, _) -> "Unable to delete " <> filename
MkdirError(filename, _) -> "Unable to mkdir " <> filename
CopyFileError(src, dst, _) -> "Unable to copy " <> src <> " to " <> dst
GlanceParseError(error, filename, contents) ->
internal.format_glance_error(error, filename, contents)
}
Expand Down
9 changes: 9 additions & 0 deletions src/macabre.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import filepath
import gleam/dict
import gleam/io
import gleam/result
import gleam/set
import output

pub fn main() {
Expand All @@ -31,13 +32,21 @@ fn write_program(
program: program.CompiledProgram,
build_directory: String,
) -> Result(Nil, errors.Error) {
// TODO: would use make this more pleasant?
build_directory
|> output.delete
|> result.try(fn(_) { output.create_directory(build_directory) })
|> result.try(fn(_) { output.write_prelude_file(build_directory) })
|> result.try(fn(_) {
output.write_py_main(build_directory, program.main_module)
})
|> result.try(fn(_) {
output.copy_externals(
build_directory,
program.source_directory,
program.external_import_files |> set.to_list,
)
})
|> result.try(fn(_) {
dict.fold(program.modules, Ok(Nil), fn(state, name, module) {
result.try(state, fn(_) {
Expand Down
19 changes: 19 additions & 0 deletions src/output.gleam
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import errors
import filepath
import gleam/io
import gleam/list
import gleam/option
import gleam/result
import python_prelude
Expand Down Expand Up @@ -67,3 +68,21 @@ pub fn create_directory(path) -> Result(Nil, errors.Error) {
simplifile.create_directory(path)
|> result.map_error(errors.MkdirError(path, _))
}

pub fn copy_externals(
build_directory: String,
source_directory: String,
files: List(String),
) -> Result(Nil, errors.Error) {
list.fold(files, Ok(Nil), fn(state, file) {
case state {
Ok(Nil) -> {
let src = filepath.join(source_directory, file)
let dst = filepath.join(build_directory, file)
simplifile.copy_file(src, dst)
|> result.map_error(errors.CopyFileError(src, dst, _))
}
Error(error) -> Error(error)
}
})
}

0 comments on commit caf1e11

Please sign in to comment.