Skip to content

Commit d24eb0c

Browse files
committed
zkDSL compiler: make it posible to use placeholders in files
1 parent 9a14b10 commit d24eb0c

File tree

15 files changed

+198
-257
lines changed

15 files changed

+198
-257
lines changed

crates/lean_compiler/src/lib.rs

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::collections::BTreeMap;
2+
13
use lean_vm::*;
24

35
use crate::{
@@ -12,8 +14,41 @@ pub mod ir;
1214
mod lang;
1315
mod parser;
1416

15-
pub fn compile_program(filepath: &str, program: String) -> Bytecode {
16-
let parsed_program = parse_program(filepath, &program).unwrap();
17+
#[derive(Debug, Clone)]
18+
pub enum ProgramSource {
19+
Raw(String),
20+
Filepath(String),
21+
}
22+
23+
impl ProgramSource {
24+
pub fn get_content(&self, flags: &CompilationFlags) -> Result<String, std::io::Error> {
25+
match self {
26+
ProgramSource::Raw(src) => {
27+
let mut result = src.clone();
28+
for (key, value) in flags.replacements.iter() {
29+
result = result.replace(key, value);
30+
}
31+
Ok(result)
32+
}
33+
ProgramSource::Filepath(fp) => {
34+
let mut result = std::fs::read_to_string(fp)?;
35+
for (key, value) in flags.replacements.iter() {
36+
result = result.replace(key, value);
37+
}
38+
Ok(result)
39+
}
40+
}
41+
}
42+
}
43+
44+
#[derive(Debug, Clone, Default)]
45+
pub struct CompilationFlags {
46+
/// useful for placeholder replacements in source code
47+
pub replacements: BTreeMap<String, String>,
48+
}
49+
50+
pub fn compile_program_with_flags(input: &ProgramSource, flags: CompilationFlags) -> Bytecode {
51+
let parsed_program = parse_program(input, flags).unwrap();
1752
// println!("Parsed program: {}", parsed_program.to_string());
1853
let function_locations = parsed_program.function_locations.clone();
1954
let source_code = parsed_program.source_code.clone();
@@ -33,14 +68,17 @@ pub fn compile_program(filepath: &str, program: String) -> Bytecode {
3368
// compiled
3469
}
3570

71+
pub fn compile_program(input: &ProgramSource) -> Bytecode {
72+
compile_program_with_flags(input, CompilationFlags::default())
73+
}
74+
3675
pub fn compile_and_run(
37-
filepath: &str,
38-
program: String,
76+
source: &ProgramSource,
3977
(public_input, private_input): (&[F], &[F]),
4078
no_vec_runtime_memory: usize, // size of the "non-vectorized" runtime memory
4179
profiler: bool,
4280
) {
43-
let bytecode = compile_program(filepath, program);
81+
let bytecode = compile_program(source);
4482
let summary = execute_bytecode(
4583
&bytecode,
4684
(public_input, private_input),

crates/lean_compiler/src/parser/parsers/mod.rs

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use crate::parser::{
33
error::{ParseResult, SemanticError},
44
grammar::{ParsePair, Rule},
55
};
6+
use crate::{CompilationFlags, ProgramSource};
67
use std::collections::{BTreeMap, BTreeSet};
78

89
pub mod expression;
@@ -37,20 +38,28 @@ pub struct ParseContext {
3738
pub imported_filepaths: BTreeSet<String>,
3839
/// Next unused file ID
3940
pub next_file_id: usize,
41+
/// Compilation flags
42+
pub flags: CompilationFlags,
4043
}
4144

4245
impl ParseContext {
43-
pub fn new(current_filepath: &str, current_source_code: &str) -> Self {
44-
Self {
46+
pub fn new(input: &ProgramSource, flags: CompilationFlags) -> Result<Self, SemanticError> {
47+
let current_source_code = input.get_content(&flags).unwrap();
48+
let (current_filepath, imported_filepaths) = match input {
49+
ProgramSource::Raw(_) => ("<raw_input>".to_string(), BTreeSet::new()),
50+
ProgramSource::Filepath(fp) => (fp.clone(), [fp.clone()].into_iter().collect()),
51+
};
52+
Ok(Self {
4553
constants: BTreeMap::new(),
4654
const_arrays: BTreeMap::new(),
4755
trash_var_count: 0,
48-
current_filepath: current_filepath.to_string(),
56+
current_filepath,
4957
current_file_id: 0,
50-
imported_filepaths: BTreeSet::new(),
51-
current_source_code: current_source_code.to_string(),
58+
imported_filepaths,
59+
current_source_code,
5260
next_file_id: 1,
53-
}
61+
flags,
62+
})
5463
}
5564

5665
/// Adds a scalar constant to the context.
@@ -103,12 +112,6 @@ impl ParseContext {
103112
}
104113
}
105114

106-
impl Default for ParseContext {
107-
fn default() -> Self {
108-
Self::new("<string>", "")
109-
}
110-
}
111-
112115
/// Core trait for all parsers in the system.
113116
pub trait Parse<T>: Sized {
114117
/// Parses the given input into the target type.

crates/lean_compiler/src/parser/parsers/program.rs

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use super::function::FunctionParser;
22
use super::literal::ConstantDeclarationParser;
33
use crate::{
4+
CompilationFlags, ProgramSource,
45
lang::{Program, SourceLocation},
56
parser::{
67
error::{ParseError, ParseResult, SemanticError},
@@ -55,14 +56,9 @@ impl Parse<Program> for ProgramParser {
5556
let file_id = ctx.get_next_file_id();
5657
ctx.current_file_id = file_id;
5758
filepaths.insert(file_id, filepath.clone());
58-
let input = std::fs::read_to_string(filepath.clone()).map_err(|_| {
59-
SemanticError::with_context(
60-
format!("Imported file not found: {filepath}"),
61-
"import declaration",
62-
)
63-
})?;
64-
source_code.insert(file_id, input.clone());
65-
let subprogram = parse_program_helper(filepath.as_str(), input.as_str(), ctx)?;
59+
ctx.current_source_code = ProgramSource::Filepath(filepath).get_content(&ctx.flags).unwrap();
60+
source_code.insert(file_id, ctx.current_source_code.clone());
61+
let subprogram = parse_program_helper(ctx)?;
6662
functions.extend(subprogram.functions);
6763
function_locations.extend(subprogram.function_locations);
6864
source_code.extend(subprogram.source_code);
@@ -138,22 +134,17 @@ impl Parse<String> for ImportStatementParser {
138134
}
139135
}
140136

141-
fn parse_program_helper(filepath: &str, input: &str, ctx: &mut ParseContext) -> Result<Program, ParseError> {
137+
fn parse_program_helper(ctx: &mut ParseContext) -> Result<Program, ParseError> {
142138
// Preprocess source to remove comments
143-
let processed_input = lexer::preprocess_source(input);
139+
let processed_input = lexer::preprocess_source(&ctx.current_source_code);
144140

145141
// Parse grammar into AST nodes
146142
let program_pair = parse_source(&processed_input)?;
147143

148144
// Parse into semantic structures
149-
ctx.current_filepath = filepath.to_string();
150-
ctx.current_source_code = input.to_string();
151-
ctx.imported_filepaths.insert(filepath.to_string());
152145
ProgramParser.parse(program_pair, ctx)
153146
}
154147

155-
pub fn parse_program(filepath: &str, input: &str) -> Result<Program, ParseError> {
156-
let mut ctx = ParseContext::new(filepath, input);
157-
ctx.imported_filepaths.insert(filepath.to_string());
158-
parse_program_helper(filepath, input, &mut ctx)
148+
pub fn parse_program(input: &ProgramSource, flags: CompilationFlags) -> Result<Program, ParseError> {
149+
parse_program_helper(&mut ParseContext::new(input, flags)?)
159150
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import "asdfasdfadsfasdf.snark";
2+
3+
fn main() {
4+
return;
5+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import "bar.snark";
2+
import "foo.snark";
3+
4+
fn bar() {
5+
return;
6+
}
7+
8+
fn main() {
9+
return;
10+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import "bar.snark";
2+
import "foo.snark";
3+
4+
const FOO = 5;
5+
6+
fn main() {
7+
return;
8+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import "foo.snark";
2+
import "foo.snark";
3+
4+
fn main() {
5+
return;
6+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import "circular_import.snark";
2+
3+
fn main() {
4+
return;
5+
}

crates/lean_compiler/tests/program_5.snark

Whitespace-only changes.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import "bar.snark";
2+
import "foo.snark";
3+
4+
fn main() {
5+
x = bar(FOO);
6+
assert x == 6;
7+
return;
8+
}

0 commit comments

Comments
 (0)