Skip to content

Commit

Permalink
Add Compiler::compile_ast
Browse files Browse the repository at this point in the history
Compiling an AST directly was removed in
e8546bb but it turns out that this is
useful in some cases, particularly for tools like `koto-ls` that want to
process an AST after checking that it compiles correctly.
  • Loading branch information
irh committed Jan 8, 2025
1 parent 365aaee commit 220950c
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 6 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@ The Koto project adheres to

## [0.16.0] Unreleased

### Added

#### API

- `Compiler::compile_ast` has been added, useful for tools that want to work with the AST
after checking that it compiles correctly.

### Changed

#### Language
Expand Down
20 changes: 14 additions & 6 deletions crates/bytecode/src/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ use crate::{
};
use circular_buffer::CircularBuffer;
use derive_name::VariantName;
use koto_memory::Ptr;
use koto_parser::{
Ast, AstBinaryOp, AstFor, AstIf, AstIndex, AstNode, AstTry, AstUnaryOp, AstVec, ChainNode,
ConstantIndex, Function, ImportItem, KString, MatchArm, MetaKeyId, Node, Parser, Span,
Expand Down Expand Up @@ -261,13 +260,24 @@ pub struct Compiler {
}

impl Compiler {
/// Compiles a Koto script using the provided settings, returning a compiled [Chunk]
/// Compiles a script using the provided settings, returning a compiled [Chunk]
pub fn compile(
script: &str,
script_path: Option<KString>,
settings: CompilerSettings,
) -> Result<Ptr<Chunk>> {
) -> Result<Chunk> {
let ast = Parser::parse(script)?;
let mut result = Self::compile_ast(ast, script_path, settings)?;
result.debug_info.source = script.to_string();
Ok(result)
}

/// Compiles an [Ast] using the provided settings, returning a compiled [Chunk]
pub fn compile_ast(
ast: Ast,
script_path: Option<KString>,
settings: CompilerSettings,
) -> Result<Chunk> {
let mut compiler = Compiler {
settings,
..Default::default()
Expand All @@ -284,16 +294,14 @@ impl Compiler {
return compiler.error(ErrorKind::ResultingBytecodeIsTooLarge(compiler.bytes.len()));
}

compiler.debug_info.source = script.to_string();

let result = Chunk {
bytes: compiler.bytes,
constants: ast.consume_constants(),
path: script_path,
debug_info: compiler.debug_info,
};

Ok(result.into())
Ok(result)
}

fn compile_node(
Expand Down
1 change: 1 addition & 0 deletions crates/bytecode/src/module_loader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ impl ModuleLoader {
settings: CompilerSettings,
) -> Result<Ptr<Chunk>, ModuleLoaderError> {
Compiler::compile(script, script_path.clone(), settings)
.map(Ptr::from)
.map_err(|e| ModuleLoaderError::from_compiler_error(e, script, script_path))
}

Expand Down

0 comments on commit 220950c

Please sign in to comment.