mirror of
https://github.com/Zenithsiz/dcb.git
synced 2026-02-04 00:21:57 +00:00
Revised some names in parse::line and added some unit tests.
This commit is contained in:
parent
b572f1d922
commit
c211a2fc86
@ -2,14 +2,15 @@
|
||||
|
||||
// Modules
|
||||
pub mod error;
|
||||
|
||||
use std::str::FromStr;
|
||||
#[cfg(test)]
|
||||
pub mod test;
|
||||
|
||||
// Exports
|
||||
pub use error::{ParseLineError, ReadArgError, ReadFuncError, ReadLiteralError, ReadNameError};
|
||||
pub use error::{ParseArgError, ParseFuncError, ParseLineError, ParseLiteralError, ParseNameError};
|
||||
|
||||
// Imports
|
||||
use crate::inst::Register;
|
||||
use std::str::FromStr;
|
||||
|
||||
/// A line
|
||||
#[derive(PartialEq, Clone, Debug)]
|
||||
@ -26,7 +27,7 @@ impl Line {
|
||||
pub fn parse(line: &str) -> Result<Self, ParseLineError> {
|
||||
let mut line = line.trim();
|
||||
|
||||
// Read all labels and then the mnemonic
|
||||
// Parse all labels and then the mnemonic
|
||||
let mut labels = vec![];
|
||||
let mnemonic = loop {
|
||||
// If the line starts with a comment or is empty, return all labels
|
||||
@ -34,8 +35,8 @@ impl Line {
|
||||
return Ok(Self { labels, inst: None });
|
||||
}
|
||||
|
||||
// Read a name
|
||||
let (name, rest) = self::read_name(line)?;
|
||||
// Parse a name
|
||||
let (name, rest) = self::parse_name(line)?;
|
||||
|
||||
// Check the character after the name
|
||||
let mut rest = rest.chars();
|
||||
@ -60,7 +61,7 @@ impl Line {
|
||||
},
|
||||
|
||||
// If we got a space or eof, we found the mnemonic.
|
||||
// On a space, break and read arguments
|
||||
// On a space, break and parse arguments
|
||||
Some(' ') => {
|
||||
line = rest.as_str().trim_start();
|
||||
break name.to_owned();
|
||||
@ -69,18 +70,18 @@ impl Line {
|
||||
}
|
||||
};
|
||||
|
||||
// Then read all arguments
|
||||
// Then parse all arguments
|
||||
let mut args = vec![];
|
||||
loop {
|
||||
// Read an argument
|
||||
let (arg, rest) = self::read_arg(line)?;
|
||||
// Parse an argument
|
||||
let (arg, rest) = self::parse_arg(line)?;
|
||||
args.push(arg);
|
||||
|
||||
// Check the character after the argument
|
||||
let rest = rest.trim_start();
|
||||
let mut rest = rest.chars();
|
||||
match rest.next() {
|
||||
// If we got ',', continue reading
|
||||
// If we got ',', continue parsing
|
||||
Some(',') => {
|
||||
line = rest.as_str().trim_start();
|
||||
continue;
|
||||
@ -164,6 +165,54 @@ pub enum LineArgExpr {
|
||||
},
|
||||
}
|
||||
|
||||
impl LineArgExpr {
|
||||
/// Parses an expression
|
||||
pub fn parse(s: &str) -> Result<(LineArgExpr, &str), ParseArgError> {
|
||||
let mut chars = s.char_indices();
|
||||
match chars.next() {
|
||||
// If it's numeric, 0..9 or '+' / '-', it's a simple literal
|
||||
Some((_, '0'..='9' | '+' | '-')) => self::parse_literal(s)
|
||||
.map(|(num, rest)| (LineArgExpr::Literal(num), rest))
|
||||
.map_err(ParseArgError::Literal),
|
||||
|
||||
// If it starts with a label char, it's a label
|
||||
Some((_, c)) if self::is_valid_first_name_char(c) => {
|
||||
// Parse the label
|
||||
let (label, rest) = self::parse_name(s).map_err(ParseArgError::Label)?;
|
||||
|
||||
// If there's a '+' after, parse an offset too
|
||||
let (offset, rest) = match rest.strip_prefix('+') {
|
||||
Some(rest) => self::parse_literal(rest)
|
||||
.map(|(num, rest)| (Some(num), rest))
|
||||
.map_err(ParseArgError::LabelOffset)?,
|
||||
None => (None, rest),
|
||||
};
|
||||
|
||||
// If there's a '@' after, parse a function too
|
||||
let (func, rest) = match rest.strip_prefix('@') {
|
||||
Some(rest) => self::parse_func(rest)
|
||||
.map(|(func, rest)| (Some(func), rest))
|
||||
.map_err(ParseArgError::LabelFunc)?,
|
||||
None => (None, rest),
|
||||
};
|
||||
|
||||
let label = LineArgExpr::Label {
|
||||
label: label.to_owned(),
|
||||
offset,
|
||||
func,
|
||||
};
|
||||
|
||||
Ok((label, rest))
|
||||
},
|
||||
|
||||
// Else it's an invalid char
|
||||
Some(_) => Err(ParseArgError::InvalidStartChar),
|
||||
|
||||
None => Err(ParseArgError::Empty),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Line label functions
|
||||
#[allow(clippy::pub_enum_variant_names)] // We'll have other functions eventually
|
||||
#[derive(PartialEq, Clone, Debug)]
|
||||
@ -175,14 +224,14 @@ pub enum LineLabelFunc {
|
||||
AddrHi,
|
||||
}
|
||||
|
||||
/// Reads a name
|
||||
fn read_name(s: &str) -> Result<(&str, &str), ReadNameError> {
|
||||
/// Parses a name
|
||||
pub fn parse_name(s: &str) -> Result<(&str, &str), ParseNameError> {
|
||||
// Make sure the first character is valid
|
||||
let mut chars = s.char_indices();
|
||||
match chars.next() {
|
||||
Some((_, c)) if self::is_valid_first_name_char(c) => (),
|
||||
Some(_) => return Err(ReadNameError::StartChar),
|
||||
None => return Err(ReadNameError::Empty),
|
||||
Some(_) => return Err(ParseNameError::StartChar),
|
||||
None => return Err(ParseNameError::Empty),
|
||||
}
|
||||
|
||||
// Then keep consuming until we get a non-valid continuation character
|
||||
@ -197,38 +246,38 @@ fn read_name(s: &str) -> Result<(&str, &str), ReadNameError> {
|
||||
Ok((&s[..idx], &s[idx..]))
|
||||
}
|
||||
|
||||
/// Reads an argument
|
||||
fn read_arg(s: &str) -> Result<(LineArg, &str), ReadArgError> {
|
||||
/// Parses an argument
|
||||
pub fn parse_arg(s: &str) -> Result<(LineArg, &str), ParseArgError> {
|
||||
let mut chars = s.char_indices();
|
||||
match chars.next() {
|
||||
// If we got '$', it's a register
|
||||
Some((_, '$')) => self::read_reg(s).map(|(reg, rest)| (LineArg::Register(reg), rest)),
|
||||
Some((_, '$')) => self::parse_reg(s).map(|(reg, rest)| (LineArg::Register(reg), rest)),
|
||||
|
||||
// If we got '"', it's a string
|
||||
Some((_, '"')) => self::read_string(s).map(|(string, rest)| (LineArg::String(string), rest)),
|
||||
Some((_, '"')) => self::parse_string(s).map(|(string, rest)| (LineArg::String(string), rest)),
|
||||
|
||||
// If we got '^', it's a mnemonic
|
||||
Some((_, '^')) => self::read_name(chars.as_str())
|
||||
Some((_, '^')) => self::parse_name(chars.as_str())
|
||||
.map(|(name, rest)| (LineArg::Mnemonic(name.to_owned()), rest))
|
||||
.map_err(ReadArgError::ReadLabel),
|
||||
.map_err(ParseArgError::Label),
|
||||
|
||||
// Else try to read an expression
|
||||
// Else try to parse an expression
|
||||
Some(_) => {
|
||||
// Read the expression
|
||||
let (expr, rest) = self::read_expr(s)?;
|
||||
// Parse the expression
|
||||
let (expr, rest) = LineArgExpr::parse(s)?;
|
||||
|
||||
// Then check if we have a register
|
||||
let rest = rest.trim_start();
|
||||
match rest.strip_prefix('(') {
|
||||
// If the rest starts with '(', read it as a register offset
|
||||
// If the rest starts with '(', parse it as a register offset
|
||||
Some(rest) => match rest.split_once(')') {
|
||||
Some((reg, rest)) => {
|
||||
// Parse the register
|
||||
// If we have leftover tokens after reading it, return Err
|
||||
// If we have leftover tokens after parsing it, return Err
|
||||
let reg = reg.trim();
|
||||
let (reg, reg_rest) = self::read_reg(reg)?;
|
||||
let (reg, reg_rest) = self::parse_reg(reg)?;
|
||||
if !reg_rest.is_empty() {
|
||||
return Err(ReadArgError::RegisterOffsetLeftoverTokens);
|
||||
return Err(ParseArgError::RegisterOffsetLeftoverTokens);
|
||||
}
|
||||
|
||||
Ok((
|
||||
@ -239,82 +288,38 @@ fn read_arg(s: &str) -> Result<(LineArg, &str), ReadArgError> {
|
||||
rest,
|
||||
))
|
||||
},
|
||||
None => Err(ReadArgError::MissingRegisterOffsetDelimiter),
|
||||
None => Err(ParseArgError::MissingRegisterOffsetDelimiter),
|
||||
},
|
||||
None => Ok((LineArg::Expr(expr), rest)),
|
||||
}
|
||||
},
|
||||
|
||||
None => Err(ReadArgError::Empty),
|
||||
None => Err(ParseArgError::Empty),
|
||||
}
|
||||
}
|
||||
|
||||
/// Reads an expression
|
||||
pub fn read_expr(s: &str) -> Result<(LineArgExpr, &str), ReadArgError> {
|
||||
let mut chars = s.char_indices();
|
||||
match chars.next() {
|
||||
// If it's numeric, 0..9 or '+' / '-', it's a simple literal
|
||||
Some((_, '0'..='9' | '+' | '-')) => self::read_literal(s)
|
||||
.map(|(num, rest)| (LineArgExpr::Literal(num), rest))
|
||||
.map_err(ReadArgError::ReadLiteral),
|
||||
|
||||
// If it starts with a label char, it's a label
|
||||
Some((_, c)) if self::is_valid_first_name_char(c) => {
|
||||
// Read the label
|
||||
let (label, rest) = self::read_name(s).map_err(ReadArgError::ReadLabel)?;
|
||||
|
||||
// If there's a '+' after, read an offset too
|
||||
let (offset, rest) = match rest.strip_prefix('+') {
|
||||
Some(rest) => self::read_literal(rest)
|
||||
.map(|(num, rest)| (Some(num), rest))
|
||||
.map_err(ReadArgError::ReadLabelOffset)?,
|
||||
None => (None, rest),
|
||||
};
|
||||
|
||||
// If there's a '@' after, read a function too
|
||||
let (func, rest) = match rest.strip_prefix('@') {
|
||||
Some(rest) => self::read_func(rest)
|
||||
.map(|(func, rest)| (Some(func), rest))
|
||||
.map_err(ReadArgError::ReadLabelFunc)?,
|
||||
None => (None, rest),
|
||||
};
|
||||
|
||||
let label = LineArgExpr::Label {
|
||||
label: label.to_owned(),
|
||||
offset,
|
||||
func,
|
||||
};
|
||||
|
||||
Ok((label, rest))
|
||||
},
|
||||
|
||||
// Else it's an invalid char
|
||||
Some(_) => Err(ReadArgError::InvalidStartChar),
|
||||
|
||||
None => Err(ReadArgError::Empty),
|
||||
}
|
||||
}
|
||||
|
||||
/// Reads a register
|
||||
fn read_reg(s: &str) -> Result<(Register, &str), ReadArgError> {
|
||||
/// Parse a register
|
||||
pub fn parse_reg(s: &str) -> Result<(Register, &str), ParseArgError> {
|
||||
match s.get(..3) {
|
||||
Some(reg) => match Register::from_str(reg) {
|
||||
Ok(reg) => Ok((reg, &s[3..])),
|
||||
Err(()) => Err(ReadArgError::UnknownRegister),
|
||||
Err(()) => Err(ParseArgError::UnknownRegister),
|
||||
},
|
||||
None => Err(ReadArgError::ExpectedRegister),
|
||||
None => Err(ParseArgError::ExpectedRegister),
|
||||
}
|
||||
}
|
||||
|
||||
/// Reads a func
|
||||
fn read_func(s: &str) -> Result<(LineLabelFunc, &str), ReadFuncError> {
|
||||
/// Parses a func
|
||||
pub fn parse_func(s: &str) -> Result<(LineLabelFunc, &str), ParseFuncError> {
|
||||
None.or_else(|| s.strip_prefix("addr_hi").map(|rest| (LineLabelFunc::AddrHi, rest)))
|
||||
.or_else(|| s.strip_prefix("addr_lo").map(|rest| (LineLabelFunc::AddrLo, rest)))
|
||||
.ok_or(ReadFuncError::Unknown)
|
||||
.ok_or(ParseFuncError::Unknown)
|
||||
}
|
||||
|
||||
/// Reads a string
|
||||
fn read_string(s: &str) -> Result<(String, &str), ReadArgError> {
|
||||
/// Parses a string
|
||||
///
|
||||
/// # Panics if `s[0]` isn't '"'.
|
||||
pub fn parse_string(s: &str) -> Result<(String, &str), ParseArgError> {
|
||||
let mut is_escaping = false;
|
||||
let mut in_multi_escape = false;
|
||||
let mut chars = s.char_indices();
|
||||
@ -344,7 +349,7 @@ fn read_string(s: &str) -> Result<(String, &str), ReadArgError> {
|
||||
let (string, rest) = s.split_at(idx + 1);
|
||||
|
||||
// Note: For whatever reason 'snailquote' requires the quotes to be included in `string`
|
||||
let string = snailquote::unescape(string).map_err(ReadArgError::UnescapeString)?;
|
||||
let string = snailquote::unescape(string).map_err(ParseArgError::UnescapeString)?;
|
||||
|
||||
break Ok((string, rest));
|
||||
},
|
||||
@ -352,13 +357,13 @@ fn read_string(s: &str) -> Result<(String, &str), ReadArgError> {
|
||||
// Else just continue
|
||||
Some(_) => continue,
|
||||
|
||||
None => break Err(ReadArgError::MissingClosingDelimiterString),
|
||||
None => break Err(ParseArgError::MissingClosingDelimiterString),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// Reads a literal from a string and returns the rest
|
||||
fn read_literal(s: &str) -> Result<(i64, &str), ReadLiteralError> {
|
||||
/// Parses a literal from a string and returns the rest
|
||||
pub fn parse_literal(s: &str) -> Result<(i64, &str), ParseLiteralError> {
|
||||
// Check if it's negative
|
||||
let (is_neg, num) = match s.chars().next() {
|
||||
Some('+') => (false, &s[1..]),
|
||||
@ -390,7 +395,7 @@ fn read_literal(s: &str) -> Result<(i64, &str), ReadLiteralError> {
|
||||
};
|
||||
|
||||
// Parse it
|
||||
let num = i64::from_str_radix(num, base).map_err(ReadLiteralError::Parse)?;
|
||||
let num = i64::from_str_radix(num, base).map_err(ParseLiteralError::Parse)?;
|
||||
let num = match is_neg {
|
||||
true => -num,
|
||||
false => num,
|
||||
@ -399,12 +404,14 @@ fn read_literal(s: &str) -> Result<(i64, &str), ReadLiteralError> {
|
||||
Ok((num, rest))
|
||||
}
|
||||
|
||||
/// Returns if `c` is a valid mnemonic first character
|
||||
/// Returns if `c` is a valid name first character
|
||||
#[must_use]
|
||||
fn is_valid_first_name_char(c: char) -> bool {
|
||||
c.is_ascii_alphabetic() || ['.', '_'].contains(&c)
|
||||
}
|
||||
|
||||
/// Returns if `c` is a valid mnemonic continuation character
|
||||
/// Returns if `c` is a valid name continuation character
|
||||
#[must_use]
|
||||
fn is_valid_cont_name_char(c: char) -> bool {
|
||||
c.is_ascii_alphanumeric() || ['.', '_'].contains(&c)
|
||||
}
|
||||
|
||||
@ -4,28 +4,28 @@ use snailquote::UnescapeError;
|
||||
|
||||
|
||||
/// Error for [`Line::parse`](super::Line::parse)
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
#[derive(PartialEq, Debug, thiserror::Error)]
|
||||
pub enum ParseLineError {
|
||||
/// Unable to read name
|
||||
/// Unable to parse name
|
||||
#[error("Expected name")]
|
||||
ReadName(#[from] ReadNameError),
|
||||
ParseName(#[from] ParseNameError),
|
||||
|
||||
/// Invalid name suffix
|
||||
#[error("Invalid name suffix")]
|
||||
InvalidNameSuffix,
|
||||
|
||||
/// Unable to read argument
|
||||
/// Unable to parse argument
|
||||
#[error("Expected argument")]
|
||||
ReadArg(#[from] ReadArgError),
|
||||
ParseArg(#[from] ParseArgError),
|
||||
|
||||
/// Invalid argument suffix
|
||||
#[error("Invalid argument suffix")]
|
||||
InvalidArgSuffix,
|
||||
}
|
||||
|
||||
/// Name reading error
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum ReadNameError {
|
||||
/// Name parsing error
|
||||
#[derive(PartialEq, Clone, Debug, thiserror::Error)]
|
||||
pub enum ParseNameError {
|
||||
/// Name was empty
|
||||
#[error("Name was empty")]
|
||||
Empty,
|
||||
@ -35,25 +35,25 @@ pub enum ReadNameError {
|
||||
StartChar,
|
||||
}
|
||||
|
||||
/// Literal reading error
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum ReadLiteralError {
|
||||
/// Literal parsing error
|
||||
#[derive(PartialEq, Clone, Debug, thiserror::Error)]
|
||||
pub enum ParseLiteralError {
|
||||
/// Parse
|
||||
#[error("Unable to parse literal")]
|
||||
Parse(#[from] std::num::ParseIntError),
|
||||
}
|
||||
|
||||
/// Func reading error
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum ReadFuncError {
|
||||
/// Func parsing error
|
||||
#[derive(PartialEq, Clone, Debug, thiserror::Error)]
|
||||
pub enum ParseFuncError {
|
||||
/// Parse
|
||||
#[error("Unknown functions")]
|
||||
Unknown,
|
||||
}
|
||||
|
||||
/// Argument reading error
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum ReadArgError {
|
||||
/// Argument parsing error
|
||||
#[derive(PartialEq, Debug, thiserror::Error)]
|
||||
pub enum ParseArgError {
|
||||
/// Empty
|
||||
#[error("Argument was empty")]
|
||||
Empty,
|
||||
@ -62,25 +62,25 @@ pub enum ReadArgError {
|
||||
#[error("Invalid starting char")]
|
||||
InvalidStartChar,
|
||||
|
||||
/// Read Literal
|
||||
#[error("Unable to read literal")]
|
||||
ReadLiteral(#[source] ReadLiteralError),
|
||||
/// Parse Literal
|
||||
#[error("Unable to parse literal")]
|
||||
Literal(#[source] ParseLiteralError),
|
||||
|
||||
/// Read mnemonic
|
||||
#[error("Unable to read mnemonic")]
|
||||
ReadMnemonic(#[source] ReadNameError),
|
||||
/// Parse mnemonic
|
||||
#[error("Unable to parse mnemonic")]
|
||||
ParseMnemonic(#[source] ParseNameError),
|
||||
|
||||
/// Read label
|
||||
#[error("Unable to read label")]
|
||||
ReadLabel(#[source] ReadNameError),
|
||||
/// Parse label
|
||||
#[error("Unable to parse label")]
|
||||
Label(#[source] ParseNameError),
|
||||
|
||||
/// Read label offset
|
||||
#[error("Unable to read label offset")]
|
||||
ReadLabelOffset(#[source] ReadLiteralError),
|
||||
/// Parse label offset
|
||||
#[error("Unable to parse label offset")]
|
||||
LabelOffset(#[source] ParseLiteralError),
|
||||
|
||||
/// Read label func
|
||||
#[error("Unable to read label func")]
|
||||
ReadLabelFunc(#[source] ReadFuncError),
|
||||
/// Parse label func
|
||||
#[error("Unable to parse label func")]
|
||||
LabelFunc(#[source] ParseFuncError),
|
||||
|
||||
/// Expected register
|
||||
#[error("Expected register")]
|
||||
|
||||
47
dcb-exe/src/inst/parse/line/test.rs
Normal file
47
dcb-exe/src/inst/parse/line/test.rs
Normal file
@ -0,0 +1,47 @@
|
||||
//! Tests
|
||||
|
||||
// Imports
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_parse_literal() {
|
||||
// Oks
|
||||
assert_matches!(self::parse_literal("0"), Ok((0, "")));
|
||||
assert_matches!(self::parse_literal("123"), Ok((123, "")));
|
||||
assert_matches!(self::parse_literal("123abc"), Ok((123, "abc")));
|
||||
assert_matches!(self::parse_literal("+1"), Ok((1, "")));
|
||||
assert_matches!(self::parse_literal("-1"), Ok((-1, "")));
|
||||
assert_matches!(self::parse_literal("0x100"), Ok((0x100, "")));
|
||||
assert_matches!(self::parse_literal("0b100"), Ok((0b100, "")));
|
||||
assert_matches!(self::parse_literal("0o100"), Ok((0o100, "")));
|
||||
assert_matches!(self::parse_literal("-0x100"), Ok((-0x100, "")));
|
||||
assert_matches!(self::parse_literal("-0b100"), Ok((-0b100, "")));
|
||||
assert_matches!(self::parse_literal("-0o100"), Ok((-0o100, "")));
|
||||
assert_matches!(self::parse_literal("0x123abc"), Ok((0x123abc, "")));
|
||||
assert_matches!(self::parse_literal("0b123abc"), Ok((0b1, "23abc")));
|
||||
assert_matches!(self::parse_literal("0o123abc"), Ok((0o123, "abc")));
|
||||
|
||||
// Errors
|
||||
assert_matches!(self::parse_literal(""), Err(ParseLiteralError::Parse(_)));
|
||||
assert_matches!(self::parse_literal("abc"), Err(ParseLiteralError::Parse(_)));
|
||||
assert_matches!(self::parse_literal("0xg"), Err(ParseLiteralError::Parse(_)));
|
||||
assert_matches!(self::parse_literal("0b2"), Err(ParseLiteralError::Parse(_)));
|
||||
assert_matches!(self::parse_literal("0o8"), Err(ParseLiteralError::Parse(_)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_string() {
|
||||
// Oks
|
||||
assert_eq!(
|
||||
self::parse_string(r#""Hello,\n World""#),
|
||||
Ok(("Hello,\n World".to_owned(), ""))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn parse_string_panic() {
|
||||
match self::parse_string("a") {
|
||||
Ok(_) | Err(_) => (),
|
||||
}
|
||||
}
|
||||
@ -17,7 +17,7 @@ mod cli;
|
||||
// Imports
|
||||
use anyhow::Context;
|
||||
use dcb_exe::{
|
||||
inst::{parse::line, DisplayCtx, Inst, InstDisplay, InstFmtArg, ParseCtx},
|
||||
inst::{parse::LineArgExpr, DisplayCtx, Inst, InstDisplay, InstFmtArg, ParseCtx},
|
||||
reader::iter::ExeItem,
|
||||
ExeReader, Func, Pos,
|
||||
};
|
||||
@ -248,7 +248,7 @@ pub fn inst_display<'a>(
|
||||
// Validator
|
||||
let validate = || -> Result<(), anyhow::Error> {
|
||||
// Parse the override
|
||||
let (expr, rest) = line::read_expr(&value).context("Unable to parse override")?;
|
||||
let (expr, rest) = LineArgExpr::parse(&value).context("Unable to parse override")?;
|
||||
|
||||
let rest = rest.trim_start();
|
||||
if !rest.is_empty() {
|
||||
|
||||
@ -404,6 +404,12 @@
|
||||
start_pos: 0x80049e80
|
||||
end_pos: 0x80049ef8
|
||||
|
||||
- name: something42
|
||||
start_pos: 0x8004b2f0
|
||||
end_pos: 0x8004b394
|
||||
inline_comments:
|
||||
0x8004b2f0: "Division by 0"
|
||||
|
||||
# A functions
|
||||
- name: InitHeap
|
||||
signature: "fn(addr: *u32, size: u32)"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user