Skip to content

Commit c969c0b

Browse files
committed
Merge remote-tracking branch 'origin/main' into feat/trait-system-improvements
# Conflicts: # docs/pages/specs/syntax/types/function.md
2 parents 7194625 + 3450109 commit c969c0b

58 files changed

Lines changed: 3564 additions & 1389 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ resolver = "2"
44

55
[workspace.package]
66
description = "Edge Language Compiler Workspace"
7-
version = "0.1.17"
7+
version = "0.1.18"
88
edition = "2021"
99
rust-version = "1.85"
1010
license = "MIT"

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,10 @@ edgec check examples/counter.edge
8484
# Print the contract ABI as JSON
8585
edgec --emit abi examples/counter.edge
8686
# [{"type":"function","name":"increment","inputs":[],"outputs":[],"stateMutability":"view"}, ...]
87+
88+
# Standard JSON I/O (for tool integration — reads from stdin, writes to stdout)
89+
echo '{"language":"Edge","sources":{"counter.edge":{"content":"..."}}}' | edgec standard-json
90+
# {"sources":{"counter.edge":{"id":0}},"contracts":{"counter.edge":{"Counter":{"abi":[...],"evm":{"bytecode":{"object":"604d..."},...}}}}}
8791
```
8892

8993
### Example: counter contract

bin/edgec/src/cli.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ pub enum Commands {
5858
Lsp,
5959
/// Parse a file and print AST
6060
Parse(FileArgs),
61+
/// Compile using standard JSON I/O (reads stdin, writes stdout)
62+
#[command(name = "standard-json")]
63+
StandardJson,
6164
}
6265

6366
/// Arguments for file-based subcommands
@@ -75,6 +78,7 @@ impl Cli {
7578
Some(Commands::Lex(args)) => Self::lex(args, self.std_path),
7679
Some(Commands::Lsp) => Self::lsp(),
7780
Some(Commands::Parse(args)) => Self::parse(args, self.std_path),
81+
Some(Commands::StandardJson) => Self::standard_json(),
7882
None => {
7983
if let Some(file) = self.file {
8084
Self::compile(
@@ -258,4 +262,26 @@ impl Cli {
258262

259263
Ok(())
260264
}
265+
266+
fn standard_json() -> Result<()> {
267+
use std::io::Read;
268+
let mut input_str = String::new();
269+
std::io::stdin().read_to_string(&mut input_str)?;
270+
let output =
271+
match serde_json::from_str::<edge_driver::standard_json::StandardJsonInput>(&input_str)
272+
{
273+
Ok(input) => edge_driver::standard_json::compile_standard_json(input),
274+
Err(e) => edge_driver::standard_json::StandardJsonOutput {
275+
errors: vec![edge_driver::standard_json::OutputError {
276+
kind: "Error".into(),
277+
severity: "error".into(),
278+
message: format!("invalid standard JSON input: {e}"),
279+
formatted_message: format!("invalid standard JSON input: {e}"),
280+
}],
281+
..Default::default()
282+
},
283+
};
284+
println!("{}", serde_json::to_string_pretty(&output)?);
285+
Ok(())
286+
}
261287
}

crates/driver/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ thiserror = { workspace = true }
2222
tracing = { workspace = true }
2323
indexmap = { workspace = true }
2424
tiny-keccak = { workspace = true }
25+
serde = { workspace = true, features = ["derive"] }
26+
serde_json = { workspace = true }
2527

2628
[dev-dependencies]
2729
edge-parser = { workspace = true }

crates/driver/README.md

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# edge-driver
22

3-
Compiler driver that orchestrates the full Edge compilation pipeline. Reads source files and runs each phase in sequence: lex, parse, type-check, lower to IR, and emit EVM bytecode.
3+
Compiler driver that orchestrates the full Edge compilation pipeline. Reads source files and runs each phase in sequence: lex, parse, type-check, lower to IR, and emit EVM bytecode. The `standard_json` module provides a Solidity-compatible standard JSON I/O interface so that build tools like Foundry can drive `edgec` with a single JSON blob on stdin.
44

55
## Pipeline Position
66

@@ -25,6 +25,9 @@ source -> lexer -> parser -> AST -> typeck -> IR -> codegen -> driver -> bytecod
2525
- **`CompilerConfig`** -- Input file path, output path, emit kind, optimization level, verbose flag
2626
- **`EmitKind`** -- What the compiler should produce: `Tokens`, `Ast`, `Abi`, or `Bytecode`
2727
- **`Session`** -- Per-compilation state: config, source text, and accumulated diagnostics
28+
- **`StandardJsonInput`** -- Deserialized standard JSON request (sources, settings)
29+
- **`StandardJsonOutput`** -- Serialized standard JSON response (contracts, errors)
30+
- **`compile_standard_json`** -- Compiles all sources from a `StandardJsonInput` and returns a `StandardJsonOutput`
2831

2932
## Usage
3033

@@ -45,6 +48,17 @@ if let Some(abi) = &output.abi {
4548
}
4649
```
4750

51+
The `compile_standard_json` function accepts a `StandardJsonInput` and returns a `StandardJsonOutput` containing ABI and bytecode for every contract in the input. Errors are reported inside the output rather than as Rust-level failures.
52+
53+
```rust,no_run
54+
use edge_driver::standard_json::{compile_standard_json, StandardJsonInput};
55+
56+
let json_str = r#"{"language":"Edge","sources":{"counter.edge":{"content":"..."}}}"#;
57+
let input: StandardJsonInput = serde_json::from_str(json_str).unwrap();
58+
let output = compile_standard_json(input);
59+
println!("{}", serde_json::to_string_pretty(&output).unwrap());
60+
```
61+
4862
## Integration
4963

5064
- **Input**: `.edge` source file on disk

crates/driver/src/compiler.rs

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -157,20 +157,24 @@ impl Compiler {
157157
CompileError::TypeCheckErrors
158158
})?;
159159

160-
// ABI extraction — return early if that's all the user requested
160+
// ABI extraction — always compute so downstream consumers (e.g. standard-json)
161+
// can access the ABI alongside bytecode.
162+
let abi: Vec<edge_typeck::AbiEntry> = checked
163+
.contracts
164+
.iter()
165+
.flat_map(|c| edge_typeck::extract_abi(c, &checked.events))
166+
.collect();
167+
168+
// Return early if ABI is all the user requested
161169
if emit == EmitKind::Abi {
162-
let mut all_entries = Vec::new();
163-
for contract in &checked.contracts {
164-
all_entries.extend(edge_typeck::extract_abi(contract, &checked.events));
165-
}
166170
return Ok(CompileOutput {
167171
tokens: None,
168172
ast: None,
169173
ir: None,
170174
bytecode: None,
171175
bytecodes: None,
172176
asm: None,
173-
abi: Some(all_entries),
177+
abi: Some(abi),
174178
});
175179
}
176180

@@ -307,7 +311,7 @@ impl Compiler {
307311
bytecode: last_bytecode,
308312
bytecodes: Some(all_bytecodes),
309313
asm: None,
310-
abi: None,
314+
abi: Some(abi),
311315
})
312316
}
313317

@@ -622,4 +626,9 @@ impl Compiler {
622626
pub const fn session(&self) -> &Session {
623627
&self.session
624628
}
629+
630+
/// Get a mutable reference to the session
631+
pub const fn session_mut(&mut self) -> &mut Session {
632+
&mut self.session
633+
}
625634
}

crates/driver/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
pub mod compiler;
66
pub mod config;
77
pub mod session;
8+
pub mod standard_json;
89

910
/// Embedded standard library sources, generated by build.rs.
1011
/// Maps module key (e.g. `"tokens/erc20"`) to `.edge` source text.

0 commit comments

Comments
 (0)