Compare commits

..

No commits in common. "8b45ae7a035f42ee458cc9572a15257d6e8e51a1" and "366ac05225d04a1a41cd04faadd51fbba5c82145" have entirely different histories.

16 changed files with 173 additions and 227 deletions

40
Cargo.lock generated
View file

@ -33,9 +33,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "clap"
version = "3.2.17"
version = "3.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29e724a68d9319343bb3328c9cc2dfde263f4b3142ee1059a9980580171c954b"
checksum = "a3dbbb6653e7c55cc8595ad3e1f7be8f32aba4eb7ff7f0fd1163d4f3d137c0a9"
dependencies = [
"atty",
"bitflags",
@ -50,9 +50,9 @@ dependencies = [
[[package]]
name = "clap_derive"
version = "3.2.17"
version = "3.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13547f7012c01ab4a0e8f8967730ada8f9fdf419e8b6c792788f39cf4e46eefa"
checksum = "9ba52acd3b0a5c33aeada5cdaa3267cdc7c594a98731d4268cdc1532f4264cb4"
dependencies = [
"heck",
"proc-macro-error",
@ -86,9 +86,9 @@ dependencies = [
[[package]]
name = "either"
version = "1.8.0"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797"
checksum = "3f107b87b6afc2a64fd13cac55fe06d6c8859f12d4b14cbcdd2c67d0976781be"
[[package]]
name = "encode_unicode"
@ -162,9 +162,9 @@ dependencies = [
[[package]]
name = "libc"
version = "0.2.132"
version = "0.2.126"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5"
checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"
[[package]]
name = "num"
@ -253,15 +253,15 @@ dependencies = [
[[package]]
name = "once_cell"
version = "1.13.1"
version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "074864da206b4973b84eb91683020dbefd6a8c3f0f38e054d93954e891935e4e"
checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1"
[[package]]
name = "os_str_bytes"
version = "6.3.0"
version = "6.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ff7415e9ae3fff1225851df9e0d9e4e5479f947619774677a63572e55e80eff"
checksum = "648001efe5d5c0102d8cea768e348da85d90af8ba91f0bea908f157951493cd4"
[[package]]
name = "ppv-lite86"
@ -295,18 +295,18 @@ dependencies = [
[[package]]
name = "proc-macro2"
version = "1.0.43"
version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab"
checksum = "dd96a1e8ed2596c337f8eae5f24924ec83f5ad5ab21ea8e455d3566c69fbcaf7"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.21"
version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804"
dependencies = [
"proc-macro2",
]
@ -361,9 +361,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
[[package]]
name = "syn"
version = "1.0.99"
version = "1.0.98"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "58dbef6ec655055e20b86b15a8cc6d439cca19b667537ac6a1369572d151ab13"
checksum = "c50aef8a904de4c23c788f104b7dddc7d6f79c647c7c8ce4cc8f73eb0ca773dd"
dependencies = [
"proc-macro2",
"quote",
@ -397,9 +397,9 @@ checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb"
[[package]]
name = "unicode-ident"
version = "1.0.3"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4f5b37a154999a8f3f98cc23a628d850e154479cd94decf3414696e12e31aaf"
checksum = "15c61ba63f9235225a22310255a29b806b907c9b8c964bcbd0a2c70f3f2deea7"
[[package]]
name = "unicode-width"

View file

@ -1,23 +1,2 @@
[package]
name = "hence"
version = "0.1.0"
edition = "2021"
[lib]
name = "hence"
path = "src/lib/lib.rs"
[[bin]]
name = "hence"
path = "src/bin/main.rs"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
itertools = "0.10.2"
num-parse = "0.1.2"
clap = { version = "3.2.16", features = ["derive"] }
rhexdump = "0.1.1"
radix_fmt = "1"
rand = "0.8.5"
console = "0.15.1"
[workspace]
members = ["hence"]

View file

@ -26,4 +26,3 @@
| `0x0b` | `alu` | Runs ALU with `tmp`'s value as operator | |
| `0x0c` | `get` | Sets `tmp` to memory at address in `tmp` | |
| `0x0d` | `set` | Sets memory to value at specific address | |

View file

@ -1,4 +1,4 @@
; hence core lib
@ hence core lib
core:
core_mem:
.define CORE_MEM_PRG, (0 * 1024)
@ -40,7 +40,7 @@ core:
.define CORE_ALU_INV, 0x11
.define CORE_ALU_RND, 0x12
; hence standard lib
@ hence standard lib
STD:
.define STD_U8_MAX, 0xff
.define STD_U16_MAX, 0xffff
@ -61,14 +61,87 @@ forth:
ts jump_main
tlr CORE_REG_PC
main:
end_input:
dbg
; set PC to maximum for u16 and therefore stops program execution
ts 0xffff ; load 0xffff into TMP
tlr CORE_REG_PC ; store value of TMP into register PC
main:
@ loop body
loop:
@ read key from stdin
ts CORE_MEM_KEY
get
@ check if key is newline (0x0a)
tlr CORE_REG_D @ store in register D because register A is used later on
tlr CORE_REG_A @ store in register A as input for ALU
ts "\n" @ store newline in TMP
tlr CORE_REG_B @ store newline in register B as input for ALU
ts CORE_ALU_EQ @ ALU equal operation
alu @ run ALU
@ go back to loop start if pressed key is newline
tlr CORE_REG_A @ store result of ALU operation in TMP
@ ts loop @ load memory address of loop start into TMP
ts 0
tls
ts jump_switch
tls
ts end_input
tlrc CORE_REG_PC @ set register PC to loop start address if result is true
pop
tlr CORE_REG_A
ts 0
tlrc CORE_REG_C
@ print out char
tsr CORE_REG_D @ get char
tlr CORE_REG_A @ load char into register A
ts CORE_MEM_CHR @ set TMP to char print memory address
set @ print char
@ increment counter by one
tsr CORE_REG_C
tlr CORE_REG_A
ts 1
tlr CORE_REG_B
ts CORE_ALU_ADD
alu
tlr CORE_REG_C
tlr CORE_REG_A
ts FORTH_MEM_INPUT_SIZE
tlr CORE_REG_B
ts CORE_ALU_LT
alu
tlr CORE_REG_A
ts loop
tlrc CORE_REG_PC
ts "\n"
tlr CORE_REG_A
ts CORE_MEM_CHR
set
tsr CORE_REG_C
tls
dbg
pop
ts 0
tlr CORE_REG_C
ts loop
tlr CORE_REG_PC
@ .std_stop
@ set PC to maximum for u16 and therefore stops program execution
ts 0xffff @ load 0xffff into TMP
tlr CORE_REG_PC @ store value of TMP into register PC
jump_switch:
dbg
.org jump_main
ts main
tlr CORE_REG_PC

Binary file not shown.

View file

@ -1,147 +0,0 @@
@ hence core lib
core:
core_mem:
.define CORE_MEM_PRG, (0 * 1024)
.define CORE_MEM_ST, (32 * 1024)
.define CORE_MEM_MEM, (40 * 1024)
.define CORE_MEM_OUT, (56 * 1024)
.define CORE_MEM_CHR, (56 * 1024 + 1)
.define CORE_MEM_KEY, (56 * 1024 + 2)
core_reg:
.define CORE_REG_PC, 0x0
.define CORE_REG_OPC, 0x1
.define CORE_REG_ARG, 0x2
.define CORE_REG_S, 0x3
.define CORE_REG_SP, 0x4
.define CORE_REG_A, 0x5
.define CORE_REG_B, 0x6
.define CORE_REG_C, 0x7
.define CORE_REG_D, 0x8
core_alu:
.define CORE_ALU_NOT, 0x00
.define CORE_ALU_AND, 0x01
.define CORE_ALU_OR, 0x02
.define CORE_ALU_XOR, 0x03
.define CORE_ALU_LSH, 0x04
.define CORE_ALU_RSH, 0x05
.define CORE_ALU_ADD, 0x06
.define CORE_ALU_SUB, 0x07
.define CORE_ALU_MUL, 0x08
.define CORE_ALU_DIV, 0x09
.define CORE_ALU_CMP, 0x0a
.define CORE_ALU_EQ, 0x0b
.define CORE_ALU_LT, 0x0c
.define CORE_ALU_GT, 0x0d
.define CORE_ALU_LEQ, 0x0e
.define CORE_ALU_GEQ, 0x0f
.define CORE_ALU_BOL, 0x10
.define CORE_ALU_INV, 0x11
.define CORE_ALU_RND, 0x12
@ hence standard lib
STD:
.define STD_U8_MAX, 0xff
.define STD_U16_MAX, 0xffff
.macro std_stop
ts 0xffff
tlr CORE_REG_PC
.macroend
forth:
.define FORTH_MEM_INPUT_SIZE, 16
.define FORTH_MEM_INPUT_DYN_SIZE, CORE_MEM_MEM
.define FORTH_MEM_INPUT_START, (FORTH_MEM_INPUT_DYN_SIZE + 1)
.define FORTH_MEM_INPUT_END, (FORTH_MEM_INPUT_START + FORTH_MEM_INPUT_SIZE)
.define jump_main, (CORE_MEM_ST - 3 - 1)
ts jump_main
tlr CORE_REG_PC
end_input:
dbg
main:
@ loop body
loop:
@ read key from stdin
ts CORE_MEM_KEY
get
@ check if key is newline (0x0a)
tlr CORE_REG_D @ store in register D because register A is used later on
tlr CORE_REG_A @ store in register A as input for ALU
ts "\n" @ store newline in TMP
tlr CORE_REG_B @ store newline in register B as input for ALU
ts CORE_ALU_EQ @ ALU equal operation
alu @ run ALU
@ go back to loop start if pressed key is newline
tlr CORE_REG_A @ store result of ALU operation in TMP
@ ts loop @ load memory address of loop start into TMP
ts 0
tls
ts jump_switch
tls
ts end_input
tlrc CORE_REG_PC @ set register PC to loop start address if result is true
pop
tlr CORE_REG_A
ts 0
tlrc CORE_REG_C
@ print out char
tsr CORE_REG_D @ get char
tlr CORE_REG_A @ load char into register A
ts CORE_MEM_CHR @ set TMP to char print memory address
set @ print char
@ increment counter by one
tsr CORE_REG_C
tlr CORE_REG_A
ts 1
tlr CORE_REG_B
ts CORE_ALU_ADD
alu
tlr CORE_REG_C
tlr CORE_REG_A
ts FORTH_MEM_INPUT_SIZE
tlr CORE_REG_B
ts CORE_ALU_LT
alu
tlr CORE_REG_A
ts loop
tlrc CORE_REG_PC
ts "\n"
tlr CORE_REG_A
ts CORE_MEM_CHR
set
tsr CORE_REG_C
tls
dbg
pop
ts 0
tlr CORE_REG_C
ts loop
tlr CORE_REG_PC
@ .std_stop
@ set PC to maximum for u16 and therefore stops program execution
ts 0xffff @ load 0xffff into TMP
tlr CORE_REG_PC @ store value of TMP into register PC
jump_switch:
dbg
.org jump_main
ts main
tlr CORE_REG_PC

1
hence/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
/target

23
hence/Cargo.toml Normal file
View file

@ -0,0 +1,23 @@
[package]
name = "hence"
version = "0.1.0"
edition = "2021"
[lib]
name = "hence"
path = "src/lib/lib.rs"
[[bin]]
name = "hence"
path = "src/bin/main.rs"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
itertools = "0.10.2"
num-parse = "0.1.2"
clap = { version = "3.2.16", features = ["derive"] }
rhexdump = "0.1.1"
radix_fmt = "1"
rand = "0.8.5"
console = "0.15.1"

View file

@ -69,8 +69,11 @@ fn main() {
);
assembler::assemble(&mut data).unwrap();
if let Some(x) = bin {
File::create(x).unwrap().write_all(&data.program).unwrap();
match bin {
Some(x) => {
File::create(x).unwrap().write_all(&data.program).unwrap();
}
_ => {}
}
if dump {
println!("{}", rhexdump::hexdump(&data.program));

View file

@ -52,7 +52,10 @@ impl assembler::ByteResolvable<assembler::Data> for Arg {
let mut arg: Option<arg::Arg>;
loop {
arg = data.contants.get(&name).cloned();
arg = match data.contants.get(&name) {
Some(a) => Some(a.clone()),
_ => None,
};
match arg {
Some(a) => {
@ -92,7 +95,12 @@ impl assembler::ByteResolvable<assembler::Data> for Arg {
let mut arg: Option<arg::Arg>;
loop {
arg = data.contants.get(&name).cloned();
dbg!(&name);
arg = match data.contants.get(&name) {
Some(a) => Some(a.clone()),
_ => None,
};
dbg!(&arg);
match arg {
Some(a) => {
@ -166,7 +174,7 @@ pub fn parse_binary_expression_arg(tokens: &mut Vec<&&lexer::Token>) -> Result<A
op: parse_binary_operation(args[1]).unwrap(),
};
while !tokens.is_empty() {
while tokens.len() != 0 {
args = tokens.drain(..2).collect();
bin_expr = Arg::BinaryExpression {
left: Box::new(bin_expr),

View file

@ -136,6 +136,20 @@ pub fn assemble(data: &mut Data) -> Result<(), String> {
}
println!("==========");
}
// "define" => {
// let name = match &args[0] {
// arg::Arg::Variable(x) | arg::Arg::String(x) => x,
// _ => return Err(
// "First argument of define macro needs to be a literal-like"
// .to_string(),
// ),
// };
// if data.contants.contains_key(name) {
// return Err(format!("Constant already exists: '{name}'"));
// }
// data.contants.insert(name.to_string(), (&args[1]).clone());
// }
"define" => {
let name = match &args[0] {
arg::Arg::Variable(x) | arg::Arg::String(x) => x,
@ -156,18 +170,13 @@ pub fn assemble(data: &mut Data) -> Result<(), String> {
),
};
let args = match (&args[1..])
.iter()
// .map(|a| match a {
// arg::Arg::Variable(x) => Ok(x.clone()),
// __ => {
// Err("Macro arguments need to be variables".to_string())
// }
// })
.map(|a| {
if let arg::Arg::Variable(x) = a {
Ok(x.clone())
} else {
Err("Macro arguments need to be variables".to_string())
.into_iter()
.map(|a| match a {
arg::Arg::Variable(x) => Ok(x.clone()),
__ => {
return Err(
"Macro arguments need to be variables".to_string()
)
}
})
.collect::<Result<Vec<_>, _>>()

View file

@ -27,7 +27,7 @@ pub struct Data {
impl Data {
pub fn new(program: [u8; 32 * 1024]) -> Self {
Self {
return Self {
program,
tmp: 0,
@ -46,14 +46,14 @@ impl Data {
memory: [0; 16 * 1024],
term: console::Term::stdout(),
}
};
}
pub fn get_memory(&self, address: u16) -> u16 {
if address < (32 * 1024) {
match self.program.get(address as usize) {
Some(val) => *val as u16,
None => 0,
Some(val) => val.clone() as u16,
_ => 0,
}
} else if address < (40 * 1024) {
self.stack[(address - (32 * 1024)) as usize]
@ -67,8 +67,7 @@ impl Data {
}
pub fn set_memory(&mut self, address: u16, value: u16) {
// if address >= (32 * 1024) && address < (40 * 1024) {
if ((32 * 1024)..(40 * 1024)).contains(&address) {
if address >= (32 * 1024) && address < (40 * 1024) {
self.stack[(address - (32 * 1024)) as usize] = value;
} else if address < (40 * 1024) {
self.memory[(address - (40 * 1024)) as usize] = value;
@ -253,7 +252,7 @@ pub fn emulate(data: &mut Data) -> Result<(), String> {
data.reg_arg = data.get_memory(data.reg_pc) << 8;
data.reg_pc = data.reg_pc.wrapping_add(1);
data.reg_arg |= data.get_memory(data.reg_pc);
data.reg_arg = data.reg_arg | data.get_memory(data.reg_pc);
data.reg_pc = data.reg_pc.wrapping_add(1);
}

View file

@ -55,11 +55,10 @@ pub fn parse(tokens: Vec<lexer::Token>) -> Result<ast::AST, String> {
body.push(ast::Node::Call {
name: x.clone(),
// arg: match args.first() {
// Some(x) => Some(x.clone()),
// _ => None,
// },
arg: args.first().cloned(),
arg: match args.first() {
Some(x) => Some(x.clone()),
_ => None,
},
});
}
}