1use super::ArgSpec;
2use super::Binop;
3use super::RcStr;
4use super::Unop;
5use super::VarScope;
6use std::fmt;
7use std::fmt::Write;
8use std::rc::Rc;
9
10pub struct Source {
11 pub name: RcStr,
12 pub data: RcStr,
13}
14
15impl fmt::Debug for Source {
16 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
17 write!(f, "Source({})", self.name)
18 }
19}
20
21#[derive(Debug, Clone)]
22pub struct Mark {
23 pub source: Rc<Source>,
24 pub pos: usize,
25}
26
27impl Mark {
28 pub fn format(&self) -> String {
29 let mut ret = String::new();
30 let out = &mut ret;
31 writeln!(out, "in {:?} on line {}", self.source.name, self.lineno()).unwrap();
32 let start = self.source.data[..self.pos]
33 .rfind('\n')
34 .map(|x| x + 1)
35 .unwrap_or(0);
36 let end = self.source.data[self.pos..]
37 .find('\n')
38 .map(|x| x + self.pos)
39 .unwrap_or(self.source.data.len());
40 writeln!(out, "{}", &self.source.data[start..end]).unwrap();
41 for _ in start..self.pos {
42 write!(out, " ").unwrap();
43 }
44 writeln!(out, "*").unwrap();
45 ret
46 }
47 pub fn lineno(&self) -> usize {
48 self.source.data[..self.pos].matches('\n').count() + 1
49 }
50}
51
52pub struct File {
53 pub source: Rc<Source>,
54 pub imports: Vec<Import>,
55 pub funcs: Vec<FuncDisplay>,
56 pub body: Stmt,
57
58 pub vars: Vec<Var>,
60}
61
62impl File {
63 pub fn name(&self) -> &RcStr {
64 &self.source.name
65 }
66}
67
68#[derive(Debug, Clone)]
69pub struct Var {
70 pub mark: Mark,
71 pub name: RcStr, pub vscope: VarScope,
73 pub index: u32,
74}
75
76#[derive(Debug, Clone)]
77pub struct Import {
78 pub mark: Mark,
79 pub module_name: RcStr,
80 pub alias: RcStr,
81
82 pub unique_name: RcStr,
84}
85
86pub struct FuncDisplay {
87 pub mark: Mark,
88 pub generator: bool,
89 pub test: bool,
90 pub short_name: RcStr,
91 pub argspec: ArgSpec,
92 pub body: Stmt,
93
94 pub vars: Vec<Var>,
96 pub as_var: Option<Var>,
97}
98
99impl FuncDisplay {
100 pub fn full_name(&self) -> &RcStr {
101 &self.as_var.as_ref().unwrap().name
102 }
103}
104
105pub struct Stmt {
106 pub mark: Mark,
107 pub desc: StmtDesc,
108}
109
110pub enum StmtDesc {
111 Block(Vec<Stmt>),
112 Return(Option<Expr>),
113 Assign(AssignTarget, Vec<AssignTarget>, Expr),
114 Expr(Expr),
115 Print(Expr),
116 Assert(Expr),
117
118 Label(RcStr),
120 Goto(RcStr),
121 If(Vec<(Expr, Stmt)>, Option<Box<Stmt>>),
122 While(Expr, Box<Stmt>),
123 ForIn(AssignTarget, Expr, Box<Stmt>),
124 ForClassic(AssignTarget, Expr, Expr, bool, f64, Box<Stmt>),
125}
126
127pub struct AssignTarget {
128 pub mark: Mark,
129 pub desc: AssignTargetDesc,
130}
131
132pub enum AssignTargetDesc {
133 Name(RcStr),
134 List(Vec<AssignTarget>),
135}
136
137#[derive(Debug)]
138pub struct Expr {
139 pub mark: Mark,
140 pub desc: ExprDesc,
141}
142
143#[derive(Debug)]
144pub enum ExprDesc {
145 Nil,
146 Bool(bool),
147 Number(f64),
148 String(RcStr),
149 List(Vec<Expr>),
150
151 GetVar(RcStr),
152 GetAttr(Box<Expr>, RcStr),
153
154 CallFunc(Box<Expr>, Vec<Expr>),
155
156 Binop(Binop, Box<Expr>, Box<Expr>),
157 Unop(Unop, Box<Expr>),
158
159 Yield(Box<Expr>),
160 Next(Box<Expr>), Disasm(Box<Expr>),
164}