Skip to content

Commit 15e2742

Browse files
committed
Add float type
1 parent aa963dc commit 15e2742

10 files changed

Lines changed: 89 additions & 29 deletions

File tree

parser/src/ast.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ pub enum Expression {
126126
args: Vec<Expression>,
127127
},
128128
Number {
129-
value: i32,
129+
value: Number,
130130
},
131131
List {
132132
elements: Vec<Expression>,
@@ -196,3 +196,13 @@ pub enum Comparison {
196196
Is,
197197
IsNot,
198198
}
199+
200+
#[derive(Debug, PartialEq, Clone)]
201+
pub enum Number {
202+
Integer {
203+
value: i32,
204+
},
205+
Float {
206+
value: f64,
207+
},
208+
}

parser/src/lexer.rs

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
pub use super::token::Tok;
22
use std::collections::HashMap;
33
use std::str::CharIndices;
4-
use std::str::FromStr;
54

65
pub struct Lexer<'input> {
76
chars: CharIndices<'input>,
@@ -100,9 +99,18 @@ impl<'input> Lexer<'input> {
10099
while self.is_number() {
101100
value_text.push(self.next_char().unwrap());
102101
}
102+
103+
// If float:
104+
if let Some('.') = self.chr0 {
105+
value_text.push(self.next_char().unwrap());
106+
while self.is_number() {
107+
value_text.push(self.next_char().unwrap());
108+
}
109+
}
110+
103111
let end_pos = self.location;
104112

105-
let value = i32::from_str(&value_text).unwrap();
113+
let value = value_text;
106114

107115
return Ok((start_pos, Tok::Number { value: value }, end_pos));
108116
}
@@ -672,7 +680,7 @@ mod tests {
672680
fn $name() {
673681
let source = String::from(format!(r"99232 # {}", $eol));
674682
let tokens = lex_source(&source);
675-
assert_eq!(tokens, vec![Tok::Number { value: 99232 }]);
683+
assert_eq!(tokens, vec![Tok::Number { value: "99232".to_string() }]);
676684
}
677685
)*
678686
}
@@ -695,9 +703,9 @@ mod tests {
695703
assert_eq!(
696704
tokens,
697705
vec![
698-
Tok::Number { value: 123 },
706+
Tok::Number { value: "123".to_string() },
699707
Tok::Newline,
700-
Tok::Number { value: 456 },
708+
Tok::Number { value: "456".to_string() },
701709
]
702710
)
703711
}
@@ -722,11 +730,11 @@ mod tests {
722730
name: String::from("avariable"),
723731
},
724732
Tok::Equal,
725-
Tok::Number { value: 99 },
733+
Tok::Number { value: "99".to_string() },
726734
Tok::Plus,
727-
Tok::Number { value: 2 },
735+
Tok::Number { value: "2".to_string() },
728736
Tok::Minus,
729-
Tok::Number { value: 0 },
737+
Tok::Number { value: "0".to_string() },
730738
]
731739
);
732740
}
@@ -751,7 +759,7 @@ mod tests {
751759
Tok::Newline,
752760
Tok::Indent,
753761
Tok::Return,
754-
Tok::Number { value: 99 },
762+
Tok::Number { value: "99".to_string() },
755763
Tok::Newline,
756764
Tok::Dedent,
757765
]
@@ -794,7 +802,7 @@ mod tests {
794802
Tok::Newline,
795803
Tok::Indent,
796804
Tok::Return,
797-
Tok::Number { value: 99 },
805+
Tok::Number { value: "99".to_string() },
798806
Tok::Newline,
799807
Tok::Dedent,
800808
Tok::Dedent,
@@ -826,9 +834,9 @@ mod tests {
826834
},
827835
Tok::Equal,
828836
Tok::Lsqb,
829-
Tok::Number { value: 1 },
837+
Tok::Number { value: "1".to_string() },
830838
Tok::Comma,
831-
Tok::Number { value: 2 },
839+
Tok::Number { value: "2".to_string() },
832840
Tok::Rsqb,
833841
Tok::Newline,
834842
]

parser/src/parser.rs

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,9 @@ mod tests {
118118
ast::Expression::String {
119119
value: String::from("Hello world"),
120120
},
121-
ast::Expression::Number { value: 2 },
121+
ast::Expression::Number {
122+
value: ast::Number::Integer { value: 2 },
123+
},
122124
],
123125
},
124126
},],
@@ -133,17 +135,27 @@ mod tests {
133135
assert_eq!(
134136
parse_ast,
135137
ast::Statement::If {
136-
test: ast::Expression::Number { value: 1 },
138+
test: ast::Expression::Number {
139+
value: ast::Number::Integer { value: 1 },
140+
},
137141
body: vec![ast::Statement::Expression {
138-
expression: ast::Expression::Number { value: 10 },
142+
expression: ast::Expression::Number {
143+
value: ast::Number::Integer { value: 10 },
144+
},
139145
},],
140146
orelse: Some(vec![ast::Statement::If {
141-
test: ast::Expression::Number { value: 2 },
147+
test: ast::Expression::Number {
148+
value: ast::Number::Integer { value: 2 },
149+
},
142150
body: vec![ast::Statement::Expression {
143-
expression: ast::Expression::Number { value: 20 },
151+
expression: ast::Expression::Number {
152+
value: ast::Number::Integer { value: 20 },
153+
},
144154
},],
145155
orelse: Some(vec![ast::Statement::Expression {
146-
expression: ast::Expression::Number { value: 30 },
156+
expression: ast::Expression::Number {
157+
value: ast::Number::Integer { value: 30 },
158+
},
147159
},]),
148160
},]),
149161
}

parser/src/python.lalrpop

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
use super::ast;
33
use super::lexer;
44
use std::iter::FromIterator;
5+
use std::str::FromStr;
56

67
grammar;
78

@@ -399,7 +400,16 @@ Comma<T>: Vec<T> = {
399400
}
400401
};
401402

402-
Number: i32 = <s:number> => s;
403+
Number: ast::Number = {
404+
<s:number> => {
405+
if s.contains(".") {
406+
ast::Number::Float { value: f64::from_str(&s).unwrap() }
407+
} else {
408+
ast::Number::Integer { value: i32::from_str(&s).unwrap() }
409+
}
410+
}
411+
};
412+
403413
String: String = {
404414
<s:string> => s,
405415
};
@@ -478,7 +488,7 @@ extern {
478488
"True" => lexer::Tok::True,
479489
"False" => lexer::Tok::False,
480490
"None" => lexer::Tok::None,
481-
number => lexer::Tok::Number { value: <i32> },
491+
number => lexer::Tok::Number { value: <String> },
482492
string => lexer::Tok::String { value: <String> },
483493
name => lexer::Tok::Name { name: <String> },
484494
"\n" => lexer::Tok::Newline,

parser/src/token.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
#[derive(Debug, PartialEq)]
33
pub enum Tok {
44
Name { name: String },
5-
Number { value: i32 },
5+
Number { value: String },
66
String { value: String },
77
Newline,
88
Indent,

vm/src/bytecode.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ pub enum Instruction {
112112
#[derive(Debug, Clone)]
113113
pub enum Constant {
114114
Integer { value: i32 }, // TODO: replace by arbitrary big int math.
115-
// TODO: Float { value: f64 },
115+
Float { value: f64 },
116116
Boolean { value: bool },
117117
String { value: String },
118118
Code { code: CodeObject },

vm/src/compile.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -523,8 +523,12 @@ impl Compiler {
523523
self.emit(i);
524524
}
525525
ast::Expression::Number { value } => {
526+
let const_value = match value {
527+
ast::Number::Integer { value } => bytecode::Constant::Integer { value: *value },
528+
ast::Number::Float { value } => bytecode::Constant::Float { value: *value },
529+
};
526530
self.emit(Instruction::LoadConst {
527-
value: bytecode::Constant::Integer { value: *value },
531+
value: const_value,
528532
});
529533
}
530534
ast::Expression::List { elements } => {

vm/src/pyobject.rs

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,10 @@ impl PyContext {
9595
PyObject::new(PyObjectKind::Integer { value: i }, self.type_type.clone())
9696
}
9797

98+
pub fn new_float(&self, i: f64) -> PyObjectRef {
99+
PyObject::new(PyObjectKind::Float { value: i }, self.type_type.clone())
100+
}
101+
98102
pub fn new_str(&self, s: String) -> PyObjectRef {
99103
PyObject::new(PyObjectKind::String { value: s }, self.type_type.clone())
100104
}
@@ -526,6 +530,7 @@ impl PyObject {
526530
match self.kind {
527531
PyObjectKind::String { ref value } => value.clone(),
528532
PyObjectKind::Integer { ref value } => format!("{:?}", value),
533+
PyObjectKind::Float { ref value } => format!("{:?}", value),
529534
PyObjectKind::Boolean { ref value } => format!("{:?}", value),
530535
PyObjectKind::List { ref elements } => format!(
531536
"[{}]",
@@ -568,6 +573,7 @@ impl PyObject {
568573
PyObjectKind::RustFunction { function: _ } => format!("<rustfunc>"),
569574
PyObjectKind::Module { ref name, dict: _ } => format!("<module '{}'>", name),
570575
PyObjectKind::Scope { ref scope } => format!("<scope '{:?}'>", scope),
576+
PyObjectKind::NameError { ref name } => format!("NameError: {:?}", name),
571577
PyObjectKind::Slice {
572578
ref start,
573579
ref stop,
@@ -581,10 +587,6 @@ impl PyObject {
581587
position,
582588
iterated_obj.borrow_mut().str()
583589
),
584-
_ => {
585-
println!("Not impl {:?}", self);
586-
panic!("Not impl");
587-
}
588590
}
589591
}
590592

@@ -632,6 +634,20 @@ impl<'a> Add<&'a PyObject> for &'a PyObject {
632634
PyObjectKind::Integer { value: ref value2 } => PyObjectKind::Integer {
633635
value: value1 + value2,
634636
},
637+
PyObjectKind::Float { value: ref value2 } => PyObjectKind::Float {
638+
value: (*value1 as f64) + value2,
639+
},
640+
_ => {
641+
panic!("NOT IMPL");
642+
}
643+
},
644+
PyObjectKind::Float { value: ref value1 } => match &rhs.kind {
645+
PyObjectKind::Float { value: ref value2 } => PyObjectKind::Float {
646+
value: value1 + value2,
647+
},
648+
PyObjectKind::Integer { value: ref value2 } => PyObjectKind::Float {
649+
value: value1 + (*value2 as f64),
650+
},
635651
_ => {
636652
panic!("NOT IMPL");
637653
}

vm/src/vm.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -547,7 +547,7 @@ impl VirtualMachine {
547547
bytecode::Instruction::LoadConst { ref value } => {
548548
let obj = match value {
549549
&bytecode::Constant::Integer { ref value } => self.ctx.new_int(*value),
550-
// &bytecode::Constant::Float
550+
&bytecode::Constant::Float { ref value } => self.ctx.new_float(*value),
551551
&bytecode::Constant::String { ref value } => self.new_str(value.clone()),
552552
&bytecode::Constant::Boolean { ref value } => self.new_bool(value.clone()),
553553
&bytecode::Constant::Code { ref code } => {

0 commit comments

Comments
 (0)