1use super::error::BitsyError;
2use super::loc::Loc;
3use super::loc::SourceInfo;
4
5use super::{BinOp, Length, Name, UnOp, Width, Pat};
6
7use lalrpop_util::lalrpop_mod;
8use lalrpop_util::ParseError;
9lalrpop_mod!(grammar);
10
11#[derive(Debug, Clone)]
13pub struct Package {
14 pub items: Vec<Item>,
15}
16
17#[derive(Debug, Clone)]
19pub enum Item {
20 ModDef(ModDef),
21 ExtDef(ModDef),
22 EnumTypeDef(EnumTypeDef),
23 StructTypeDef(StructTypeDef),
24 FnDef(FnDef),
25}
26
27impl Item {
28 pub fn name(&self) -> &str {
29 match self {
30 Item::ModDef(ModDef(_loc, name, _decls)) => name,
31 Item::ExtDef(ModDef(_loc, name, _decls)) => name,
32 Item::EnumTypeDef(typedef) => typedef.name.as_str(),
33 Item::StructTypeDef(typedef) => typedef.name.as_str(),
34 Item::FnDef(fndef) => fndef.name.as_str(),
35 }
36 }
37}
38
39#[derive(Debug, Clone)]
40pub struct ModDef(pub Loc, pub Name, pub Vec<Decl>);
41
42#[derive(Debug, Clone)]
44pub enum Decl {
45 Mod(Loc, Name, Vec<Decl>),
46 ModInst(Loc, Name, Name),
47 Incoming(Loc, Name, Type),
48 Outgoing(Loc, Name, Type),
49 Node(Loc, Name, Type),
50 Reg(Loc, Name, Type, Option<Box<Expr>>),
51 Wire(Loc, Wire),
52 When(Loc, When),
53}
54
55#[derive(Debug, Clone)]
57pub struct EnumTypeDef {
58 pub name: String,
59 pub values: Vec<(String, WordLit)>,
60}
61
62#[derive(Debug, Clone)]
64pub struct StructTypeDef {
65 pub name: String,
66 pub fields: Vec<(String, Type)>,
67}
68
69#[derive(Debug, Clone)]
71pub struct FnDef {
72 pub name: String,
73 pub args: Vec<(String, Type)>,
74 pub ret: Type,
75 pub body: Expr,
76}
77
78#[derive(Debug, Clone)]
80pub enum Expr {
81 Ref(Loc, Target),
83 Word(Loc, Option<Width>, u64),
85 Enum(Loc, Type, String),
87 Struct(Loc, Vec<(String, Box<Expr>)>),
89 Vec(Loc, Vec<Expr>),
91 Call(Loc, String, Vec<Expr>),
93 Let(Loc, String, Box<Expr>, Box<Expr>),
95 UnOp(Loc, UnOp, Box<Expr>),
97 BinOp(Loc, BinOp, Box<Expr>, Box<Expr>),
99 If(Loc, Box<Expr>, Box<Expr>, Box<Expr>),
101 Match(Loc, Box<Expr>, Vec<MatchArm>),
103 IdxField(Loc, Box<Expr>, String),
105 Idx(Loc, Box<Expr>, u64),
107 IdxRange(Loc, Box<Expr>, u64, u64),
109 Hole(Loc, Option<String>),
111}
112
113#[derive(Debug, Clone)]
115pub enum Target {
116 Local(Name),
117 Nonlocal(Name, Name),
118}
119
120#[derive(Debug, Clone, PartialEq, Eq)]
122pub enum WireType {
123 Direct,
125 Latch,
127 Proc,
129}
130
131#[derive(Debug, Clone)]
133pub struct Wire(pub Loc, pub Target, pub Box<Expr>, pub WireType);
134
135#[derive(Clone, Debug)]
137pub struct MatchArm(pub Pat, pub Box<Expr>);
138
139#[derive(Debug, Clone, PartialEq, Eq)]
141pub struct WordLit(pub Option<Width>, pub u64);
142
143#[derive(Clone, Debug)]
145pub enum Type {
146 Word(Width),
148 Vec(Box<Type>, Length),
150 Valid(Box<Type>),
152 TypeRef(String),
154}
155
156#[derive(Debug, Clone)]
158pub struct When(pub Box<Expr>, pub Vec<Wire>);
159
160pub fn parse_package_from_string(package_text: &str) -> Result<Package, Vec<BitsyError>> {
161 let source_info = SourceInfo::from_string(package_text);
162 match grammar::PackageParser::new().parse(&source_info, &package_text) {
163 Err(ParseError::UnrecognizedToken { token, expected }) => {
164 let start_idx = token.0;
165 let end_idx = token.2;
166 let loc = Loc::from(&source_info, start_idx, end_idx);
167
168 let message = format!("Parse error: Expected one of {}", expected.join(" "));
169 return Err(vec![BitsyError::ParseError(loc, message)]);
170 },
171 Err(ParseError::InvalidToken { location }) => {
172 let loc = Loc::from(&source_info, location, location + 1);
173 let message = format!("Parse error");
174 return Err(vec![BitsyError::ParseError(loc, message)]);
175 },
176 Err(ParseError::ExtraToken { token }) => {
177 let start_idx = token.0;
178 let end_idx = token.2;
179 let loc = Loc::from(&source_info, start_idx, end_idx);
180 let message = format!("Parse error: extra token: {token:?}");
181 return Err(vec![BitsyError::ParseError(loc, message)]);
182 },
183 Err(ParseError::UnrecognizedEof { location, expected }) => {
184 let loc = Loc::from(&source_info, location, location + 1);
185 let message = format!("Parse error: Unexpected end of file: Expected {expected:?}");
186 return Err(vec![BitsyError::ParseError(loc, message)]);
187 },
188 Err(ParseError::User { error }) => {
189 let message = format!("Parse error: {error:?}");
190 return Err(vec![BitsyError::ParseError(Loc::unknown(), message)]);
191 },
192 Ok(package) => Ok(package),
193 }
194}