1mod assembler;
29mod bind;
30mod builtin;
31mod compile_context;
32mod func_info;
33mod json;
34mod label;
35mod macros;
36mod parser;
37mod portable_executable;
38mod scope_info;
39mod utility;
40use compile_context::CompileContext;
41use core::error::Error;
42use parser::Parser;
43use scope_info::ScopeInfo;
44use std::{collections::HashMap, vec::IntoIter};
45#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
46#[expect(dead_code)]
47enum Disp {
48 Byte(i8),
49 Dword(i32),
50 Zero,
51}
52#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)]
53#[expect(dead_code, clippy::arbitrary_source_item_ordering)]
54enum Reg {
55 Rax = 0,
56 Rcx = 1,
57 Rdx = 2,
58 Rbx = 3,
59 Rsp = 4,
60 Rbp = 5,
61 Rsi = 6,
62 Rdi = 7,
63 R8 = 8,
64 R9 = 9,
65 R10 = 10,
66 R11 = 11,
67 R12 = 12,
68 R13 = 13,
69 R14 = 14,
70 R15 = 15,
71}
72#[derive(Clone, Copy, PartialEq, Eq)]
73#[expect(clippy::allow_attributes)]
74enum Memory {
75 #[allow(dead_code)]
76 Base(Reg, Disp),
77 Reg(Reg),
78 RipRel(i32),
79 #[allow(dead_code)]
80 Sib(Sib),
81}
82#[derive(Clone, Copy, PartialEq, Eq)]
83#[expect(dead_code)]
84enum Scale {
85 S1 = 0,
86 S2 = 1,
87 S4 = 2,
88 S8 = 3,
89}
90#[derive(Clone, Copy, PartialEq, Eq)]
91struct Sib {
92 base: Reg,
93 disp: Disp,
94 index: Reg,
95 scale: Scale,
96}
97#[repr(u8)]
98#[derive(Eq, PartialEq, Ord, PartialOrd, Hash)]
99enum Sect {
100 Bss,
101 Data,
102 Idata,
103 Text,
104}
105struct Assembler {
106 addr_sect: HashMap<usize, Sect>,
107 dlls: Dlls,
108 rva: HashMap<Sect, u32>,
109 sym_addr: HashMap<usize, u32>,
110}
111type Dlls = Vec<(&'static str, Vec<(u16, &'static str)>)>;
112#[expect(dead_code)]
113#[derive(Clone, Debug)]
114enum Inst {
115 AddRId(Reg, u32),
116 AddRR(Reg, Reg),
117 AndRbRb(Reg, Reg),
118 Bss(usize, u32),
119 Byte(usize, u8),
120 Call(usize),
121 CallApi((usize, usize)),
122 Clear(Reg),
123 CmpRIb(Reg, i8),
124 Cqo,
125 IDivR(Reg),
126 IMulRR(Reg, Reg),
127 Jmp(usize),
128 JzJe(usize),
129 Label(usize),
130 LeaRM(Reg, VarKind),
131 MovMId(VarKind, u32),
132 MovMbIb(VarKind, u8),
133 MovMbRb(VarKind, Reg),
134 MovQQ(OpQ, OpQ),
135 MovRbIb(Reg, u8),
136 MovRbMb(Reg, VarKind),
137 MovRdId(Reg, u32),
138 NegR(Reg),
139 NotRb(Reg),
140 OrRbRb(Reg, Reg),
141 Pop(Reg),
142 Push(Reg),
143 Quad(usize, u64),
144 Ret,
145 Shl1R(Reg),
146 StringZ(usize, String),
147 SubRId(Reg, u32),
148 SubRR(Reg, Reg),
149 TestRR(Reg, Reg),
150 TestRbRb(Reg, Reg),
151 TestRdRd(Reg, Reg),
152 XorRR(Reg, Reg),
153 XorRbRb(Reg, Reg),
154}
155#[derive(Debug, Clone, Copy, PartialEq, Eq)]
156enum OpQ {
157 Args(usize),
158 Iq(u64),
159 Mq(VarKind),
160 Rq(Reg),
161}
162#[derive(Copy, Clone)]
183enum Arity {
184 Any,
185 AtLeast(usize),
186 #[expect(dead_code)]
187 AtMost(usize),
188 Exactly(usize),
189 #[expect(dead_code)]
190 NoArgs,
191 #[expect(dead_code)]
192 Range(usize, usize),
193}
194#[derive(Clone)]
195struct AsmFunc {
196 id: usize,
197 params: Vec<Json>,
198 ret: Box<Json>,
199}
200#[derive(Clone)]
201enum Bind<T> {
202 Lit(T),
203 Var(Label),
204}
205struct Builtin {
206 arg_len: Arity,
207 func: JFunc,
208 scoped: bool,
209 skip_eval: bool,
210}
211type ErrOR<T> = Result<T, Box<dyn Error>>;
212struct FuncInfo {
213 args: IntoIter<WithPos<Json>>,
214 free_list: Vec<(u32, u32)>,
215 len: usize,
216 name: String,
217 pos: Position,
218}
219type JFunc = fn(&mut Jsonpiler, &mut FuncInfo, &mut ScopeInfo) -> ErrOR<Json>;
220#[derive(Clone, Default)]
221enum Json {
222 Array(Bind<Vec<WithPos<Json>>>),
223 Bool(Bind<bool>),
224 Float(Bind<f64>),
225 Function(AsmFunc),
226 Int(Bind<i64>),
227 #[default]
228 Null,
229 Object(Bind<Vec<(WithPos<String>, WithPos<Json>)>>),
230 String(Bind<String>),
231}
232#[doc(hidden)]
233pub struct Jsonpiler {
234 builtin: HashMap<String, Builtin>,
235 ctx: CompileContext,
236 globals: HashMap<String, Json>,
237 import_table: Dlls,
238 insts: Vec<Inst>,
239 parser: Parser,
240 sym_table: HashMap<&'static str, usize>,
241}
242#[derive(Clone, Copy)]
243struct Label {
244 kind: VarKind,
245 size: u32,
246}
247#[derive(Copy, Clone, Default)]
248struct Position {
249 line: usize,
250 offset: usize,
251 size: usize,
252}
253#[derive(Clone, Copy, PartialEq, Eq, Debug)]
254enum VarKind {
255 Global { id: usize },
256 Local { offset: u32 },
257 Tmp { offset: u32 },
258}
259#[derive(Clone, Default)]
260struct WithPos<T> {
261 pos: Position,
262 value: T,
263}