use crate::{Identifier, tir::{TirProgram, TirDeclaration, TirStructure, TirFunction, TirExpression, TirConstant, TirStatement, TirType}}; grammar; pub Program: TirProgram = <(Declaration)*> => TirProgram::new(<>, 512); Declaration: TirDeclaration = { "#" "[" "header" "(" ")" "]" => TirDeclaration::DocumentHeader(<>), "#" "[" "std" "]" => TirDeclaration::RequireStd, "#" "[" "no_std" "]" => TirDeclaration::NoStd, "#" "[" "assert" "(" ")" "]" => TirDeclaration::Assert(<>), "#" "[" "extern" "(" ")" "]" => TirDeclaration::Extern(<>), "#" "[" "include" "(" ")" "]" => TirDeclaration::Include(<>), "#" "[" "memory" "(" ")" "]" => TirDeclaration::Memory(<> as i32), "#" "[" "error" "(" ")" "]" => TirDeclaration::Error(<>), "#" "[" "if" "(" ")" "{" "}" "]" => TirDeclaration::If(cond, code), "#" "[" "if" "(" ")" "{" "}" "else" "{" "}" "]" => TirDeclaration::IfElse(cond, then_code, else_code), "#" "[" "define" "(" "," ")" "]" => TirDeclaration::Constant(None, name, constant), "#" "[" "doc" "(" ")" "]" "const" "=" ";" => TirDeclaration::Constant(Some(doc), name, constant), "const" "=" ";" => TirDeclaration::Constant(None, name, constant), => TirDeclaration::Function(<>), => TirDeclaration::Structure(<>), } Str: String = => String::from(&s[1..s.len()-1]).replace("\\\"", "\"").replace("\\n", "\n").replace("\\r", "\r").replace("\\t", "\t").replace("\\0", "\0"); Char: char = => s.replace("\\'", "'").replace("\\n", "\n").replace("\\r", "\r").replace("\\t", "\t").replace("\\0", "\0").chars().nth(1).unwrap() as char; Num: f64 = { // r"([0-9]+([.][0-9]*)?|[.][0-9]+)" => <>.to_string().parse::().unwrap(), r"([1-9][0-9]*|[0])([.][0-9]+)?" => <>.to_string().parse::().unwrap(), } Ident: Identifier = { => { let mut result = String::new(); for (a, b) in head { result += a; result += b; } result += tail; result } } List: Vec = { )*> => { match end { None => list.iter().map(|(v, s)| v.clone()).collect(), Some(val) => { let mut list: Vec<_> = list.iter().map(|(v, s)| v.clone()).collect(); list.push(val); list } } } } Constant: TirConstant = { "?" ":" => TirConstant::Conditional(Box::new(cond), Box::new(then), Box::new(otherwise)), => <> } ConstantAtom: TirConstant = { "is_movable" "(" ")" => TirConstant::IsMovable(<>), "sizeof" "(" ")" => TirConstant::SizeOf(<>), "is_defined" "(" ")" => TirConstant::IsDefined(<>), "true" => TirConstant::True, "false" => TirConstant::False, => TirConstant::Constant(<>), => TirConstant::Float(<>), => TirConstant::Character(<>), "-" => TirConstant::Subtract(Box::new(TirConstant::Float(0.0)), Box::new(<>)), "!" => TirConstant::Not(Box::new(<>)) } ConstantMathBottom: TirConstant = { "&&" => TirConstant::And(Box::new(l), Box::new(r)), "||" => TirConstant::Or(Box::new(l), Box::new(r)), => <> } ConstantMathLow: TirConstant = { "==" => TirConstant::Equal(Box::new(l), Box::new(r)), "!=" => TirConstant::NotEqual(Box::new(l), Box::new(r)), ">=" => TirConstant::GreaterEqual(Box::new(l), Box::new(r)), ">" => TirConstant::Greater(Box::new(l), Box::new(r)), "<=" => TirConstant::LessEqual(Box::new(l), Box::new(r)), "<" => TirConstant::Less(Box::new(l), Box::new(r)), => <> } ConstantMathMiddle: TirConstant = { "+" => TirConstant::Add(Box::new(l), Box::new(r)), "-" => TirConstant::Subtract(Box::new(l), Box::new(r)), => <> } ConstantMathHigh: TirConstant = { "*" => TirConstant::Multiply(Box::new(l), Box::new(r)), "/" => TirConstant::Divide(Box::new(l), Box::new(r)), => <> } Function: TirFunction = { "#" "[" "doc" "(" ")" "]" "fn" > => TirFunction::new(Some(doc), name, args.iter().map(|(a, _, t)| (a.clone(), t.clone())).collect(), TirType::Void, body), "#" "[" "doc" "(" ")" "]" "fn" > "->" => TirFunction::new(Some(doc), name, args.iter().map(|(a, _, t)| (a.clone(), t.clone())).collect(), return_type, body), "fn" > => TirFunction::new(None, name, args.iter().map(|(a, _, t)| (a.clone(), t.clone())).collect(), TirType::Void, body), "fn" > "->" => TirFunction::new(None, name, args.iter().map(|(a, _, t)| (a.clone(), t.clone())).collect(), return_type, body), } Structure: TirStructure = { "#" "[" "doc" "(" ")" "]" "struct" "{" > "}" => TirStructure::new(Some(doc), name, members.iter().map(|(a, _, t)| (a.clone(), t.clone())).collect(), methods), "struct" "{" > "}" => TirStructure::new(None, name, members.iter().map(|(a, _, t)| (a.clone(), t.clone())).collect(), methods), } Body: Vec = "{" "}" => { let mut result = Vec::new(); for stmt in head { result.push(stmt) } if let Some(stmt) = tail { result.push(stmt) } result }; Type: TirType = { "&" => TirType::Pointer(Box::new(<>)), "&&" => TirType::Pointer(Box::new(TirType::Pointer(Box::new(<>)))), "void" => TirType::Void, "num" => TirType::Float, "bool" => TirType::Boolean, "char" => TirType::Character, => TirType::Structure(<>) } Statement: TirStatement = { => <>, ";" => <> } BodyStatement: TirStatement = { "for" "(" ";" ";" ")" => TirStatement::For(Box::new(pre), cond, Box::new(post), body), "for" "in" ".." => TirStatement::ForRange(var, from, to, body), "while" => TirStatement::While(cond, body), "if" => TirStatement::If(cond, body), "if" "else" => TirStatement::IfElse(cond, then_body, else_body), "if" "else" => { TirStatement::IfElifElse(cond, then_body, elifs.iter().map(|(_, _, cond, body)| (cond.clone(), body.clone())).collect(), else_body) }, } SmallStatement: TirStatement = { "return" > => TirStatement::Return(exprs), "return" => TirStatement::Return(vec![expr]), "free" ":" => TirStatement::Free(addr, size), "let" "=" => TirStatement::AutoDefine(name, expr), "let" ":" "=" => TirStatement::Define(name, t, expr), "=" => TirStatement::AssignVariable(name, expr), "+=" => TirStatement::AddAssignVariable(name, expr), "-=" => TirStatement::SubtractAssignVariable(name, expr), "*=" => TirStatement::MultiplyAssignVariable(name, expr), "/=" => TirStatement::DivideAssignVariable(name, expr), "*" "=" => TirStatement::AssignAddress(lhs, rhs), "*" "+=" => TirStatement::AddAssignAddress(lhs, rhs), "*" "-=" => TirStatement::SubtractAssignAddress(lhs, rhs), "*" "*=" => TirStatement::MultiplyAssignAddress(lhs, rhs), "*" "/=" => TirStatement::DivideAssignAddress(lhs, rhs), "[" "]" "=" => TirStatement::AssignAddress(TirExpression::Index(Box::new(ptr), Box::new(idx)), rhs), "[" "]" "+=" => TirStatement::AddAssignAddress(TirExpression::Index(Box::new(ptr), Box::new(idx)), rhs), "[" "]" "-=" => TirStatement::SubtractAssignAddress(TirExpression::Index(Box::new(ptr), Box::new(idx)), rhs), "[" "]" "*=" => TirStatement::MultiplyAssignAddress(TirExpression::Index(Box::new(ptr), Box::new(idx)), rhs), "[" "]" "/=" => TirStatement::DivideAssignAddress(TirExpression::Index(Box::new(ptr), Box::new(idx)), rhs), "->" "=" => TirStatement::AssignAddress(TirExpression::Method(Box::new(instance), name, vec![]), rhs), "->" "+=" => TirStatement::AddAssignAddress(TirExpression::Method(Box::new(instance), name, vec![]), rhs), "->" "-=" => TirStatement::SubtractAssignAddress(TirExpression::Method(Box::new(instance), name, vec![]), rhs), "->" "*=" => TirStatement::MultiplyAssignAddress(TirExpression::Method(Box::new(instance), name, vec![]), rhs), "->" "/=" => TirStatement::DivideAssignAddress(TirExpression::Method(Box::new(instance), name, vec![]), rhs), => TirStatement::Expression(<>) } Expression: TirExpression = { "?" ":" => TirExpression::Conditional(Box::new(cond), Box::new(then), Box::new(otherwise)), "as" => TirExpression::TypeCast(Box::new(expr), t), "*" => TirExpression::Deref(Box::new(ptr)), => <>, } ExpressionAtom: TirExpression = { "is_movable" "(" ")" => TirExpression::IsMovable(<>), "is_defined" "(" ")" => TirExpression::Constant(TirConstant::IsDefined(<>)), "move" "(" ")" => TirExpression::Move(Box::new(val)), "sizeof" "(" ")" => TirExpression::SizeOf(<>), "alloc" "(" ")" => TirExpression::Alloc(Box::new(size)), > => TirExpression::Call(name, args), "!" > => TirExpression::ForeignCall(name, args), "true" => TirExpression::True, "false" => TirExpression::False, => TirExpression::Variable(<>), => TirExpression::String(<>), "@" => TirExpression::Void, => TirExpression::Constant(TirConstant::Float(<>)), => TirExpression::Character(<>), "!" => TirExpression::Not(Box::new(<>)), "(" ")" => <>, "-" => TirExpression::Subtract(Box::new(TirExpression::Constant(TirConstant::Float(0.0))), Box::new(<>)), } ExpressionBottom: TirExpression = { "&&" => TirExpression::And(Box::new(l), Box::new(r)), "||" => TirExpression::Or(Box::new(l), Box::new(r)), => <> } ExpressionLow: TirExpression = { "==" => TirExpression::Equal(Box::new(l), Box::new(r)), "!=" => TirExpression::NotEqual(Box::new(l), Box::new(r)), ">=" => TirExpression::GreaterEqual(Box::new(l), Box::new(r)), ">" => TirExpression::Greater(Box::new(l), Box::new(r)), "<=" => TirExpression::LessEqual(Box::new(l), Box::new(r)), "<" => TirExpression::Less(Box::new(l), Box::new(r)), => <> } ExpressionMiddle: TirExpression = { "+" => TirExpression::Add(Box::new(l), Box::new(r)), "-" => TirExpression::Subtract(Box::new(l), Box::new(r)), => <> } ExpressionHigh: TirExpression = { "&" "[" "]" => TirExpression::Index(Box::new(ptr), Box::new(idx)), "&" "->" > => TirExpression::Method(Box::new(instance), name, args), "&" "->" => TirExpression::Method(Box::new(instance), name, vec![]), "&" => TirExpression::Refer(name), "[" "]" => TirExpression::Deref(Box::new(TirExpression::Index(Box::new(ptr), Box::new(idx)))), "." > => TirExpression::Method(Box::new(instance), name, args), "." => TirExpression::Method(Box::new(instance), name, vec![]), "->" > => TirExpression::Deref(Box::new(TirExpression::Method(Box::new(instance), name, args))), "->" => TirExpression::Deref(Box::new(TirExpression::Method(Box::new(instance), name, vec![]))), "*" => TirExpression::Multiply(Box::new(l), Box::new(r)), "/" => TirExpression::Divide(Box::new(l), Box::new(r)), => <> }