rprlib/
block.rs

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}