1use crate::assembly::operand::{FullOperand, NonMemoryOperand};
6use std::collections::HashMap;
7use thiserror::Error;
8
9#[derive(Debug, Error)]
10pub enum Error {
11 #[error("file opening: {0}")]
13 FileOpening(std::io::Error),
14 #[error("file metadata: {0}")]
16 FileMetadata(std::io::Error),
17 #[error("file reading: {0}")]
19 FileReading(std::io::Error),
20 #[error(transparent)]
21 AssemblyParseError(#[from] AssemblyParseError),
22}
23
24#[derive(Debug, Error, PartialEq)]
25pub enum AssemblyParseError {
26 #[error("assembly code cannot be empty")]
27 EmptyCode,
28 #[error("assembly code cannot be larger than {0} instructions")]
29 CodeTooLarge(usize),
30 #[error("can not parse data section element: {0}")]
31 DataSectionInvalid(SectionReadError),
32 #[error("can not parse globals section element: {0}")]
33 GlobalsSectionInvalid(SectionReadError),
34 #[error("can not parse text section element: {0}")]
35 TextSectionInvalid(SectionReadError),
36 #[error("there is a duplicate label in a code: {0}")]
37 DuplicateLabel(String),
38 #[error("there is no label `{0}` in data section of functions")]
39 LabelNotFound(String),
40 #[error("failed to resolve relocation for label `{0}` in data section")]
41 RelocationError(String),
42 #[error("Label {1} was tried to be used for either PC or constant at offset {0} that is more than `{2}` addressable space")]
43 CodeIsTooLong(usize, String, u64),
44}
45
46#[derive(Debug, Error, PartialEq)]
47pub enum SectionReadError {
48 #[error("cannot parse lines: {0:?}")]
49 LineReadError(HashMap<usize, (String, InstructionReadError)>),
50}
51
52#[derive(Debug, Error, PartialEq)]
53pub enum InstructionReadError {
54 #[error("assembly parse error {0}")]
56 AssemblyParseError(AssemblyParseError),
57 #[error("unknown register `{0}`")]
59 UnknownRegister(String),
60 #[error("invalid number `{0}`: {1}")]
62 InvalidNumber(String, std::num::ParseIntError),
63 #[error("invalid big number `{0}`: {1}")]
65 InvalidBigNumber(String, num_bigint::ParseBigIntError),
66 #[error("failed to parse labeled constant value `{0}`")]
68 InvalidLabeledConstant(String),
69 #[error(
71 "invalid argument {0}: expected `{1}`, found `{2}`",
72 index,
73 expected,
74 found
75 )]
76 InvalidArgument {
77 index: usize,
79 expected: &'static str,
81 found: String,
83 },
84 #[error("failed to parse generic operand location: received `{0}`")]
85 InvalidGenericOperand(String),
86 #[error("failed to parse absolute-like `reg + imm` location: received `{0}`")]
87 InvalidAbsoluteLikeAddress(String),
88 #[error("failed to parse labeled constant operand location: received `{0}`")]
89 InvalidLabeledConstantOperand(String),
90 #[error("found immediate `{0}` for location where register only is expected")]
92 InvalidOperandImmInRegLocation(String),
93 #[error(
94 "invalid operand for location that should be generic: on position `{index}`: {found:?}"
95 )]
96 InvalidOperandForGenericLocation { index: usize, found: FullOperand },
97 #[error("invalid operand for location that is reg-only: on position `{index}`: {found:?}")]
99 InvalidOperandForRegLocation { index: usize, found: FullOperand },
100 #[error("invalid operand for location that is reg-only or imm-only: on position `{index}`: {found:?}")]
101 InvalidOperandForRegImmLocation { index: usize, found: FullOperand },
102 #[error("invalid operand for location that is reg-only in this version: on position `{index}`: {found:?}")]
103 InvalidRegImmInPlaceOfReg {
104 index: usize,
105 found: NonMemoryOperand,
106 },
107 #[error("invalid operand for location that is label-only: on position `{index}`: {found:?}")]
109 InvalidOperandForLabelLocation { index: usize, found: FullOperand },
110 #[error(
112 "invalid number of arguments: expected `{0}`, found `{1}`",
113 expected,
114 found
115 )]
116 InvalidArgumentCount {
117 expected: usize,
119 found: usize,
121 },
122 #[error("unknown argument `{0}`")]
124 UnknownArgument(String),
125 #[error(
126 "subtraction and negative literals are only supported in memory offsets, not in immediates"
127 )]
128 UnexpectedSubtraction,
129 #[error("integer overflow when computing the immediate")]
130 IntegerOverflow,
131 #[error("unknown symbol or label `{0}`")]
132 UnknownLabel(String),
133 #[error("unknown mnemonic `{0}`")]
134 UnknownMnemonic(String),
135 #[error("unexpected constant-like line {0:?} not in section")]
136 UnexpectedConstant(String),
137 #[error("unexpected line {0:?} in Text section")]
138 UnexpectedInstruction(String),
139 #[error("duplicate modifier `{0}` in the instruction")]
140 DuplicateModifier(String),
141 #[error("code is too long, can address {0} opcodes at maximum, encountered {1}")]
142 TooManyOpcodes(u64, u64),
143 #[error("code is too long, can address {0} words at maximum, encountered {1}")]
144 CodeIsTooLong(u64, u64),
145 }
148
149#[derive(Debug, Error, PartialEq)]
150pub enum BinaryParseError {
151 #[error("use_mem flag must be reset in Memory instruction")]
152 MemoryOpcodeInvalidFlag,
153 #[error("force stack flag can only be set for Stack memory type")]
154 UnexpectedForceStackFlag,
155 #[error("invalid register selector. At most one register can be selected per position.")]
156 InvalidRegisterSelector,
157 #[error("bytecode cannot be empty")]
158 EmptyBytecode,
159 #[error("bytecode length in bytes must be a multiple of {0}")]
160 InvalidBytecodeLength(usize),
161 #[error("bytecode length in bytes must be less than {0}")]
162 BytecodeTooLong(usize),
163 #[error("invalid opcode")]
164 InvalidOpcode,
165 #[error("Supported context fields indices: 0-5")]
166 UnknownContextField,
167}