xassembler/
golang.rs

1use crate::{Compile, Identifier, Target, Value, MACHINE_NAME};
2
3use alloc::string::{String, ToString};
4use alloc::vec::Vec;
5
6pub struct Golang;
7
8impl Target for Golang {
9    fn push(value: impl ToString) -> String {
10        format!("{}.Push({})\n", MACHINE_NAME, value.to_string())
11    }
12
13    fn load(identifier: impl ToString) -> String {
14        format!(
15            "{name}{MACHINE}.Load()\n",
16            MACHINE = MACHINE_NAME,
17            name = identifier.to_string()
18        )
19    }
20
21    fn number(number: impl ToString) -> String {
22        format!("NewNumber({})", number.to_string())
23    }
24
25    fn string(string: impl ToString) -> String {
26        format!("NewString({})", string.to_string())
27    }
28
29    fn store(value: impl ToString) -> String {
30        format!("{}{}.Store()\n", value.to_string(), MACHINE_NAME)
31    }
32
33    fn copy(value: impl ToString) -> String {
34        format!("{}{}.Copy()\n", value.to_string(), MACHINE_NAME)
35    }
36
37    fn block(body: impl ToString) -> String {
38        format!(
39            "NewFunction(func({MACHINE} *Machine) {{{}}}, MakeMachine())",
40            body.to_string(),
41            MACHINE = MACHINE_NAME
42        )
43    }
44
45    fn func(body: impl ToString) -> String {
46        format!(
47            "NewFunction(func({MACHINE} *Machine) {{{func}}}, {MACHINE}.Duplicate())",
48            func = body.to_string(),
49            MACHINE = MACHINE_NAME
50        )
51    }
52
53    fn foreign_func(name: impl ToString) -> String {
54        format!(
55            "NewFunction(Xasm_{name}, MakeMachine())",
56            name = name.to_string(),
57        )
58    }
59
60    fn for_loop(
61        counter: impl ToString,
62        element: impl ToString,
63        list: impl ToString,
64        body: impl ToString,
65    ) -> String {
66        format!(
67            "{body}{list}{element}{counter}{MACHINE}.ForLoop()\n",
68            MACHINE = MACHINE_NAME,
69            counter = counter.to_string(),
70            element = element.to_string(),
71            list = list.to_string(),
72            body = Self::push(Self::block(body))
73        )
74    }
75
76    fn while_loop(condition: impl ToString, body: impl ToString) -> String {
77        format!(
78            "{body}{condition}{MACHINE}.WhileLoop()\n",
79            MACHINE = MACHINE_NAME,
80            condition = Self::push(Self::block(condition)),
81            body = Self::push(Self::block(body))
82        )
83    }
84
85    fn if_then_else(
86        condition: impl ToString,
87        then_fn: impl ToString,
88        else_fn: impl ToString,
89    ) -> String {
90        format!(
91            "{else_fn}{then_fn}{condition}{MACHINE}.IfThenElse()\n",
92            MACHINE = MACHINE_NAME,
93            condition = Self::push(Self::block(condition)),
94            then_fn = Self::push(Self::block(then_fn)),
95            else_fn = Self::push(Self::block(else_fn))
96        )
97    }
98
99    fn call(func: impl ToString) -> String {
100        format!(
101            "{func}{MACHINE}.Call()\n",
102            MACHINE = MACHINE_NAME,
103            func = func.to_string()
104        )
105    }
106
107    fn method_call(method_name: impl ToString) -> String {
108        format!(
109            "{method_name}{MACHINE}.MethodCall()\n",
110            method_name = Self::push(method_name.to_string()),
111            MACHINE = MACHINE_NAME
112        )
113    }
114
115    fn assign(pointer_value: impl ToString) -> String {
116        format!(
117            "{pointer_value}{MACHINE}.Assign()\n",
118            pointer_value = pointer_value.to_string(),
119            MACHINE = MACHINE_NAME
120        )
121    }
122
123    fn dotname(head: Value, tail: Vec<Identifier>) -> String {
124        let mut result = Compile::<Self>::compile(head).unwrap();
125        for ident in tail {
126            let Identifier(name) = ident;
127            result += &(Self::push(Self::string(Self::quote(name)))
128                + &format!("{}.Index()\n", MACHINE_NAME));
129        }
130        result
131    }
132
133    fn indexname(head: Value, tail: Vec<Value>) -> String {
134        let mut result = Compile::<Self>::compile(head).unwrap();
135        for value in tail {
136            result += &(Compile::<Self>::compile(value).unwrap()
137                + &format!("{}.Index()\n", MACHINE_NAME));
138        }
139        result
140    }
141}