1use serde::{Deserialize, Serialize};
2use crate::{node::*, utils::{get_num, get_str, get_sym}};
3
4
5#[derive(Debug, Clone)]
6#[derive(Serialize, Deserialize)]
7pub struct LabelInfo {
8 label_name: String,
9 start: usize,
10 end: usize
11}
12
13#[derive(Debug, Clone)]
14#[derive(Serialize, Deserialize)]
15pub struct PosInfo {
16 pub file: usize,
17 pub line: usize,
18 pub col: usize,
19 pub start: usize,
20 pub end: usize
21}
22
23#[derive(Debug, Clone)]
24#[derive(Serialize, Deserialize)]
25pub struct BlockMap{
26 pub file_list: Vec<String>,
27 pub type_info_table: Vec<TypeBind>,
28 pub label_table: Vec<LabelInfo>,
29 pub pos_table: Vec<PosInfo>,
30 pub inst_table: Vec<Node>
31}
32
33#[derive(Debug, Clone)]
34#[derive(Serialize, Deserialize)]
35pub struct TypeBind {
36 pub label: String,
37 pub type_name: String,
38}
39
40pub fn block(i: Vec<Node>) -> BlockMap {
41 let mut file_list: Vec<String> = vec![];
42 let mut type_info_table: Vec<TypeBind> = vec![];
43 let mut label_table: Vec<LabelInfo> = vec![];
44 let mut pos_table: Vec<PosInfo> = vec![];
45 let mut inst_table: Vec<Node> = vec![];
46 let mut offset: usize = 0;
47 let mut label_record: Option<(String, usize)> = None;
48 let mut pos_record: Option<(usize, usize, usize, usize)> = None;
49 for i in i {
50 if let Node::Label(Label(Symbol(i, _))) = i.clone() {
51 if let Some((label, start)) = label_record.clone() {
52 label_table.push(LabelInfo {
53 label_name: label,
54 start,
55 end: offset,
56 });
57 }
58 if let Some((file, line, col, start)) = pos_record {
59 pos_table.push(PosInfo {
60 file, line, col, start,
61 end: offset,
62 });
63 }
64 label_record = Some((i, offset));
65 continue;
66 }
67 if let Node::PseudoOps(Pseudo(op, exprs)) = i.clone() {
68 if op.as_str() == "loc" {
69 if let Some((file, line, col, start)) = pos_record {
70 let end = offset;
71 pos_table.push(PosInfo { file, line, col, start, end });
72 }
73 let file = get_num(exprs.get(0).unwrap()).parse::<usize>().unwrap();
74 let line = get_num(exprs.get(1).unwrap()).parse::<usize>().unwrap();
75 let col = get_num(exprs.get(2).unwrap()).parse::<usize>().unwrap();
76 pos_record = Some((file, line, col, offset));
77 continue;
78 }
79 if op.as_str() == "file" {
80 match exprs.len() {
81 1 => {
82 let file_name = get_str(exprs.get(0).unwrap());
83 file_list.insert(0, file_name)
84 }
85 2 => {
86 let offset = get_num(exprs.get(0).unwrap()).parse::<usize>().unwrap();
87 let file_name = get_str(exprs.get(1).unwrap());
88 file_list.insert(offset, file_name)
89 }
90 _ => unreachable!("wtf")
91 }
92 continue;
93 }
94 if op.as_str() == "type" {
95 let label = get_sym(exprs.get(0).unwrap());
96 let type_name = get_sym(exprs.get(1).unwrap());
97 type_info_table.push(TypeBind { label, type_name });
98 continue;
99 }
100 }
101
102 inst_table.push(i);
103 offset+=1;
104 }
105 BlockMap{
106 file_list,
107 type_info_table,
108 label_table,
109 pos_table,
110 inst_table,
111 }
112}