Skip to content

Instantly share code, notes, and snippets.

@silverweed
Last active August 29, 2015 14:12
Show Gist options
  • Save silverweed/aa1efadf128d3e1505b0 to your computer and use it in GitHub Desktop.
Save silverweed/aa1efadf128d3e1505b0 to your computer and use it in GitHub Desktop.
-- generate random assembly for tiny
opcodes = {
{{ 'AND', 'm', 'm' }, { 'AND', 'm', 'c' }},
{{ 'OR', 'm', 'm' }, { 'OR', 'm', 'c' }},
{{ 'XOR', 'm', 'm' }, { 'XOR', 'm', 'c' }},
{{ 'NOT', 'm' }},
{{ 'MOV', 'm', 'm' }, { 'MOV', 'm', 'c' }},
{{ 'RANDOM', 'm' }},
{{ 'ADD', 'm', 'm' }, { 'ADD', 'm', 'c' }},
{{ 'SUB', 'm', 'm' }, { 'SUB', 'm', 'c' }},
{{ 'APRINT', 'm' }, { 'APRINT', 'c' }},
{{ 'DPRINT', 'm' }, { 'DPRINT', 'c' }},
}
for i = 0, 10000, 1 do
local op = opcodes[math.random(#opcodes)]
local optype = op[math.random(#op)]
io.write(optype[1], " ");
for j = 2, #optype, 1 do
if optype[j] == 'c' then
io.write(math.random(255))
else
io.write("[", math.random(255), "]")
end
io.write(" ")
end
print("")
end
print("HALT")
{- Assembler for the tiny assembly language
- (see http://www.reddit.com/r/dailyprogrammer/comments/1kqxz9/080813_challenge_132_intermediate_tiny_assembler/)
- by silverweed
-}
import Data.Char (toUpper)
import Data.Word
import System.IO
import qualified Data.ByteString as B
data ParamType = Const Int | Mem Int
data ParamList =
NoParams
| OneParam ParamType
| TwoParams ParamType ParamType
| ThreeParams ParamType ParamType ParamType
parseType :: String -> ParamType
parseType s@('[':v)
| last v == ']' = Mem $ read $ init v
| otherwise = error ("Invalid operand: " ++ s)
parseType v = Const $ read v
get :: String -> (String, ParamList)
get line =
case len of
1 -> (op, NoParams)
2 -> (op, OneParam p1)
where
p1 = parseType $ par !! 0
3 -> (op, TwoParams p1 p2)
where
p1 = parseType $ par !! 0
p2 = parseType $ par !! 1
4 -> (op, ThreeParams p1 p2 p3)
where
p1 = parseType $ par !! 0
p2 = parseType $ par !! 1
p3 = parseType $ par !! 2
where
spl = words line
len = length spl
op = map toUpper $ head spl
par = tail spl
emitCode :: (String, ParamList) -> [Word8]
emitCode x = map fromIntegral $ encode x
where
encode ("AND", TwoParams (Mem a) (Mem b)) = [0x00, a, b]
encode ("AND", TwoParams (Mem a) (Const b)) = [0x01, a, b]
encode ("OR", TwoParams (Mem a) (Mem b)) = [0x02, a, b]
encode ("OR", TwoParams (Mem a) (Const b)) = [0x03, a, b]
encode ("XOR", TwoParams (Mem a) (Mem b)) = [0x04, a, b]
encode ("XOR", TwoParams (Mem a) (Const b)) = [0x05, a, b]
encode ("NOT", OneParam (Mem a)) = [0x06, a]
encode ("MOV", TwoParams (Mem a) (Mem b)) = [0x07, a, b]
encode ("MOV", TwoParams (Mem a) (Const b)) = [0x08, a, b]
encode ("RANDOM", OneParam (Mem a)) = [0x09, a]
encode ("ADD", TwoParams (Mem a) (Mem b)) = [0x0a, a, b]
encode ("ADD", TwoParams (Mem a) (Const b)) = [0x0b, a, b]
encode ("SUB", TwoParams (Mem a) (Mem b)) = [0x0c, a, b]
encode ("SUB", TwoParams (Mem a) (Const b)) = [0x0d, a, b]
encode ("JMP", OneParam (Mem a)) = [0x0e, a]
encode ("JMP", OneParam (Const a)) = [0x0f, a]
encode ("JZ", TwoParams (Mem a) (Mem b)) = [0x10, a, b]
encode ("JZ", TwoParams (Mem a) (Const b)) = [0x11, a, b]
encode ("JZ", TwoParams (Const a) (Mem b)) = [0x12, a, b]
encode ("JZ", TwoParams (Const a) (Const b)) = [0x13, a, b]
encode ("JEQ", ThreeParams (Mem a) (Mem b) (Mem c)) = [0x14, a, b, c]
encode ("JEQ", ThreeParams (Const a) (Mem b) (Mem c)) = [0x15, a, b, c]
encode ("JEQ", ThreeParams (Mem a) (Mem b) (Const c)) = [0x16, a, b, c]
encode ("JEQ", ThreeParams (Const a) (Mem b) (Const c)) = [0x17, a, b, c]
encode ("JLS", ThreeParams (Mem a) (Mem b) (Mem c)) = [0x18, a, b, c]
encode ("JLS", ThreeParams (Const a) (Mem b) (Mem c)) = [0x19, a, b, c]
encode ("JLS", ThreeParams (Mem a) (Mem b) (Const c)) = [0x1a, a, b, c]
encode ("JLS", ThreeParams (Const a) (Mem b) (Const c)) = [0x1b, a, b, c]
encode ("JGT", ThreeParams (Mem a) (Mem b) (Mem c)) = [0x1c, a, b, c]
encode ("JGT", ThreeParams (Const a) (Mem b) (Mem c)) = [0x1d, a, b, c]
encode ("JGT", ThreeParams (Mem a) (Mem b) (Const c)) = [0x1e, a, b, c]
encode ("JGT", ThreeParams (Const a) (Mem b) (Const c)) = [0x1f, a, b, c]
encode ("HALT", NoParams) = [0xff]
encode ("APRINT", OneParam (Mem a)) = [0x20, a]
encode ("APRINT", OneParam (Const a)) = [0x21, a]
encode ("DPRINT", OneParam (Mem a)) = [0x22, a]
encode ("DPRINT", OneParam (Const a)) = [0x23, a]
encode (x, _) = error ("Invalid line: " ++ x)
readLine :: Bool -> IO ()
readLine True = return ()
readLine False = do
line <- getLine
B.putStr $ B.pack $ emitCode $ get line
isEOF >>= readLine
main = isEOF >>= readLine
// written by Hamcha (https://github.com/hamcha)
use std::rand;
fn execute(code: Vec<u8>) {
let length = code.len();
let mut memory = [0u8; 256];
let mut offset = 0u;
while offset < length {
let opcode = code[offset];
match opcode {
// AND
0x00 | 0x01 => {
let (a, b) = (code[offset + 1], code[offset + 2]);
let op = if opcode & 1 < 1 { memory[b as uint] } else { b };
memory[a as uint] &= op;
offset += 2;
}
// OR
0x02 | 0x03 => {
let (a, b) = (code[offset + 1], code[offset + 2]);
let op = if opcode & 1 < 1 { memory[b as uint] } else { b };
memory[a as uint] |= op;
offset += 2;
}
// XOR
0x04 | 0x05 => {
let (a, b) = (code[offset + 1], code[offset + 2]);
let op = if opcode & 1 < 1 { memory[b as uint] } else { b };
memory[a as uint] ^= op;
offset += 2;
}
// NOT
0x06 => {
let a = code[offset + 1];
memory[a as uint] ^= 0xff;
offset += 1;
}
// MOV
0x07 | 0x08 => {
let (a, b) = (code[offset + 1], code[offset + 2]);
let op = if opcode & 1 > 0 { memory[b as uint] } else { b };
memory[a as uint] = op;
offset += 2;
}
// RANDOM
0x09 => {
let a = code[offset + 1];
memory[a as uint] = rand::random::<u8>() % 26;
offset += 1;
}
// ADD
0x0a | 0x0b => {
let (a, b) = (code[offset + 1], code[offset + 2]);
let op = if opcode & 1 < 1 { memory[b as uint] } else { b };
memory[a as uint] += op;
offset += 2;
}
// SUB
0x0c | 0x0d => {
let (a, b) = (code[offset + 1], code[offset + 2]);
let op = if opcode & 1 < 1 { memory[b as uint] } else { b };
memory[a as uint] -= op;
offset += 2;
}
// JMP
0x0e | 0x0f => {
let a = code[offset + 1];
let addr = if opcode & 1 < 1 { memory[a as uint] } else { a };
offset = (addr as uint) - 1;
}
// JZ
0x10 | 0x11 | 0x12 | 0x13 => {
let (a, b) = (code[offset + 1], code[offset + 2]);
let addr = if opcode < 0x12 { memory[a as uint] } else { a };
let op = if opcode & 1 < 1 { memory[b as uint] } else { b };
offset = if op == 0 { (addr as uint) - 1 } else { offset + 2 };
}
// JEQ
0x14 | 0x15 | 0x16 | 0x17 => {
let (a, b, c) = (code[offset + 1], code[offset + 2], code[offset + 3]);
let addr = if opcode < 0x16 { memory[a as uint] } else { a };
let op = if opcode & 1 < 1 { memory[c as uint] } else { c };
offset = if op == memory[b as uint] { (addr as uint) - 1 } else { offset + 3 };
}
// JLS
0x18 | 0x19 | 0x1a | 0x1b => {
let (a, b, c) = (code[offset + 1], code[offset + 2], code[offset + 3]);
let addr = if opcode < 0x1a { memory[a as uint] } else { a };
let op = if opcode & 1 < 1 { memory[c as uint] } else { c };
offset = if op > memory[b as uint] { (addr as uint) - 1 } else { offset + 3 };
}
// JGT
0x1c | 0x1d | 0x1e | 0x1f => {
let (a, b, c) = (code[offset + 1], code[offset + 2], code[offset + 3]);
let addr = if opcode < 0x1e { memory[a as uint] } else { a };
let op = if opcode & 1 < 1 { memory[c as uint] } else { c };
offset = if op < memory[b as uint] { (addr as uint) - 1 } else { offset + 3 };
}
// APRINT, DPRINT
0x20 | 0x21 | 0x22 | 0x23 => {
let a = code[offset + 1];
let op = if opcode & 1 < 1 { memory[a as uint] } else { a };
if opcode < 0x22 {
println!("{}",op as char);
} else {
println!("{}",op as u8);
}
offset += 1;
}
// HALT
0xff => { break }
_ => println!("Unknown opcode: {}", opcode)
}
offset += 1;
}
println!("\nFinished execution, dumping RAM..");
for i in range(0u, 256u) {
if i % 16 < 1 {
println!("");
if i < 0x10 {
print!("0");
}
print!("{:X} : ", i);
}
if memory[i] < 0x10 {
print!("0");
}
print!("{:X} ", memory[i]);
}
println!("");
}
fn main() {
let code = std::io::stdin().read_to_end().ok().expect("Can't read from STDIN");
execute(code);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment