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}