2023-07-08 20:54:23 -05:00
|
|
|
#[derive(PartialEq, Clone, Debug)]
|
|
|
|
|
pub struct Program(pub Vec<Declaration>);
|
|
|
|
|
|
|
|
|
|
#[derive(PartialEq, Clone, Debug)]
|
2023-07-03 23:11:44 -05:00
|
|
|
pub enum Declaration {
|
|
|
|
|
Function(Function),
|
|
|
|
|
Global(Global),
|
|
|
|
|
Struct(Struct),
|
|
|
|
|
Const(Const),
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-09 00:24:04 -05:00
|
|
|
#[derive(PartialEq, Clone, Debug, Default)]
|
2023-07-03 23:11:44 -05:00
|
|
|
pub struct Varinfo {
|
|
|
|
|
pub typename: Option<String>,
|
2023-08-02 21:56:26 -05:00
|
|
|
pub size: Option<Expr>,
|
2023-07-03 23:11:44 -05:00
|
|
|
}
|
|
|
|
|
|
2023-07-09 00:24:04 -05:00
|
|
|
#[derive(PartialEq, Clone, Debug)]
|
2023-07-03 23:11:44 -05:00
|
|
|
pub struct Global {
|
|
|
|
|
pub name: String,
|
|
|
|
|
pub typename: Option<String>,
|
2023-08-02 21:56:26 -05:00
|
|
|
pub size: Option<Expr>,
|
2023-07-03 23:11:44 -05:00
|
|
|
}
|
|
|
|
|
|
2023-07-09 00:24:04 -05:00
|
|
|
#[derive(PartialEq, Clone, Debug)]
|
2023-07-03 23:11:44 -05:00
|
|
|
pub struct Struct {
|
|
|
|
|
pub name: String,
|
|
|
|
|
pub members: Vec<Member>,
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-09 00:24:04 -05:00
|
|
|
#[derive(PartialEq, Clone, Debug)]
|
2023-07-03 23:11:44 -05:00
|
|
|
pub struct Member {
|
|
|
|
|
pub name: String,
|
|
|
|
|
pub typename: Option<String>,
|
2023-08-02 21:56:26 -05:00
|
|
|
pub size: Option<Expr>,
|
2023-07-03 23:11:44 -05:00
|
|
|
}
|
|
|
|
|
|
2023-07-09 00:24:04 -05:00
|
|
|
#[derive(PartialEq, Clone, Debug)]
|
2023-07-03 23:11:44 -05:00
|
|
|
pub struct Const {
|
|
|
|
|
pub name: String,
|
2023-08-02 21:56:26 -05:00
|
|
|
pub value: Option<Expr>,
|
2023-07-03 23:11:44 -05:00
|
|
|
pub string: Option<String>,
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-08 20:54:23 -05:00
|
|
|
#[derive(PartialEq, Clone, Debug)]
|
|
|
|
|
pub struct Block(pub Vec<Statement>);
|
|
|
|
|
|
|
|
|
|
#[derive(PartialEq, Clone, Debug)]
|
2023-07-03 23:11:44 -05:00
|
|
|
pub struct Function {
|
|
|
|
|
pub name: String,
|
|
|
|
|
pub args: Vec<Argname>,
|
2023-07-08 20:54:23 -05:00
|
|
|
pub body: Block,
|
2023-07-03 23:11:44 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Eq, PartialEq, Clone, Debug)]
|
|
|
|
|
pub struct Argname {
|
|
|
|
|
pub name: String,
|
|
|
|
|
pub typename: Option<String>,
|
|
|
|
|
}
|
2023-07-04 02:49:29 -05:00
|
|
|
|
2023-07-08 19:09:32 -05:00
|
|
|
#[derive(PartialEq, Clone, Debug)]
|
2023-07-04 02:49:29 -05:00
|
|
|
pub enum Statement {
|
|
|
|
|
Return(Return),
|
|
|
|
|
Assignment(Assignment),
|
2023-08-02 21:56:26 -05:00
|
|
|
Expr(Expr),
|
2023-07-04 02:49:29 -05:00
|
|
|
VarDecl(VarDecl),
|
|
|
|
|
Conditional(Conditional),
|
|
|
|
|
WhileLoop(WhileLoop),
|
|
|
|
|
RepeatLoop(RepeatLoop),
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-08 19:09:32 -05:00
|
|
|
#[derive(PartialEq, Clone, Debug)]
|
2023-08-02 21:56:26 -05:00
|
|
|
pub struct Return(pub Option<Expr>);
|
2023-07-04 02:49:29 -05:00
|
|
|
|
2023-07-08 19:09:32 -05:00
|
|
|
#[derive(PartialEq, Clone, Debug)]
|
|
|
|
|
pub struct Assignment {
|
|
|
|
|
pub lvalue: Lvalue,
|
|
|
|
|
pub rvalue: Rvalue,
|
|
|
|
|
}
|
2023-07-04 02:49:29 -05:00
|
|
|
|
2023-07-08 19:09:32 -05:00
|
|
|
#[derive(PartialEq, Clone, Debug)]
|
|
|
|
|
pub enum Lvalue {
|
|
|
|
|
ArrayRef(ArrayRef),
|
|
|
|
|
Name(String),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(PartialEq, Clone, Debug)]
|
|
|
|
|
pub enum Rvalue {
|
2023-08-02 21:56:26 -05:00
|
|
|
Expr(Expr),
|
2023-07-08 19:09:32 -05:00
|
|
|
String(String),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(PartialEq, Clone, Debug)]
|
|
|
|
|
pub struct VarDecl {
|
|
|
|
|
pub name: String,
|
|
|
|
|
pub typename: Option<String>,
|
2023-08-02 21:56:26 -05:00
|
|
|
pub size: Option<Expr>,
|
|
|
|
|
pub initial: Option<Expr>,
|
2023-07-08 19:09:32 -05:00
|
|
|
}
|
2023-07-04 02:49:29 -05:00
|
|
|
|
2023-07-08 20:54:23 -05:00
|
|
|
#[derive(PartialEq, Clone, Debug)]
|
|
|
|
|
pub struct Conditional {
|
2023-08-02 21:56:26 -05:00
|
|
|
pub condition: Expr,
|
2023-07-08 20:54:23 -05:00
|
|
|
pub body: Block,
|
|
|
|
|
pub alternative: Option<Block>,
|
|
|
|
|
}
|
2023-07-04 02:49:29 -05:00
|
|
|
|
2023-07-08 20:54:23 -05:00
|
|
|
#[derive(PartialEq, Clone, Debug)]
|
|
|
|
|
pub struct WhileLoop {
|
2023-08-02 21:56:26 -05:00
|
|
|
pub condition: Expr,
|
2023-07-08 20:54:23 -05:00
|
|
|
pub body: Block,
|
|
|
|
|
}
|
2023-07-04 02:49:29 -05:00
|
|
|
|
2023-07-08 20:54:23 -05:00
|
|
|
#[derive(PartialEq, Clone, Debug)]
|
|
|
|
|
pub struct RepeatLoop {
|
2023-08-02 21:56:26 -05:00
|
|
|
pub count: Expr,
|
2023-07-08 20:54:23 -05:00
|
|
|
pub name: Option<String>,
|
|
|
|
|
pub body: Block,
|
|
|
|
|
}
|
2023-07-04 02:49:29 -05:00
|
|
|
|
|
|
|
|
/// One of the five arithmetical operators
|
|
|
|
|
#[derive(Debug, PartialEq, Copy, Clone)]
|
|
|
|
|
pub enum Operator {
|
|
|
|
|
Add,
|
|
|
|
|
Sub,
|
|
|
|
|
Mul,
|
|
|
|
|
Div,
|
|
|
|
|
Mod,
|
2023-07-08 23:08:22 -05:00
|
|
|
And,
|
|
|
|
|
Or,
|
|
|
|
|
BitAnd,
|
|
|
|
|
BitOr,
|
|
|
|
|
Xor,
|
|
|
|
|
Lt,
|
|
|
|
|
Le,
|
|
|
|
|
Gt,
|
|
|
|
|
Ge,
|
|
|
|
|
Eq,
|
|
|
|
|
Ne,
|
|
|
|
|
Lshift,
|
|
|
|
|
Rshift,
|
2023-07-04 02:49:29 -05:00
|
|
|
}
|
|
|
|
|
|
2023-07-08 23:33:30 -05:00
|
|
|
#[derive(Debug, PartialEq, Copy, Clone)]
|
|
|
|
|
pub enum Prefix {
|
|
|
|
|
Neg,
|
|
|
|
|
Not,
|
2023-08-02 21:56:26 -05:00
|
|
|
Address
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, PartialEq, Clone)]
|
|
|
|
|
pub enum Suffix {
|
|
|
|
|
Subscript(Expr),
|
|
|
|
|
Arglist(Vec<Rvalue>),
|
|
|
|
|
Member(String),
|
2023-07-08 23:33:30 -05:00
|
|
|
}
|
|
|
|
|
|
2023-07-04 02:49:29 -05:00
|
|
|
#[derive(PartialEq, Clone, Debug)]
|
2023-08-02 21:56:26 -05:00
|
|
|
pub struct Expr {
|
|
|
|
|
pub lhs: Val,
|
|
|
|
|
pub op: Option<Operator>,
|
|
|
|
|
pub rhs: Option<BoxExpr>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(PartialEq, Clone, Debug)]
|
|
|
|
|
pub enum Val {
|
|
|
|
|
Number(i32, Vec<Prefix>, Vec<Suffix>),
|
|
|
|
|
Name(String, Vec<Prefix>, Vec<Suffix>),
|
|
|
|
|
Expr(BoxExpr, Vec<Prefix>, Vec<Suffix>),
|
2023-07-04 02:49:29 -05:00
|
|
|
}
|
|
|
|
|
|
2023-08-02 21:56:26 -05:00
|
|
|
impl Val {
|
|
|
|
|
pub fn is_simple(&self) -> bool {
|
|
|
|
|
if let Self::Expr(expr, pre, suf) = &self {
|
|
|
|
|
pre.is_empty() && suf.is_empty() && expr.0.op.is_none()
|
|
|
|
|
} else {
|
|
|
|
|
false
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn inner_expr(self) -> Option<Expr> {
|
|
|
|
|
if let Self::Expr(expr, _, _) = self {
|
|
|
|
|
Some(expr.into())
|
|
|
|
|
} else { None }
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl From<i32> for Val {
|
2023-07-04 02:49:29 -05:00
|
|
|
fn from(val: i32) -> Self {
|
2023-08-02 21:56:26 -05:00
|
|
|
Self::Number(val, vec![], vec![])
|
2023-07-04 02:49:29 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-02 21:56:26 -05:00
|
|
|
impl From<&str> for Val {
|
2023-07-04 02:49:29 -05:00
|
|
|
fn from(s: &str) -> Self {
|
2023-08-02 21:56:26 -05:00
|
|
|
Self::Name(String::from(s), vec![], vec![])
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl From<Expr> for Val {
|
|
|
|
|
fn from(value: Expr) -> Self {
|
|
|
|
|
Self::Expr(value.into(), vec![], vec![])
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl From<BoxExpr> for Val {
|
|
|
|
|
fn from(value: BoxExpr) -> Self {
|
|
|
|
|
Self::Expr(value, vec![], vec![])
|
2023-07-04 02:49:29 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-05 23:19:54 -05:00
|
|
|
#[repr(transparent)]
|
|
|
|
|
#[derive(PartialEq, Clone, Debug)]
|
2023-08-02 21:56:26 -05:00
|
|
|
pub struct BoxExpr(pub Box<Expr>);
|
|
|
|
|
|
|
|
|
|
impl From<Val> for Expr {
|
|
|
|
|
fn from(value: Val) -> Self {
|
|
|
|
|
Self {
|
|
|
|
|
lhs: value,
|
|
|
|
|
op: None,
|
|
|
|
|
rhs: None
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-07-05 23:19:54 -05:00
|
|
|
|
2023-08-02 21:56:26 -05:00
|
|
|
impl From<i32> for BoxExpr {
|
2023-07-05 23:19:54 -05:00
|
|
|
fn from(val: i32) -> Self {
|
2023-08-02 21:56:26 -05:00
|
|
|
BoxExpr(Box::from(Expr::from(Val::from(val))))
|
2023-07-05 23:19:54 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-02 21:56:26 -05:00
|
|
|
impl From<Expr> for BoxExpr {
|
|
|
|
|
fn from(val: Expr) -> Self {
|
|
|
|
|
BoxExpr(Box::from(val))
|
2023-07-05 23:19:54 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-02 21:56:26 -05:00
|
|
|
impl From<BoxExpr> for Expr {
|
|
|
|
|
fn from(val: BoxExpr) -> Self {
|
2023-07-05 23:19:54 -05:00
|
|
|
*(val.0)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-02 21:56:26 -05:00
|
|
|
impl From<i32> for Expr {
|
|
|
|
|
fn from(value: i32) -> Self {
|
|
|
|
|
Self {
|
|
|
|
|
lhs: Val::Number(value, vec![], vec![]),
|
|
|
|
|
op: None,
|
|
|
|
|
rhs: None
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-05 23:45:04 -05:00
|
|
|
#[derive(PartialEq, Clone, Debug)]
|
|
|
|
|
pub struct ArrayRef {
|
|
|
|
|
pub name: String,
|
2023-08-02 21:56:26 -05:00
|
|
|
pub subscript: BoxExpr,
|
2023-07-05 23:45:04 -05:00
|
|
|
}
|