aboutsummaryrefslogtreecommitdiff
path: root/src/lisp
diff options
context:
space:
mode:
authorAkshay <[email protected]>2021-03-24 07:35:05 +0000
committerAkshay <[email protected]>2021-03-24 07:35:05 +0000
commit05c6f24c0b371a465a8735cfd1ac17c0394363cb (patch)
tree98d0f1d45c389e2a4b03ed1874f8306f1b155020 /src/lisp
parentca48cd3a51a19f35f6d2b25a5b3c011c759b6be3 (diff)
allow minus operator, improve display for exprs
Diffstat (limited to 'src/lisp')
-rw-r--r--src/lisp/expr.rs49
-rw-r--r--src/lisp/lex.rs7
-rw-r--r--src/lisp/mod.rs1
3 files changed, 32 insertions, 25 deletions
diff --git a/src/lisp/expr.rs b/src/lisp/expr.rs
index adacc1c..651e41f 100644
--- a/src/lisp/expr.rs
+++ b/src/lisp/expr.rs
@@ -1,7 +1,30 @@
1use std::fmt; 1use std::fmt;
2 2
3use crate::app::AppState; 3use crate::app::AppState;
4use crate::lisp::{error::LispError, number::LispNumber}; 4use crate::lisp::{error::LispError, number::LispNumber, Environment};
5
6#[derive(Clone)]
7pub struct PrimitiveFunc {
8 pub arity: Option<usize>, // minimim arity
9 pub closure: fn(&[LispExpr], &mut AppState) -> Result<LispExpr, LispError>,
10}
11
12impl PrimitiveFunc {
13 pub fn call(&self, args: &[LispExpr], app: &mut AppState) -> Result<LispExpr, LispError> {
14 if let Some(arity) = self.arity {
15 if args.len() < arity {
16 return Err(LispError::EvalError);
17 }
18 }
19 (self.closure)(args, app)
20 }
21}
22
23#[derive(Clone)]
24pub struct LispFunction {
25 pub params: Vec<String>,
26 pub body: Vec<LispExpr>,
27}
5 28
6#[derive(Clone)] 29#[derive(Clone)]
7pub enum LispExpr { 30pub enum LispExpr {
@@ -21,23 +44,6 @@ pub enum LispExpr {
21 Quote(Box<LispExpr>, u32), 44 Quote(Box<LispExpr>, u32),
22} 45}
23 46
24#[derive(Clone)]
25pub struct PrimitiveFunc {
26 pub arity: Option<usize>,
27 pub closure: fn(&[LispExpr], &mut AppState) -> Result<LispExpr, LispError>,
28}
29
30impl PrimitiveFunc {
31 pub fn call(&self, args: &[LispExpr], app: &mut AppState) -> Result<LispExpr, LispError> {
32 if let Some(arity) = self.arity {
33 if args.len() < arity {
34 return Err(LispError::EvalError);
35 }
36 }
37 (self.closure)(args, app)
38 }
39}
40
41impl LispExpr { 47impl LispExpr {
42 pub fn comma(self, n: u32) -> LispExpr { 48 pub fn comma(self, n: u32) -> LispExpr {
43 match self { 49 match self {
@@ -83,7 +89,7 @@ impl fmt::Display for LispExpr {
83 write!(f, " {} ", expr)? 89 write!(f, " {} ", expr)?
84 } 90 }
85 } 91 }
86 LispExpr::StringLit(s) => write!(f, "{:?}", s)?, 92 LispExpr::StringLit(s) => write!(f, "{}", s)?,
87 LispExpr::BoolLit(b) => { 93 LispExpr::BoolLit(b) => {
88 if *b { 94 if *b {
89 write!(f, "#t")? 95 write!(f, "#t")?
@@ -93,7 +99,7 @@ impl fmt::Display for LispExpr {
93 } 99 }
94 LispExpr::Ident(s) => write!(f, "{}", s)?, 100 LispExpr::Ident(s) => write!(f, "{}", s)?,
95 LispExpr::PrimitiveFunc(_) => write!(f, "<#primitive>")?, 101 LispExpr::PrimitiveFunc(_) => write!(f, "<#primitive>")?,
96 LispExpr::Function(_) => write!(f, "<#procedure>")?, 102 LispExpr::Function(func) => write!(f, "<#lambda {}>", func.params.join(" "))?,
97 LispExpr::Quasiquote(val, depth) => { 103 LispExpr::Quasiquote(val, depth) => {
98 write!(f, "{}{}", "`".repeat(*depth as usize), val)? 104 write!(f, "{}{}", "`".repeat(*depth as usize), val)?
99 } 105 }
@@ -104,6 +110,3 @@ impl fmt::Display for LispExpr {
104 Ok(()) 110 Ok(())
105 } 111 }
106} 112}
107
108#[derive(Debug, PartialEq, Clone)]
109enum LispFunction {}
diff --git a/src/lisp/lex.rs b/src/lisp/lex.rs
index 30f49fa..a7b9586 100644
--- a/src/lisp/lex.rs
+++ b/src/lisp/lex.rs
@@ -115,11 +115,13 @@ impl<'a> Lexer<'a> {
115 115
116fn parse_number<'a>(mut input: &'a str) -> Result<(usize, Token<'a>), LispError> { 116fn parse_number<'a>(mut input: &'a str) -> Result<(usize, Token<'a>), LispError> {
117 let mut dot = false; 117 let mut dot = false;
118 let mut minus = false;
118 let mut size = 0; 119 let mut size = 0;
119 let mut chars = input.chars(); 120 let mut chars = input.chars();
120 121
121 if let Some(v) = chars.next() { 122 if let Some(v) = chars.next() {
122 if v == '-' { 123 if v == '-' {
124 minus = true;
123 size += 1; 125 size += 1;
124 input = &input[1..]; 126 input = &input[1..];
125 } else if v.is_digit(10) { 127 } else if v.is_digit(10) {
@@ -143,7 +145,10 @@ fn parse_number<'a>(mut input: &'a str) -> Result<(usize, Token<'a>), LispError>
143 return Err(LispError::ParseError); 145 return Err(LispError::ParseError);
144 } 146 }
145 } 147 }
146 let tok = if dot { 148
149 let tok = if size == 1 && minus {
150 Token::Name("-")
151 } else if dot {
147 Token::Float(&input[..size]) 152 Token::Float(&input[..size])
148 } else { 153 } else {
149 Token::Integer(&input[..size]) 154 Token::Integer(&input[..size])
diff --git a/src/lisp/mod.rs b/src/lisp/mod.rs
index 2a19314..dc08835 100644
--- a/src/lisp/mod.rs
+++ b/src/lisp/mod.rs
@@ -4,7 +4,6 @@ pub mod expr;
4pub mod lex; 4pub mod lex;
5pub mod number; 5pub mod number;
6pub mod parse; 6pub mod parse;
7#[macro_use]
8mod primitives; 7mod primitives;
9 8
10use std::collections::HashMap; 9use std::collections::HashMap;