authorgravatar for 11367844+lino-levan@users.noreply.github.comLino Le Van <11367844+lino-levan@users.noreply.github.com> 2024-01-02 14:27:33+01:00
committergravatar for 11367844+lino-levan@users.noreply.github.comLino Le Van <11367844+lino-levan@users.noreply.github.com> 2024-01-02 14:27:33+01:00
logde824b0e32bfb81f03869727ac3ff2006a3492e9
treef07cffa9127dc45d01c2e04fbfcc7fe0efa1e975
parent1d5c7d0343ace11cd5a441a9d59c131181c78dc6

chore: add let support


4 files changed, 52 insertions(+), 0 deletions(-)

examples/easy.blight+4
...@@ -1,3 +1,7 @@...@@ -1,3 +1,7 @@
1var x: int = 0;1var x: int = 0;
2var y: float = 0;2var y: float = 0;
3var z: bigint = 0;3var z: bigint = 0;
4
5let a: int = 0;
6let b: float = 0;
7let c: bigint = 0;
src/transpile/ast.rs+40
...@@ -26,6 +26,11 @@ pub enum Type {...@@ -26,6 +26,11 @@ pub enum Type {
2626
27#[derive(Debug)]27#[derive(Debug)]
28pub enum Ast {28pub enum Ast {
29 ConstantDeclaration {
30 name: String,
31 typ: Type,
32 value: Box<Ast>
33 },
29 VariableDeclaration {34 VariableDeclaration {
30 name: String,35 name: String,
31 typ: Type,36 typ: Type,
...@@ -49,6 +54,41 @@ fn parse_expression(tokens: &mut dyn PeekableIterator<Item=&Token>) -> Result<As...@@ -49,6 +54,41 @@ fn parse_expression(tokens: &mut dyn PeekableIterator<Item=&Token>) -> Result<As
49/// Precondition: There is at least one token in the iterator54/// Precondition: There is at least one token in the iterator
50fn parse_statement(tokens: &mut dyn PeekableIterator<Item=&Token>) -> Result<Ast> {55fn parse_statement(tokens: &mut dyn PeekableIterator<Item=&Token>) -> Result<Ast> {
51 match tokens.next().unwrap() {56 match tokens.next().unwrap() {
57 Token::Let => {
58 let name = match tokens.next() {
59 Some(Token::Identifier(name)) => name,
60 _ => return Err(AstError::new("Expected identifier after var").into())
61 };
62 let typ = match tokens.next() {
63 Some(Token::Colon) => {
64 match tokens.next() {
65 Some(Token::Identifier(typ)) => {
66 match typ.as_str() {
67 "int" => Type::Int,
68 "float" => Type::Float,
69 "bigint" => Type::Bigint,
70 _ => return Err(AstError::new("Expected type after colon").into())
71 }
72 },
73 _ => return Err(AstError::new("Expected type after colon").into())
74 }
75 },
76 _ => return Err(AstError::new("Expected colon after identifier").into())
77 };
78 let value = match tokens.next() {
79 Some(Token::Equals) => parse_expression(tokens)?,
80 _ => return Err(AstError::new("Expected equals after identifier").into())
81 };
82 match tokens.next() {
83 Some(Token::Semicolon) => (),
84 _ => return Err(AstError::new("Expected semicolon after variable declaration").into())
85 };
86 Ok(Ast::ConstantDeclaration {
87 name: name.clone(),
88 typ,
89 value: Box::new(value),
90 })
91 },
52 Token::Var => {92 Token::Var => {
53 let name = match tokens.next() {93 let name = match tokens.next() {
54 Some(Token::Identifier(name)) => name,94 Some(Token::Identifier(name)) => name,
src/transpile/tokenizer.rs+2
...@@ -22,6 +22,7 @@ pub enum Token {...@@ -22,6 +22,7 @@ pub enum Token {
22 Identifier(String),22 Identifier(String),
23 Number(String),23 Number(String),
24 // Keywords24 // Keywords
25 Let,
25 Var,26 Var,
26 Colon,27 Colon,
27 Equals,28 Equals,
...@@ -58,6 +59,7 @@ pub fn tokenize(content: String) -> Result<Vec<Token>> {...@@ -58,6 +59,7 @@ pub fn tokenize(content: String) -> Result<Vec<Token>> {
5859
59 match current_token.as_str() {60 match current_token.as_str() {
60 "var" => tokens.push(Token::Var),61 "var" => tokens.push(Token::Var),
62 "let" => tokens.push(Token::Let),
61 _ => tokens.push(Token::Identifier(current_token)),63 _ => tokens.push(Token::Identifier(current_token)),
62 }64 }
63 },65 },
src/transpile/walker.rs+6
...@@ -9,6 +9,12 @@ fn transpile_helper(tree: Ast) -> String {...@@ -9,6 +9,12 @@ fn transpile_helper(tree: Ast) -> String {
9 _ => format!("let {} = {};\n", name, transpile_helper(*value))9 _ => format!("let {} = {};\n", name, transpile_helper(*value))
10 }10 }
11 },11 },
12 Ast::ConstantDeclaration { name, typ, value } => {
13 match typ {
14 Type::Bigint => format!("const {} = BigInt({});\n", name, transpile_helper(*value)),
15 _ => format!("const {} = {};\n", name, transpile_helper(*value))
16 }
17 }
12 }18 }
13}19}
1420