Add value directives and strings
.string, .zstring, .u64, .u32, .u16, .u8 are used before an ImmValue to determine how the memory should be laid out for that value. Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
@@ -25,7 +25,7 @@ pub enum SectionOrg {
|
||||
pub enum Line {
|
||||
Inst(Inst),
|
||||
LabelDef(String),
|
||||
ImmValue(ImmValue),
|
||||
ValueDecl(ValueDecl),
|
||||
Export(String),
|
||||
}
|
||||
|
||||
@@ -35,6 +35,53 @@ pub enum ImmValue {
|
||||
Label(String),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum ValueDecl {
|
||||
U64(u64),
|
||||
U32(u64),
|
||||
U16(u64),
|
||||
U8(u64),
|
||||
String(String),
|
||||
ZString(String),
|
||||
}
|
||||
|
||||
impl ValueDecl {
|
||||
pub fn len(&self) -> usize {
|
||||
match self {
|
||||
ValueDecl::U64(_) => 8,
|
||||
ValueDecl::U32(_) => 4,
|
||||
ValueDecl::U16(_) => 2,
|
||||
ValueDecl::U8(_) => 1,
|
||||
ValueDecl::String(s) => s.as_bytes().len() + 8,
|
||||
ValueDecl::ZString(s) => s.as_bytes().len() + 1,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_bytes(&self) -> Vec<u8> {
|
||||
let len = self.len();
|
||||
let bytes = match self {
|
||||
ValueDecl::U64(v) => v.to_le_bytes().to_vec(),
|
||||
ValueDecl::U32(v) => v.to_le_bytes()[0..4].to_vec(),
|
||||
ValueDecl::U16(v) => v.to_le_bytes()[0..2].to_vec(),
|
||||
ValueDecl::U8(v) => vec![(v & 0xff) as u8],
|
||||
ValueDecl::String(s) => {
|
||||
let mut bytes = Vec::with_capacity(self.len());
|
||||
bytes.extend(&(s.len() as u64).to_le_bytes());
|
||||
bytes.extend(s.as_bytes());
|
||||
bytes
|
||||
}
|
||||
ValueDecl::ZString(s) => {
|
||||
let mut bytes = Vec::with_capacity(self.len());
|
||||
bytes.extend(s.as_bytes());
|
||||
bytes.push(0);
|
||||
bytes
|
||||
}
|
||||
};
|
||||
assert_eq!(bytes.len(), len);
|
||||
bytes
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum Inst {
|
||||
Add(Reg, Reg),
|
||||
|
||||
@@ -3,3 +3,14 @@ use lalrpop_util::lalrpop_mod;
|
||||
lalrpop_mod!(pub parser, "/vm/obj/syn/parser.rs");
|
||||
pub mod ast;
|
||||
pub mod error;
|
||||
|
||||
pub fn unescape_string(s: impl AsRef<str>) -> String {
|
||||
let s = s.as_ref();
|
||||
s.replace(r"\\", "\\")
|
||||
.replace("\\n", "\n")
|
||||
.replace("\\r", "\r")
|
||||
.replace("\\t", "\t")
|
||||
.replace("\\t", "\t")
|
||||
.replace("\\0", "\0")
|
||||
.replace("\\\"", "\"")
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use std::str::FromStr;
|
||||
use crate::vm::{
|
||||
obj::syn::ast::*,
|
||||
obj::syn::{unescape_string, ast::*},
|
||||
reg::*,
|
||||
};
|
||||
|
||||
@@ -10,15 +10,13 @@ LabelDef: String = {
|
||||
<Label> ":" => <>
|
||||
}
|
||||
|
||||
// TODO : Value (ImmValue, String)
|
||||
|
||||
ImmValue: ImmValue = {
|
||||
<Label> => ImmValue::Label(<>),
|
||||
<Number> => ImmValue::Number(<>),
|
||||
}
|
||||
|
||||
Label: String = {
|
||||
r"[a-zA-Z]+" => String::from(<>),
|
||||
r"[a-zA-Z_][a-zA-Z0-9_]*" => String::from(<>),
|
||||
}
|
||||
|
||||
Number: u64 = {
|
||||
@@ -27,11 +25,19 @@ Number: u64 = {
|
||||
<s:r"\$0b[01]+"> => u64::from_str_radix(&s[3..], 2).unwrap(),
|
||||
}
|
||||
|
||||
String: String = {
|
||||
<s:r#""([^"\\]|\\[\\nrt0"])*""#> => {
|
||||
let len = s.len();
|
||||
unescape_string(&s[1..len-1])
|
||||
}
|
||||
}
|
||||
|
||||
Reg: Reg = {
|
||||
r"%ip" => IP,
|
||||
r"%sp" => SP,
|
||||
r"%fp" => FP,
|
||||
r"%flags" => FLAGS,
|
||||
r"%null" => NULL,
|
||||
r"%status" => STATUS,
|
||||
r"%r[0-9]{2}" => {
|
||||
let offset = (&<>[2..]).parse::<u8>().unwrap();
|
||||
@@ -68,10 +74,19 @@ Inst: Inst = {
|
||||
"halt" => Inst::Halt,
|
||||
}
|
||||
|
||||
ValueDecl: ValueDecl = {
|
||||
r"\.u64" <Number> => ValueDecl::U64(<>),
|
||||
r"\.u32" <Number> => ValueDecl::U32(<>),
|
||||
r"\.u16" <Number> => ValueDecl::U16(<>),
|
||||
r"\.u8" <Number> => ValueDecl::U8(<>),
|
||||
r"\.string" <String> => ValueDecl::String(<>),
|
||||
r"\.zstring" <String> => ValueDecl::ZString(<>),
|
||||
}
|
||||
|
||||
Line: Line = {
|
||||
<Inst> => Line::Inst(<>),
|
||||
<LabelDef> => Line::LabelDef(<>),
|
||||
<ImmValue> => Line::ImmValue(<>),
|
||||
<ValueDecl> => Line::ValueDecl(<>),
|
||||
r"\.export" <Label> => Line::Export(<>),
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user