Package
This commit is contained in:
+26
-31
@@ -1,6 +1,4 @@
|
|||||||
use parser::ast::{
|
use parser::ast::{BinaryOp, Block, Expression, Postfix, Statement, TopLevel, TypeExpr, VarKind};
|
||||||
BinaryOp, Block, Expression, Postfix, Statement, TopLevel, TypeExpr, VarKind,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub struct GoCodegen {
|
pub struct GoCodegen {
|
||||||
output: String,
|
output: String,
|
||||||
@@ -55,7 +53,11 @@ impl GoCodegen {
|
|||||||
}
|
}
|
||||||
self.addln("");
|
self.addln("");
|
||||||
}
|
}
|
||||||
TopLevel::StructDecl { export, name, fields } => {
|
TopLevel::StructDecl {
|
||||||
|
export,
|
||||||
|
name,
|
||||||
|
fields,
|
||||||
|
} => {
|
||||||
let name = if *export { name } else { name };
|
let name = if *export { name } else { name };
|
||||||
self.addln(&format!("type {} struct {{", name));
|
self.addln(&format!("type {} struct {{", name));
|
||||||
self.indent += 1;
|
self.indent += 1;
|
||||||
@@ -73,7 +75,11 @@ impl GoCodegen {
|
|||||||
return_type,
|
return_type,
|
||||||
body,
|
body,
|
||||||
} => {
|
} => {
|
||||||
let name = if *export { format!("{}", name) } else { name.clone() };
|
let name = if *export {
|
||||||
|
format!("{}", name)
|
||||||
|
} else {
|
||||||
|
name.clone()
|
||||||
|
};
|
||||||
let params_str = params
|
let params_str = params
|
||||||
.0
|
.0
|
||||||
.iter()
|
.iter()
|
||||||
@@ -96,6 +102,10 @@ impl GoCodegen {
|
|||||||
self.indent -= 1;
|
self.indent -= 1;
|
||||||
self.addln("}\n");
|
self.addln("}\n");
|
||||||
}
|
}
|
||||||
|
TopLevel::Package(pkg) => {
|
||||||
|
self.addln(&format!("package {}", pkg));
|
||||||
|
self.addln("");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,24 +165,15 @@ impl GoCodegen {
|
|||||||
then_branch,
|
then_branch,
|
||||||
else_branch,
|
else_branch,
|
||||||
} => {
|
} => {
|
||||||
self.add_indented(&format!(
|
self.add_indented(&format!("if {} ", self.generate_expression(condition)));
|
||||||
"if {} ",
|
|
||||||
self.generate_expression(condition)
|
|
||||||
));
|
|
||||||
self.generate_statement(then_branch);
|
self.generate_statement(then_branch);
|
||||||
if let Some(else_br) = else_branch {
|
if let Some(else_br) = else_branch {
|
||||||
self.add_indented("else ");
|
self.add_indented("else ");
|
||||||
self.generate_statement(else_br);
|
self.generate_statement(else_br);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Statement::While {
|
Statement::While { condition, body } => {
|
||||||
condition,
|
self.add_indented(&format!("for {} ", self.generate_expression(condition)));
|
||||||
body,
|
|
||||||
} => {
|
|
||||||
self.add_indented(&format!(
|
|
||||||
"for {} ",
|
|
||||||
self.generate_expression(condition)
|
|
||||||
));
|
|
||||||
self.generate_statement(body);
|
self.generate_statement(body);
|
||||||
}
|
}
|
||||||
Statement::For {
|
Statement::For {
|
||||||
@@ -258,11 +259,7 @@ impl GoCodegen {
|
|||||||
.join(", ");
|
.join(", ");
|
||||||
format!("{}({})", result, args_str)
|
format!("{}({})", result, args_str)
|
||||||
}
|
}
|
||||||
Postfix::Index(idx) => format!(
|
Postfix::Index(idx) => format!("{}[{}]", result, self.generate_expression(idx)),
|
||||||
"{}[{}]",
|
|
||||||
result,
|
|
||||||
self.generate_expression(idx)
|
|
||||||
),
|
|
||||||
Postfix::Binary(op, rhs) => {
|
Postfix::Binary(op, rhs) => {
|
||||||
let op_str = match op {
|
let op_str = match op {
|
||||||
BinaryOp::Plus => "+",
|
BinaryOp::Plus => "+",
|
||||||
@@ -277,12 +274,7 @@ impl GoCodegen {
|
|||||||
BinaryOp::LessThanOrEqual => "<=",
|
BinaryOp::LessThanOrEqual => "<=",
|
||||||
BinaryOp::GreaterThanOrEqual => ">=",
|
BinaryOp::GreaterThanOrEqual => ">=",
|
||||||
};
|
};
|
||||||
format!(
|
format!("{} {} {}", result, op_str, self.generate_expression(rhs))
|
||||||
"{} {} {}",
|
|
||||||
result,
|
|
||||||
op_str,
|
|
||||||
self.generate_expression(rhs)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -299,8 +291,8 @@ impl Default for GoCodegen {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use parser::ast::{Block, Expression, ParamList, Statement, TopLevel, TypeExpr};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use parser::ast::{ParamList, TypeExpr, Block, Statement, Expression, TopLevel};
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_int_literal() {
|
fn test_int_literal() {
|
||||||
@@ -337,7 +329,10 @@ mod tests {
|
|||||||
fn test_struct_decl() {
|
fn test_struct_decl() {
|
||||||
let mut cg = GoCodegen::new();
|
let mut cg = GoCodegen::new();
|
||||||
let mut fields = HashMap::new();
|
let mut fields = HashMap::new();
|
||||||
fields.insert("x".to_string(), (true, TypeExpr::Identifier("int".to_string())));
|
fields.insert(
|
||||||
|
"x".to_string(),
|
||||||
|
(true, TypeExpr::Identifier("int".to_string())),
|
||||||
|
);
|
||||||
let toplevel = TopLevel::StructDecl {
|
let toplevel = TopLevel::StructDecl {
|
||||||
export: true,
|
export: true,
|
||||||
name: "Point".to_string(),
|
name: "Point".to_string(),
|
||||||
@@ -361,4 +356,4 @@ mod tests {
|
|||||||
let output = cg.output.clone();
|
let output = cg.output.clone();
|
||||||
assert!(output.contains("if x"));
|
assert!(output.contains("if x"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ pub enum BinaryOp {
|
|||||||
#[derive(Debug, Clone, Serialize)]
|
#[derive(Debug, Clone, Serialize)]
|
||||||
pub enum TopLevel {
|
pub enum TopLevel {
|
||||||
Import(String),
|
Import(String),
|
||||||
|
Package(String),
|
||||||
StructDecl {
|
StructDecl {
|
||||||
export: bool,
|
export: bool,
|
||||||
name: String,
|
name: String,
|
||||||
|
|||||||
@@ -13,7 +13,9 @@ inner_str = @{ (!"\"" ~ ANY)* }
|
|||||||
|
|
||||||
// ================= TOP LEVEL =================
|
// ================= TOP LEVEL =================
|
||||||
|
|
||||||
top_level = _{ import | function_decl | struct_decl }
|
top_level = _{ import | function_decl | struct_decl | package }
|
||||||
|
|
||||||
|
package = { "package" ~ identifier ~ ";" }
|
||||||
|
|
||||||
export = { "export" }
|
export = { "export" }
|
||||||
|
|
||||||
|
|||||||
@@ -70,6 +70,10 @@ impl TopLevel {
|
|||||||
let path = pair.into_inner().next().unwrap().as_str().to_string();
|
let path = pair.into_inner().next().unwrap().as_str().to_string();
|
||||||
Some(TopLevel::Import(path))
|
Some(TopLevel::Import(path))
|
||||||
}
|
}
|
||||||
|
Rule::package => {
|
||||||
|
let name = pair.into_inner().next().unwrap().as_str().to_string();
|
||||||
|
Some(TopLevel::Package(name))
|
||||||
|
}
|
||||||
Rule::function_decl => {
|
Rule::function_decl => {
|
||||||
let mut inner = pair.into_inner();
|
let mut inner = pair.into_inner();
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ pub fn walk_ast(top_scope: Arc<Scope>, tl: &mut Vec<parser::ast::TopLevel>) {
|
|||||||
for tl in tl {
|
for tl in tl {
|
||||||
match tl {
|
match tl {
|
||||||
parser::ast::TopLevel::Import(_) => unimplemented!(),
|
parser::ast::TopLevel::Import(_) => unimplemented!(),
|
||||||
|
parser::ast::TopLevel::Package(_) => {}
|
||||||
|
|
||||||
parser::ast::TopLevel::FunctionDecl {
|
parser::ast::TopLevel::FunctionDecl {
|
||||||
params, body, name, ..
|
params, body, name, ..
|
||||||
|
|||||||
@@ -112,6 +112,7 @@ impl TopLevelSymbolScope {
|
|||||||
for top in top_level {
|
for top in top_level {
|
||||||
match top {
|
match top {
|
||||||
TopLevel::Import(_) => unimplemented!(),
|
TopLevel::Import(_) => unimplemented!(),
|
||||||
|
TopLevel::Package(_) => {}
|
||||||
|
|
||||||
TopLevel::FunctionDecl {
|
TopLevel::FunctionDecl {
|
||||||
export,
|
export,
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
package main;
|
||||||
|
|
||||||
export struct MyType {
|
export struct MyType {
|
||||||
export x: int,
|
export x: int,
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user