This commit is contained in:
2026-03-13 16:09:44 +01:00
parent 2d1e41a3e8
commit fde4a123fd
4 changed files with 343 additions and 4 deletions
Generated
+177
View File
@@ -5,3 +5,180 @@ version = 4
[[package]] [[package]]
name = "archforge" name = "archforge"
version = "0.1.0" version = "0.1.0"
dependencies = [
"pest",
"pest_derive",
]
[[package]]
name = "block-buffer"
version = "0.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
dependencies = [
"generic-array",
]
[[package]]
name = "cfg-if"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
[[package]]
name = "cpufeatures"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280"
dependencies = [
"libc",
]
[[package]]
name = "crypto-common"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a"
dependencies = [
"generic-array",
"typenum",
]
[[package]]
name = "digest"
version = "0.10.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
dependencies = [
"block-buffer",
"crypto-common",
]
[[package]]
name = "generic-array"
version = "0.14.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
dependencies = [
"typenum",
"version_check",
]
[[package]]
name = "libc"
version = "0.2.183"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d"
[[package]]
name = "memchr"
version = "2.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
[[package]]
name = "pest"
version = "2.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0848c601009d37dfa3430c4666e147e49cdcf1b92ecd3e63657d8a5f19da662"
dependencies = [
"memchr",
"ucd-trie",
]
[[package]]
name = "pest_derive"
version = "2.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "11f486f1ea21e6c10ed15d5a7c77165d0ee443402f0780849d1768e7d9d6fe77"
dependencies = [
"pest",
"pest_generator",
]
[[package]]
name = "pest_generator"
version = "2.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8040c4647b13b210a963c1ed407c1ff4fdfa01c31d6d2a098218702e6664f94f"
dependencies = [
"pest",
"pest_meta",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "pest_meta"
version = "2.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89815c69d36021a140146f26659a81d6c2afa33d216d736dd4be5381a7362220"
dependencies = [
"pest",
"sha2",
]
[[package]]
name = "proc-macro2"
version = "1.0.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
dependencies = [
"proc-macro2",
]
[[package]]
name = "sha2"
version = "0.10.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
dependencies = [
"cfg-if",
"cpufeatures",
"digest",
]
[[package]]
name = "syn"
version = "2.0.117"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "typenum"
version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb"
[[package]]
name = "ucd-trie"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971"
[[package]]
name = "unicode-ident"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
[[package]]
name = "version_check"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
+2
View File
@@ -4,3 +4,5 @@ version = "0.1.0"
edition = "2024" edition = "2024"
[dependencies] [dependencies]
pest = "2.8.6"
pest_derive = "2.8.6"
+26 -3
View File
@@ -1,21 +1,44 @@
#[derive(Debug)]
pub struct Program { pub struct Program {
pub functions: Vec<Function>, pub functions: Vec<Function>,
pub statements: Vec<Statement>,
} }
#[derive(Debug)]
pub struct Function { pub struct Function {
pub name: String, pub name: String,
pub params: Vec<String>, pub params: Vec<String>,
pub body: Vec<Instruction>, pub body: Vec<Statement>,
} }
#[derive(Debug)]
pub enum Statement {
Instruction(Instruction),
PointerAssign { left: Reg, right: Reg },
FunctionCall(FunctionCall),
}
#[derive(Debug)]
pub struct Instruction { pub struct Instruction {
pub opcode: String, pub opcode: String,
pub operands: Vec<Operand>, pub operands: Vec<Operand>,
} }
#[derive(Debug)]
pub struct FunctionCall {
pub name: String,
pub args: Vec<Operand>,
}
#[derive(Debug)]
pub enum Operand { pub enum Operand {
Global(String), Reg(Reg),
Local(String),
Number(i64), Number(i64),
Pointer(Box<Operand>), Pointer(Box<Operand>),
} }
#[derive(Debug)]
pub enum Reg {
Global(String),
Local(String),
}
+137
View File
@@ -1 +1,138 @@
pub mod ast; pub mod ast;
use pest::iterators::Pair;
use pest_derive::Parser;
use ast::*;
#[derive(Parser)]
#[grammar = "parser/grammar.pest"] // relative to src
pub struct ForgeParser;
use pest::Parser;
pub fn parse_program(src: &str) -> Result<Program, pest::error::Error<Rule>> {
let mut pairs = ForgeParser::parse(Rule::program, src)?;
let program = pairs.next().unwrap();
let mut functions = Vec::new();
let mut statements = Vec::new();
for pair in program.into_inner() {
match pair.as_rule() {
Rule::function_def => functions.push(parse_function(pair)),
Rule::instruction | Rule::pointer_assign | Rule::function_call => {
statements.push(parse_statement(pair))
}
_ => {}
}
}
Ok(Program {
functions,
statements,
})
}
fn parse_function(pair: Pair<Rule>) -> Function {
let mut inner = pair.into_inner();
let name = inner.next().unwrap().as_str().to_string();
let mut params = Vec::new();
let mut body = Vec::new();
for p in inner {
match p.as_rule() {
Rule::param_list => {
for param in p.into_inner() {
params.push(param.as_str().to_string());
}
}
Rule::block => {
for stmt in p.into_inner() {
body.push(parse_statement(stmt));
}
}
_ => {}
}
}
Function { name, params, body }
}
fn parse_statement(pair: Pair<Rule>) -> Statement {
match pair.as_rule() {
Rule::instruction => Statement::Instruction(parse_instruction(pair)),
Rule::pointer_assign => {
let mut inner = pair.into_inner();
let left = parse_reg(inner.next().unwrap());
let right = parse_reg(inner.next().unwrap());
Statement::PointerAssign { left, right }
}
Rule::function_call => Statement::FunctionCall(parse_function_call(pair)),
_ => unreachable!(),
}
}
fn parse_instruction(pair: Pair<Rule>) -> Instruction {
let mut inner = pair.into_inner();
let opcode = inner.next().unwrap().as_str().to_string();
let mut operands = Vec::new();
if let Some(list) = inner.next() {
for op in list.into_inner() {
operands.push(parse_operand(op));
}
}
Instruction { opcode, operands }
}
fn parse_function_call(pair: Pair<Rule>) -> FunctionCall {
let mut inner = pair.into_inner();
let name = inner.next().unwrap().as_str().to_string();
let mut args = Vec::new();
if let Some(list) = inner.next() {
for arg in list.into_inner() {
args.push(parse_operand(arg));
}
}
FunctionCall { name, args }
}
fn parse_operand(pair: Pair<Rule>) -> Operand {
match pair.as_rule() {
Rule::number => Operand::Number(pair.as_str().parse().unwrap()),
Rule::global_reg | Rule::local_reg => Operand::Reg(parse_reg(pair)),
Rule::pointer_expr => {
let inner = pair.into_inner().next().unwrap();
Operand::Pointer(Box::new(parse_operand(inner)))
}
_ => unreachable!(),
}
}
fn parse_reg(pair: Pair<Rule>) -> Reg {
match pair.as_rule() {
Rule::global_reg => Reg::Global(pair.as_str()[1..].to_string()),
Rule::local_reg => Reg::Local(pair.as_str()[1..].to_string()),
_ => unreachable!(),
}
}