Skip to content

Commit 2ff305a

Browse files
committed
Start adding type information to AST
1 parent 156e5fb commit 2ff305a

10 files changed

Lines changed: 183 additions & 34 deletions

File tree

examples/compiler.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ fn main() -> ExprResult<()> {
1212

1313
let env = CompileTimeEnv::new(args.vars.clone(), vec![], vec![], vec![]);
1414

15-
let bytecode = compile(&(ast, 0..source.len()), &env)?;
15+
let bytecode = compile(&mut (ast, 0..source.len()), &env)?;
1616

1717
eprintln!("{bytecode:#?}");
1818

examples/disassembler.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ fn main() -> ExprResult<()> {
1414

1515
let env = CompileTimeEnv::new(args.vars, args.prompts, args.secrets, vec![]);
1616

17-
let bytecode = compile(&(ast, 0..source.len()), &env)?;
17+
let bytecode = compile(&mut (ast, 0..source.len()), &env)?;
1818

1919
let disassemble = Disassembler::new(&bytecode, &env);
2020
let disassembly = disassemble.disassemble();

examples/interpreter.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ fn main() -> ExprResult<()> {
1717

1818
let env = CompileTimeEnv::new(var_keys, prompt_keys, secret_keys, client_context_keys);
1919

20-
let bytecode = compile(&(ast, 0..source.len()), &env)?;
20+
let bytecode = compile(&mut (ast, 0..source.len()), &env)?;
2121

2222
let mut vm = Vm::new();
2323

examples/repl.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ fn main() -> ExprResult<()> {
267267
continue;
268268
}
269269

270-
let bytecode = compile(&(ast, 0..source.len()), &env);
270+
let bytecode = compile(&mut (ast, 0..source.len()), &env);
271271

272272
match bytecode {
273273
Ok(bytecode) => {

src/ast.rs

Lines changed: 93 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! Abstract syntax tree types
22
3-
use crate::{span::Spanned, types::Type};
3+
use crate::{prelude::CompileTimeEnv, span::Spanned, types::Type};
44

55
#[derive(Debug, PartialEq)]
66
pub enum Expr {
@@ -16,6 +16,14 @@ impl Expr {
1616
Self::Identifier(Box::new(ExprIdentifier::new(identifier)))
1717
}
1818

19+
pub fn identifier_with_type(identifier: &str, ty: Type) -> Self {
20+
Self::Identifier(Box::new(ExprIdentifier(
21+
identifier.to_string(),
22+
ExprIdentifier::get_identifier_kind(identifier),
23+
Some(ty),
24+
)))
25+
}
26+
1927
pub fn identifier_name(&self) -> Option<&str> {
2028
match self {
2129
Expr::Identifier(expr_identifier) => Some(expr_identifier.lookup_name()),
@@ -152,3 +160,87 @@ impl ExprBool {
152160
}
153161

154162
pub type ExprS = Spanned<Expr>;
163+
164+
pub fn add_type_to_expr_parse(expr: &mut Expr) {
165+
match expr {
166+
Expr::Identifier(expr_identifier) => match expr_identifier.identifier_kind() {
167+
IdentifierKind::Builtin => {}
168+
IdentifierKind::Var => {
169+
expr_identifier.2 = Some(Type::String);
170+
}
171+
IdentifierKind::Prompt => {
172+
expr_identifier.2 = Some(Type::String);
173+
}
174+
IdentifierKind::Secret => {
175+
expr_identifier.2 = Some(Type::String);
176+
}
177+
IdentifierKind::Client => {
178+
expr_identifier.2 = Some(Type::String);
179+
}
180+
},
181+
Expr::Call(expr_call) => {
182+
for arg in &mut expr_call.args {
183+
add_type_to_expr_parse(&mut arg.0);
184+
}
185+
}
186+
_ => {}
187+
}
188+
}
189+
190+
pub fn add_type_to_expr(expr: &mut Expr, env: &CompileTimeEnv) {
191+
match expr {
192+
Expr::Identifier(expr_identifier) => match expr_identifier.identifier_kind() {
193+
IdentifierKind::Builtin => {
194+
if let Some((_, index)) = env.get_builtin_index(expr_identifier.lookup_name()) {
195+
if let Some(v) = env.get_builtin(index as usize) {
196+
let v_type: Type = v.clone().into();
197+
198+
expr_identifier.2 = Some(v_type);
199+
}
200+
} else if let Some((_, index)) =
201+
env.get_user_builtin_index(expr_identifier.lookup_name())
202+
{
203+
if let Some(v) = env.get_builtin(index as usize) {
204+
let v_type: Type = v.clone().into();
205+
206+
expr_identifier.2 = Some(v_type);
207+
}
208+
}
209+
}
210+
IdentifierKind::Var => {
211+
let index = env.get_var_index(expr_identifier.lookup_name());
212+
213+
if let Some(_) = index {
214+
expr_identifier.2 = Some(Type::String);
215+
}
216+
}
217+
IdentifierKind::Prompt => {
218+
let index = env.get_prompt_index(expr_identifier.lookup_name());
219+
220+
if let Some(_) = index {
221+
expr_identifier.2 = Some(Type::String);
222+
}
223+
}
224+
IdentifierKind::Secret => {
225+
let index = env.get_secret_index(expr_identifier.lookup_name());
226+
227+
if let Some(_) = index {
228+
expr_identifier.2 = Some(Type::String);
229+
}
230+
}
231+
IdentifierKind::Client => {
232+
let index = env.get_client_context_index(expr_identifier.lookup_name());
233+
234+
if let Some(_) = index {
235+
expr_identifier.2 = Some(Type::String);
236+
}
237+
}
238+
},
239+
Expr::Call(expr_call) => {
240+
for arg in &mut expr_call.args {
241+
add_type_to_expr(&mut arg.0, env);
242+
}
243+
}
244+
_ => {}
245+
}
246+
}

src/compiler.rs

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use std::rc::Rc;
44

55
use crate::{
6-
ast::{Expr, ExprS, IdentifierKind},
6+
ast::{Expr, ExprS, IdentifierKind, add_type_to_expr},
77
builtins::{BuiltinFn, BuiltinFns},
88
errors::{
99
CompileError::{self, WrongNumberOfArgs},
@@ -235,14 +235,41 @@ impl CompileTimeEnv {
235235
self.vars.get(index)
236236
}
237237

238+
pub fn get_var_index(&self, name: &str) -> Option<usize> {
239+
let index = self
240+
.vars
241+
.iter()
242+
.position(|context_name| context_name == name);
243+
244+
index
245+
}
246+
238247
pub fn get_prompt(&self, index: usize) -> Option<&String> {
239248
self.prompts.get(index)
240249
}
241250

251+
pub fn get_prompt_index(&self, name: &str) -> Option<usize> {
252+
let index = self
253+
.prompts
254+
.iter()
255+
.position(|context_name| context_name == name);
256+
257+
index
258+
}
259+
242260
pub fn get_secret(&self, index: usize) -> Option<&String> {
243261
self.secrets.get(index)
244262
}
245263

264+
pub fn get_secret_index(&self, name: &str) -> Option<usize> {
265+
let index = self
266+
.secrets
267+
.iter()
268+
.position(|context_name| context_name == name);
269+
270+
index
271+
}
272+
246273
pub fn get_client_context(&self, index: usize) -> Option<&String> {
247274
self.client_context.get(index)
248275
}
@@ -323,7 +350,7 @@ pub fn get_version_bytes() -> [u8; 4] {
323350
}
324351

325352
/// Compile an [`ast::Expr`] into [`ExprByteCode`]
326-
pub fn compile(expr: &ExprS, env: &CompileTimeEnv) -> ExprResult<ExprByteCode> {
353+
pub fn compile(expr: &mut ExprS, env: &CompileTimeEnv) -> ExprResult<ExprByteCode> {
327354
let mut strings: Vec<String> = vec![];
328355
let mut codes = vec![];
329356

@@ -335,7 +362,7 @@ pub fn compile(expr: &ExprS, env: &CompileTimeEnv) -> ExprResult<ExprByteCode> {
335362
}
336363

337364
fn compile_expr(
338-
(expr, span): &ExprS,
365+
(expr, span): &mut ExprS,
339366
env: &CompileTimeEnv,
340367
strings: &mut Vec<String>,
341368
) -> ExprResult<Vec<u8>> {
@@ -344,6 +371,8 @@ fn compile_expr(
344371
let mut codes = vec![];
345372
let mut errs: Vec<ExprErrorS> = vec![];
346373

374+
add_type_to_expr(expr, env);
375+
347376
match expr {
348377
Expr::String(string) => {
349378
if let Some(index) = strings.iter().position(|x| x == &string.0) {
@@ -414,7 +443,7 @@ fn compile_expr(
414443
}
415444
}
416445
Expr::Call(expr_call) => {
417-
let callee_bytecode = compile_expr(&expr_call.callee, env, strings)?;
446+
let callee_bytecode = compile_expr(&mut expr_call.callee, env, strings)?;
418447

419448
if let Some(_op) = callee_bytecode.first()
420449
&& let Some(lookup) = callee_bytecode.get(1)
@@ -485,7 +514,7 @@ fn compile_expr(
485514

486515
codes.extend(callee_bytecode);
487516

488-
for arg in expr_call.args.iter() {
517+
for arg in expr_call.args.iter_mut() {
489518
match compile_expr(arg, env, strings) {
490519
Ok(arg_bytecode) => {
491520
codes.extend(arg_bytecode);

src/parser.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use lalrpop_util::lalrpop_mod;
44

55
use crate::{
6-
ast,
6+
ast::{self, add_type_to_expr_parse},
77
errors::{ExprResult, SyntaxError},
88
lexer::lex,
99
parser::grammar::ExprParser,
@@ -21,14 +21,16 @@ pub fn parse(source: &str) -> ExprResult<ast::Expr> {
2121

2222
let mut parser_errors = Vec::new();
2323

24-
let expr = match expr_parser.parse(source, &mut parser_errors, tokens) {
24+
let mut expr = match expr_parser.parse(source, &mut parser_errors, tokens) {
2525
Ok(ast) => ast,
2626
Err(err) => {
2727
errs.push(SyntaxError::from_parser_error(err, source));
2828
ast::Expr::Error
2929
}
3030
};
3131

32+
add_type_to_expr_parse(&mut expr);
33+
3234
errs.extend(parser_errors);
3335

3436
if errs.is_empty() { Ok(expr) } else { Err(errs) }

src/types.rs

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1-
use std::fmt::{Debug, Display};
1+
use std::{
2+
fmt::{Debug, Display},
3+
rc::Rc,
4+
};
25

3-
use crate::value::Value;
6+
use crate::{prelude::BuiltinFn, value::Value};
47

58
#[derive(Clone, PartialEq)]
69
pub enum Type {
@@ -85,6 +88,29 @@ impl From<Value> for Type {
8588
}
8689
}
8790

91+
impl From<Rc<BuiltinFn>> for Type {
92+
fn from(value: Rc<BuiltinFn>) -> Self {
93+
let args: Vec<Type> = value
94+
.args
95+
.iter()
96+
.filter(|x| x.variadic == false)
97+
.map(|x| x.ty.clone())
98+
.collect();
99+
let varg = value
100+
.args
101+
.iter()
102+
.find(|x| x.variadic == true)
103+
.map(|x| Box::new(x.ty.clone()));
104+
let returns = value.return_type.clone();
105+
106+
Self::Fn {
107+
args,
108+
variadic_arg: varg,
109+
returns: returns.into(),
110+
}
111+
}
112+
}
113+
88114
#[cfg(test)]
89115
mod from_tests {
90116
use std::rc::Rc;

0 commit comments

Comments
 (0)