Skip to content

Commit ff4e8da

Browse files
committed
Merge branch 'master' into newinit
2 parents ba8990e + 0199137 commit ff4e8da

34 files changed

+476
-232
lines changed

Cargo.lock

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

parser/src/ast.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,12 @@ pub enum Statement {
7171
Expression {
7272
expression: Expression,
7373
},
74+
Global {
75+
names: Vec<String>,
76+
},
77+
Nonlocal {
78+
names: Vec<String>,
79+
},
7480
If {
7581
test: Expression,
7682
body: Vec<LocatedStatement>,

parser/src/lexer.rs

Lines changed: 37 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
44
pub use super::token::Tok;
55
use std::collections::HashMap;
6+
use std::str::FromStr;
67

78
pub struct Lexer<T: Iterator<Item = char>> {
89
chars: T,
@@ -287,18 +288,37 @@ where
287288
}
288289

289290
// If float:
290-
if let Some('.') = self.chr0 {
291-
value_text.push(self.next_char().unwrap());
292-
while self.is_number() {
291+
if self.chr0 == Some('.') || self.chr0 == Some('e') {
292+
// Take '.':
293+
if self.chr0 == Some('.') {
293294
value_text.push(self.next_char().unwrap());
295+
while self.is_number() {
296+
value_text.push(self.next_char().unwrap());
297+
}
294298
}
295-
}
296299

297-
let end_pos = self.get_pos();
300+
// 1e6 for example:
301+
if self.chr0 == Some('e') {
302+
value_text.push(self.next_char().unwrap());
303+
304+
// Optional +/-
305+
if self.chr0 == Some('-') || self.chr0 == Some('+') {
306+
value_text.push(self.next_char().unwrap());
307+
}
298308

299-
let value = value_text;
309+
while self.is_number() {
310+
value_text.push(self.next_char().unwrap());
311+
}
312+
}
300313

301-
return Ok((start_pos, Tok::Number { value: value }, end_pos));
314+
let end_pos = self.get_pos();
315+
let value = f64::from_str(&value_text).unwrap();
316+
Ok((start_pos, Tok::Float { value: value }, end_pos))
317+
} else {
318+
let end_pos = self.get_pos();
319+
let value = i32::from_str(&value_text).unwrap();
320+
Ok((start_pos, Tok::Int { value: value }, end_pos))
321+
}
302322
}
303323

304324
fn lex_comment(&mut self) {
@@ -946,7 +966,7 @@ mod tests {
946966
fn $name() {
947967
let source = String::from(format!(r"99232 # {}", $eol));
948968
let tokens = lex_source(&source);
949-
assert_eq!(tokens, vec![Tok::Number { value: "99232".to_string() }]);
969+
assert_eq!(tokens, vec![Tok::Int { value: 99232 }]);
950970
}
951971
)*
952972
}
@@ -969,9 +989,9 @@ mod tests {
969989
assert_eq!(
970990
tokens,
971991
vec![
972-
Tok::Number { value: "123".to_string() },
992+
Tok::Int { value: 123 },
973993
Tok::Newline,
974-
Tok::Number { value: "456".to_string() },
994+
Tok::Int { value: 456 },
975995
]
976996
)
977997
}
@@ -996,17 +1016,11 @@ mod tests {
9961016
name: String::from("avariable"),
9971017
},
9981018
Tok::Equal,
999-
Tok::Number {
1000-
value: "99".to_string()
1001-
},
1019+
Tok::Int { value: 99 },
10021020
Tok::Plus,
1003-
Tok::Number {
1004-
value: "2".to_string()
1005-
},
1021+
Tok::Int { value: 2 },
10061022
Tok::Minus,
1007-
Tok::Number {
1008-
value: "0".to_string()
1009-
},
1023+
Tok::Int { value: 0 },
10101024
]
10111025
);
10121026
}
@@ -1031,7 +1045,7 @@ mod tests {
10311045
Tok::Newline,
10321046
Tok::Indent,
10331047
Tok::Return,
1034-
Tok::Number { value: "99".to_string() },
1048+
Tok::Int { value: 99 },
10351049
Tok::Newline,
10361050
Tok::Dedent,
10371051
]
@@ -1074,7 +1088,7 @@ mod tests {
10741088
Tok::Newline,
10751089
Tok::Indent,
10761090
Tok::Return,
1077-
Tok::Number { value: "99".to_string() },
1091+
Tok::Int { value: 99 },
10781092
Tok::Newline,
10791093
Tok::Dedent,
10801094
Tok::Dedent,
@@ -1106,9 +1120,9 @@ mod tests {
11061120
},
11071121
Tok::Equal,
11081122
Tok::Lsqb,
1109-
Tok::Number { value: "1".to_string() },
1123+
Tok::Int { value: 1 },
11101124
Tok::Comma,
1111-
Tok::Number { value: "2".to_string() },
1125+
Tok::Int { value: 2 },
11121126
Tok::Rsqb,
11131127
Tok::Newline,
11141128
]

parser/src/python.lalrpop

Lines changed: 46 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
use super::ast;
88
use super::lexer;
99
use std::iter::FromIterator;
10-
use std::str::FromStr;
1110

1211
grammar;
1312

@@ -53,6 +52,8 @@ SmallStatement: ast::LocatedStatement = {
5352
DelStatement,
5453
FlowStatement,
5554
ImportStatement,
55+
GlobalStatement,
56+
NonlocalStatement,
5657
AssertStatement,
5758
};
5859

@@ -282,6 +283,24 @@ DottedName: String = {
282283
},
283284
};
284285

286+
GlobalStatement: ast::LocatedStatement = {
287+
<loc:@L> "global" <names:OneOrMore<Identifier>> => {
288+
ast::LocatedStatement {
289+
location: loc,
290+
node: ast::Statement::Global { names }
291+
}
292+
},
293+
};
294+
295+
NonlocalStatement: ast::LocatedStatement = {
296+
<loc:@L> "nonlocal" <names:OneOrMore<Identifier>> => {
297+
ast::LocatedStatement {
298+
location: loc,
299+
node: ast::Statement::Nonlocal { names }
300+
}
301+
},
302+
};
303+
285304
AssertStatement: ast::LocatedStatement = {
286305
<loc:@L> "assert" <t:Test> <m: ("," Test)?> => {
287306
ast::LocatedStatement {
@@ -400,11 +419,7 @@ ExceptClause: ast::ExceptHandler = {
400419
};
401420

402421
WithStatement: ast::LocatedStatement = {
403-
<loc:@L> "with" <i1:WithItem> <i2:("," WithItem)*> ":" <s:Suite> => {
404-
let mut items = vec![i1];
405-
for item in i2 {
406-
items.push(item.1);
407-
}
422+
<loc:@L> "with" <items:OneOrMore<WithItem>> ":" <s:Suite> => {
408423
ast::LocatedStatement {
409424
location: loc,
410425
node: ast::Statement::With { items: items, body: s },
@@ -808,10 +823,8 @@ Atom: ast::Expression = {
808823
};
809824

810825
TestListComp: Vec<ast::Expression> = {
811-
<e:TestOrStarExpr> <e2:("," TestOrStarExpr)*> <_trailing_comma:","?> => {
812-
let mut res = vec![e];
813-
res.extend(e2.into_iter().map(|x| x.1));
814-
res
826+
<e:OneOrMore<TestOrStarExpr>> <_trailing_comma:","?> => {
827+
e
815828
},
816829
};
817830

@@ -825,10 +838,8 @@ TestListComp2: ast::Expression = {
825838
};
826839

827840
TestDict: Vec<(ast::Expression, ast::Expression)> = {
828-
<e1:DictEntry> <e2:("," DictEntry)*> <_trailing_comma:","?> => {
829-
let mut d = vec![e1];
830-
d.extend(e2.into_iter().map(|x| x.1));
831-
d
841+
<e1:OneOrMore<DictEntry>> <_trailing_comma:","?> => {
842+
e1
832843
}
833844
};
834845

@@ -846,10 +857,8 @@ DictEntry: (ast::Expression, ast::Expression) = {
846857
};
847858

848859
TestSet: Vec<ast::Expression> = {
849-
<e1:Test> <e2:("," Test)*> ","? => {
850-
let mut e = vec![e1];
851-
e.extend(e2.into_iter().map(|x| x.1));
852-
e
860+
<e1:OneOrMore<Test>> ","? => {
861+
e1
853862
}
854863
};
855864

@@ -962,14 +971,22 @@ Comma<T>: Vec<T> = {
962971
}
963972
};
964973

965-
Number: ast::Number = {
966-
<s:number> => {
967-
if s.contains(".") {
968-
ast::Number::Float { value: f64::from_str(&s).unwrap() }
969-
} else {
970-
ast::Number::Integer { value: i32::from_str(&s).unwrap() }
974+
#[inline]
975+
OneOrMore<T>: Vec<T> = {
976+
<i1: T> <i2:("," T)*> => {
977+
let mut items = vec![i1];
978+
items.extend(i2.into_iter().map(|e| e.1));
979+
items
971980
}
972-
}
981+
};
982+
983+
Number: ast::Number = {
984+
<s:int> => {
985+
ast::Number::Integer { value: s }
986+
},
987+
<s:float> => {
988+
ast::Number::Float { value: s }
989+
},
973990
};
974991

975992
StringConstant: ast::Expression = {
@@ -1052,12 +1069,14 @@ extern {
10521069
"finally" => lexer::Tok::Finally,
10531070
"for" => lexer::Tok::For,
10541071
"from" => lexer::Tok::From,
1072+
"global" => lexer::Tok::Global,
10551073
"if" => lexer::Tok::If,
10561074
"in" => lexer::Tok::In,
10571075
"is" => lexer::Tok::Is,
10581076
"import" => lexer::Tok::Import,
10591077
"from" => lexer::Tok::From,
10601078
"lambda" => lexer::Tok::Lambda,
1079+
"nonlocal" => lexer::Tok::Nonlocal,
10611080
"not" => lexer::Tok::Not,
10621081
"or" => lexer::Tok::Or,
10631082
"pass" => lexer::Tok::Pass,
@@ -1070,7 +1089,8 @@ extern {
10701089
"True" => lexer::Tok::True,
10711090
"False" => lexer::Tok::False,
10721091
"None" => lexer::Tok::None,
1073-
number => lexer::Tok::Number { value: <String> },
1092+
int => lexer::Tok::Int { value: <i32> },
1093+
float => lexer::Tok::Float { value: <f64> },
10741094
string => lexer::Tok::String { value: <String> },
10751095
bytes => lexer::Tok::Bytes { value: <Vec<u8>> },
10761096
name => lexer::Tok::Name { name: <String> },

parser/src/token.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
#[derive(Debug, PartialEq)]
33
pub enum Tok {
44
Name { name: String },
5-
Number { value: String },
5+
Int { value: i32 },
6+
Float { value: f64 },
67
Complex { real: f64, imag: f64 },
78
String { value: String },
89
Bytes { value: Vec<u8> },

src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ fn main() {
7070

7171
fn _run_string(vm: &mut VirtualMachine, source: &str, source_path: Option<String>) -> PyResult {
7272
let code_obj = compile::compile(vm, &source.to_string(), compile::Mode::Exec, source_path)?;
73-
debug!("Code object: {:?}", code_obj.borrow());
73+
// trace!("Code object: {:?}", code_obj.borrow());
7474
let builtins = vm.get_builtin_scope();
7575
let vars = vm.context().new_scope(Some(builtins)); // Keep track of local variables
7676
vm.run_code_obj(code_obj, vars)

tests/snippets/basic_types.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@
3636
except TypeError:
3737
pass
3838

39+
a = bytearray([1, 2, 3])
40+
# assert a[1] == 2
41+
3942
assert int() == 0
4043

4144
a = complex(2, 4)

tests/snippets/builtin_bin.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@
66
assert bin(-(2**24)) == '-0b1' + '0' * 24
77
assert bin(-(2**24-1)) == '-0b' + '1' * 24
88

9-
# TODO: change to 2**65 when we have support for pow in bigint
10-
a = 2**20 * 2**20 * 2**25
9+
a = 2 ** 65
1110
assert bin(a) == '0b1' + '0' * 65
1211
assert bin(a-1) == '0b' + '1' * 65
1312
assert bin(-(a)) == '-0b1' + '0' * 65

tests/snippets/builtins.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,6 @@
22
a = list(map(str, [1, 2, 3]))
33
assert a == ['1', '2', '3']
44

5+
x = sum(map(int, a))
6+
assert x == 6
7+

tests/snippets/metaclasses.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ class MC(type):
22
classes = []
33
count = 0
44

5+
def __prepare__(name, bases):
6+
return {'prepared': True}
7+
58
def __new__(cls, name, bases, namespace):
69
MC.classes.append(name)
710
return type.__new__(cls, name, bases, namespace)
@@ -16,10 +19,13 @@ def __new__(cls, count):
1619
self.count = count
1720
return self
1821

19-
class D(object, metaclass=MC):
22+
class D(metaclass=MC):
2023
pass
2124

2225
assert MC == type(C)
2326
assert C == type(C())
2427
assert MC.classes == ['C', 'D']
2528
assert C().count == 2
29+
30+
assert C.prepared
31+
assert D.prepared

0 commit comments

Comments
 (0)