This commit is contained in:
2026-04-21 11:28:26 +02:00
parent 508b180d63
commit 18fedba119
7 changed files with 38 additions and 32 deletions
+26 -31
View File
@@ -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"));
} }
} }
+1
View File
@@ -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,
+3 -1
View File
@@ -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" }
+4
View File
@@ -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();
+1
View File
@@ -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, ..
+1
View File
@@ -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,
+2
View File
@@ -1,3 +1,5 @@
package main;
export struct MyType { export struct MyType {
export x: int, export x: int,
} }