use std::collections::HashMap; use serde::Serialize; #[derive(Debug, Clone, Serialize)] pub struct ParamList(pub Vec<(String, TypeExpr)>); #[derive(Debug, Clone, Serialize)] pub struct Block(pub Vec); #[derive(Debug, Clone, Serialize)] #[serde(tag = "type", content = "value")] pub enum TypeExpr { Identifier(String), } #[derive(Debug, Clone, Serialize)] pub enum BinaryOp { Plus, Minus, Multiply, Divide, Modulo, Equal, NotEqual, LessThan, GreaterThan, LessThanOrEqual, GreaterThanOrEqual, } #[derive(Debug, Clone, Serialize)] #[serde(tag = "type", content = "value")] pub enum TopLevel { Import(String), StructDecl { export: bool, name: String, fields: ParamList, }, FunctionDecl { export: bool, name: String, params: ParamList, return_type: Option, body: Block, }, } #[derive(Debug, Clone, Serialize)] #[serde(tag = "type", content = "value")] pub enum Postfix { FieldAccess(String), Call(Vec), Index(Expression), Binary(BinaryOp, Expression), } #[derive(Debug, Clone, Serialize)] #[serde(tag = "type", content = "value")] pub enum Statement { // expr; Expression(Expression), // { ... } Block(Block), // let/const/var x = ... VarDecl { kind: VarKind, name: String, init: Option, }, VarAssign { target: Expression, value: Expression, }, // if (...) stmt else stmt If { condition: Expression, then_branch: Box, else_branch: Option>, }, // while (...) stmt While { condition: Expression, body: Box, }, // for (...) stmt For { init: (VarKind, String, Option), condition: Option, update: Option>, body: Box, }, // return expr?; Return(Option), Break, Continue, } #[derive(Debug, Clone, Serialize)] #[serde(tag = "type", content = "value")] pub enum Expression { Identifier(String), IntLiteral(i64), FloatLiteral(f64), BoolLiteral(bool), StringLiteral(String), Postfix { initial: Box, postfixes: Vec, }, } #[derive(Debug, Clone, Serialize)] pub enum VarKind { Let, Const, Var, } impl ParamList { pub fn to_hashmap(&self, f: impl Fn(&String, &TypeExpr) -> T) -> HashMap { self.0.iter().map(|(k, v)| (k.clone(), f(k, v))).collect() } }