Skip to content

Commit 73e678b

Browse files
authored
+ comment support and + excute and + lsp (#41)
1 parent e531aef commit 73e678b

File tree

5 files changed

+92
-2
lines changed

5 files changed

+92
-2
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,10 @@ $ cargo test -p three_body_interpreter
231231
232232
Create issues: [issues](https://github.com/rustq/3body-lang/issues)
233233
234+
## Visual Studio Code Extension
235+
236+
[3body-vscode-language-server](https://marketplace.visualstudio.com/items?itemName=meloalright.3body-vscode-language-server)
237+
234238
## License
235239
236240
[MIT](https://opensource.org/licenses/MIT)

interpreter/src/evaluator/mod.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1225,4 +1225,21 @@ f()
12251225

12261226
assert_eq!(Some(object::Object::Int(5)), eval(input));
12271227
}
1228+
1229+
#[test]
1230+
fn test_comment() {
1231+
let tests = vec![
1232+
(
1233+
"let identity = fn(x) { // function defination here
1234+
x; // just x
1235+
};
1236+
identity(5); // run with param 5",
1237+
Some(object::Object::Int(5)),
1238+
),
1239+
];
1240+
1241+
for (input, expect) in tests {
1242+
assert_eq!(expect, eval(input));
1243+
}
1244+
}
12281245
}

interpreter/src/lexer/mod.rs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,15 @@ impl Lexer {
6363
let tok = match self.ch {
6464
'+' => Token::Plus,
6565
'-' => Token::Minus,
66-
'/' => Token::Slash,
66+
'/' => {
67+
if self.next_is('/') {
68+
self.walk_char();
69+
self.skip_comment();
70+
return self.next_token();
71+
} else {
72+
Token::Slash
73+
}
74+
},
6775
'*' => Token::Asterisk,
6876
'<' => {
6977
if self.next_is('=') {
@@ -181,6 +189,13 @@ impl Lexer {
181189
}
182190
}
183191

192+
fn skip_comment(&mut self) {
193+
while !matches!(self.next_ch(), '\n' | '\0') {
194+
self.walk_char();
195+
}
196+
self.walk_char();
197+
}
198+
184199
fn consume_identifier(&mut self) -> Token {
185200
let start_pos = self.pos;
186201

@@ -331,6 +346,9 @@ if (5 < 10) {
331346
"foobar";
332347
"foo bar";
333348
'foo bar';
349+
"foobar";//
350+
"foo bar"; // just a comment
351+
'foo bar'; // 一段注释
334352
335353
[1, 2];
336354
@@ -433,6 +451,12 @@ if (5 < 10) {
433451
Token::Semicolon,
434452
Token::String(String::from("foo bar")),
435453
Token::Semicolon,
454+
Token::String(String::from("foobar")),
455+
Token::Semicolon,
456+
Token::String(String::from("foo bar")),
457+
Token::Semicolon,
458+
Token::String(String::from("foo bar")),
459+
Token::Semicolon,
436460
Token::Blank,
437461
Token::LBracket,
438462
Token::Int(1),

interpreter/src/parser/mod.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1891,6 +1891,29 @@ return 993322;
18911891
);
18921892
}
18931893

1894+
#[test]
1895+
fn test_comment() {
1896+
let input = "fn(x, y){
1897+
x + y // just return x + y 即可
1898+
}";
1899+
1900+
let mut parser = Parser::new(Lexer::new(input));
1901+
let program = parser.parse();
1902+
1903+
check_parse_errors(&mut parser);
1904+
assert_eq!(
1905+
vec![Stmt::Expr(Expr::Function {
1906+
params: vec![Ident(String::from("x")), Ident(String::from("y"))],
1907+
body: vec![Stmt::Expr(Expr::Infix(
1908+
Infix::Plus,
1909+
Box::new(Expr::Ident(Ident(String::from("x")))),
1910+
Box::new(Expr::Ident(Ident(String::from("y")))),
1911+
))],
1912+
})],
1913+
program,
1914+
);
1915+
}
1916+
18941917
/// errors panic
18951918
18961919
#[test]

src/bin/repl/mod.rs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use three_body_interpreter::lexer::Lexer;
1111
use three_body_interpreter::parser::Parser;
1212
use std::cell::RefCell;
1313
use std::rc::Rc;
14+
use std::fs;
1415

1516

1617
fn main() {
@@ -50,7 +51,7 @@ fn main() {
5051
}
5152
}
5253
}
53-
_ => {
54+
"-h" => {
5455
println!("usage: 3body [option] ... [arg] ...
5556
5657
Options and arguments:
@@ -60,6 +61,27 @@ Options and arguments:
6061
-c cmd : program passed in as string (terminates option list)
6162
- : program in repl (default)
6263
")
64+
},
65+
path => {
66+
let contents = fs::read_to_string(path).expect("Should have been able to read the file");
67+
let mut lexer = Lexer::new(&contents);
68+
let mut parser = Parser::new(lexer);
69+
let program = parser.parse();
70+
let errors = parser.get_errors();
71+
72+
if errors.len() > 0 {
73+
for err in errors {
74+
println!("{:?}", err);
75+
}
76+
return;
77+
}
78+
79+
if let Some(evaluated) = evaluator.eval(&program) {
80+
match evaluated {
81+
object::Object::Null => {},
82+
_ => println!("{}\n", evaluated),
83+
}
84+
}
6385
}
6486
}
6587
return;

0 commit comments

Comments
 (0)