parser: revision 1 done; super dirty
This commit is contained in:
20
examples/factorial
Normal file
20
examples/factorial
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
ENTRY 22
|
||||||
|
LOAD -3
|
||||||
|
CONST 2
|
||||||
|
LT
|
||||||
|
BRF 10
|
||||||
|
CONST 1
|
||||||
|
RET
|
||||||
|
LOAD -3
|
||||||
|
LOAD -3
|
||||||
|
CONST 1
|
||||||
|
SUB
|
||||||
|
CALL 0 1
|
||||||
|
MULT
|
||||||
|
RET
|
||||||
|
CONST 12
|
||||||
|
CALL 0 1
|
||||||
|
IPRINT
|
||||||
|
CONST 10
|
||||||
|
PRINT
|
||||||
|
HALT
|
76
src/main.rs
76
src/main.rs
@@ -2,14 +2,45 @@ use std::fs::File;
|
|||||||
use std::io;
|
use std::io;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
use std::env;
|
use std::env;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
const EXEC: [(i32, (&'static str, i32)); 1] = [
|
const EXEC_RPR: [(&'static str, i32); 28] = [
|
||||||
(0, ("add", 0))
|
("entry", 1),
|
||||||
|
("add", 0),
|
||||||
|
("sub", 0),
|
||||||
|
("mult", 0),
|
||||||
|
("div", 0),
|
||||||
|
("mod", 0),
|
||||||
|
("lt", 0),
|
||||||
|
("eq", 0),
|
||||||
|
("gt", 0),
|
||||||
|
("br", 1),
|
||||||
|
("brt", 1),
|
||||||
|
("brf", 1),
|
||||||
|
("const", 1),
|
||||||
|
("load", 1),
|
||||||
|
("gload", 1),
|
||||||
|
("store", 1),
|
||||||
|
("gstore", 1),
|
||||||
|
("print", 0),
|
||||||
|
("pop", 0),
|
||||||
|
("halt", 0),
|
||||||
|
("leq", 0),
|
||||||
|
("geq", 0),
|
||||||
|
("call", 2),
|
||||||
|
("ret", 0),
|
||||||
|
("iprint", 0),
|
||||||
|
("fetch", 0),
|
||||||
|
("inc", 0),
|
||||||
|
("dec", 0)
|
||||||
];
|
];
|
||||||
|
|
||||||
struct Exec {
|
fn build_opcodes() -> HashMap<&'static str, (i64, i32)> {
|
||||||
arguments: i32,
|
let mut opcodes = HashMap::new();
|
||||||
name: String
|
for (i, elem) in EXEC_RPR.iter().enumerate() {
|
||||||
|
opcodes.insert((*elem).0, (i as i64, (*elem).1));
|
||||||
|
}
|
||||||
|
return opcodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn usage(pname: String) {
|
fn usage(pname: String) {
|
||||||
@@ -23,14 +54,41 @@ fn get_contents(fname: String) -> Result<String, io::Error> {
|
|||||||
Ok(contents)
|
Ok(contents)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse(contents: String) -> Vec<Exec> {
|
fn parse(contents: String, opcodes: HashMap<&'static str, (i64, i32)>) -> Vec<i64> {
|
||||||
return vec![];
|
let mut code = Vec::new();
|
||||||
|
for line in contents.split("\n") {
|
||||||
|
if line.is_empty() { continue }
|
||||||
|
let tmp = line.split(" ").map(String::from).collect::<Vec<String>>();
|
||||||
|
let (op, args) = tmp.split_first().expect("malformatted line!");
|
||||||
|
let opcode: &str = &op.to_lowercase()[..];
|
||||||
|
match opcodes.get(opcode) {
|
||||||
|
Some(v) => {
|
||||||
|
code.push(v.0);
|
||||||
|
if args.len() as i32 != v.1 {
|
||||||
|
panic!("Expected {} arguments for opcode {}, but got {}!", v.1, opcode, args.len());
|
||||||
|
}
|
||||||
|
for elem in args {
|
||||||
|
match elem.parse::<i64>() {
|
||||||
|
Ok(v) => code.push(v),
|
||||||
|
_ => panic!("Could not parse argument {} to instruction {} as number!", elem, opcode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => panic!("Do not know opcode {}!", opcode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return code
|
||||||
}
|
}
|
||||||
|
|
||||||
fn exec(instructions: Vec<Exec>) {
|
fn exec(instructions: Vec<i64>) {
|
||||||
|
for elem in instructions {
|
||||||
|
println!("{}", elem);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
let opcodes = build_opcodes();
|
||||||
|
|
||||||
let args: Vec<_> = env::args().collect();
|
let args: Vec<_> = env::args().collect();
|
||||||
|
|
||||||
if args.len() != 2 {
|
if args.len() != 2 {
|
||||||
@@ -49,7 +107,7 @@ fn main() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let parsed = parse(contents);
|
let parsed = parse(contents, opcodes);
|
||||||
|
|
||||||
let execd = exec(parsed);
|
let execd = exec(parsed);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user