1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
use super::ast::*;
use Statement::*;

pub fn build_conditional_block(
    meta: Meta,
    cond: Expression,
    if_case: Statement,
    else_case: Option<Statement>,
) -> Statement {
    IfThenElse { meta, cond, else_case: else_case.map(Box::new), if_case: Box::new(if_case) }
}

pub fn build_while_block(meta: Meta, cond: Expression, stmt: Statement) -> Statement {
    While { meta, cond, stmt: Box::new(stmt) }
}

pub fn build_initialization_block(
    meta: Meta,
    xtype: VariableType,
    initializations: Vec<Statement>,
) -> Statement {
    InitializationBlock { meta, xtype, initializations }
}
pub fn build_block(meta: Meta, stmts: Vec<Statement>) -> Statement {
    Block { meta, stmts }
}

pub fn build_return(meta: Meta, value: Expression) -> Statement {
    Return { meta, value }
}

pub fn build_declaration(
    meta: Meta,
    xtype: VariableType,
    name: String,
    dimensions: Vec<Expression>,
) -> Statement {
    let is_constant = true;
    Declaration { meta, xtype, name, dimensions, is_constant }
}

pub fn build_substitution(
    meta: Meta,
    var: String,
    access: Vec<Access>,
    op: AssignOp,
    rhe: Expression,
) -> Statement {
    Substitution { meta, var, access, op, rhe }
}

pub fn build_constraint_equality(meta: Meta, lhe: Expression, rhe: Expression) -> Statement {
    ConstraintEquality { meta, lhe, rhe }
}

pub fn build_log_call(meta: Meta, args: Vec<LogArgument>) -> Statement {
    let mut new_args = Vec::new();
    for arg in args {
        match arg {
            LogArgument::LogExp(..) => {
                new_args.push(arg);
            }
            LogArgument::LogStr(str) => {
                new_args.append(&mut split_string(str));
            }
        }
    }
    LogCall { meta, args: new_args }
}

fn split_string(str: String) -> Vec<LogArgument> {
    let mut v = vec![];
    let sub_len = 230;
    let mut cur = str;
    while !cur.is_empty() {
        let (chunk, rest) = cur.split_at(std::cmp::min(sub_len, cur.len()));
        v.push(LogArgument::LogStr(chunk.to_string()));
        cur = rest.to_string();
    }
    v
}

pub fn build_assert(meta: Meta, arg: Expression) -> Statement {
    Assert { meta, arg }
}