1 /* This is a simple demo program for the S-Lang interpreter. */
2
3 #include "config.h"
4 #include "slinclud.h"
5
6 #include <stdio.h>
7 #include <math.h>
8 #ifdef HAVE_STDLIB_H
9 # include <stdlib.h>
10 #endif
11
12 #define BENCHMARK_TESTING 0
13
14 #if BENCHMARK_TESTING
15 # include <sys/time.h>
16 # include <sys/resource.h>
17 # include <unistd.h>
18 #endif
19
20 #include "slang.h"
21 #if SLANG_HAS_KANJI_SUPPORT
22 #include "slkanji.h"
23 #endif
24
25 static int open_readline (void);
26 static void close_readline (void);
27
help(void)28 static void help (void)
29 {
30 puts("ALL statements MUST be terminated with a ';' character, e.g., quit();\n");
31 puts("Available functions:");
32 puts(" cos, sin, tan, atan, acos, asin, exp, log, sqrt, fabs, log10, pow, PI, E");
33 puts("\nas well as other intrinsic S-Lang functions.");
34 puts("See S-Lang language documentation for further details.\n");
35 SLang_run_hooks ("calc_help", 0);
36 }
37
38 /* The following three functions will be callable from the interpreter */
quit_calc(void)39 static void quit_calc (void)
40 {
41 close_readline ();
42 exit (SLang_Error);
43 }
44
exit_calc(int * status)45 static void exit_calc (int *status)
46 {
47 close_readline ();
48 exit (*status);
49 }
50
51
52 /* Now here is a table that provides the link between the above functions and
53 the S-Lang interpreter */
54 static SLang_Intrin_Fun_Type Calc_Intrinsics [] =
55 {
56 MAKE_INTRINSIC("quit", quit_calc, SLANG_VOID_TYPE, 0),
57 MAKE_INTRINSIC_I("exit", exit_calc, SLANG_VOID_TYPE),
58 MAKE_INTRINSIC("help", help, SLANG_VOID_TYPE, 0),
59 SLANG_END_INTRIN_FUN_TABLE
60 };
61
62 typedef struct
63 {
64 int i_value;
65 char *s_value;
66 double d_value;
67 }
68 My_Struct_Type;
69
70 static My_Struct_Type My_Struct =
71 {
72 -41,
73 NULL,
74 7.18
75 };
76
77 static My_Struct_Type *My_Struct_Ptr = &My_Struct;
78
79 static SLang_IStruct_Field_Type My_Struct_Field_Table [] =
80 {
81 MAKE_ISTRUCT_FIELD(My_Struct_Type, i_value, "i", SLANG_INT_TYPE, 0),
82 MAKE_ISTRUCT_FIELD(My_Struct_Type, s_value, "s", SLANG_STRING_TYPE, 0),
83 MAKE_ISTRUCT_FIELD(My_Struct_Type, d_value, "d", SLANG_DOUBLE_TYPE, 0),
84 SLANG_END_ISTRUCT_TABLE
85 };
86
87
add_my_struct_type(void)88 static int add_my_struct_type (void)
89 {
90 return SLadd_istruct_table (My_Struct_Field_Table,
91 (VOID_STAR) &My_Struct_Ptr,
92 "MyS");
93 }
94
95 static int take_input (void);
96
main(int argc,char ** argv)97 int main (int argc, char **argv)
98 {
99 if ((-1 == SLang_init_all ())
100 /* || (-1 == SLang_init_import ()) / * dynamic linking */
101 || (-1 == add_my_struct_type ())
102 || (-1 == SLadd_intrin_fun_table (Calc_Intrinsics, NULL)))
103 {
104 fprintf(stderr, "Unable to initialize S-Lang.\n");
105 exit (1);
106 }
107
108 if (-1 == open_readline ())
109 return SLang_Error;
110
111 SLang_Traceback = 1;
112
113 if (argc == 1)
114 SLang_load_file("calc.sl");
115
116 while (--argc && !SLang_Error)
117 {
118 argv++;
119 SLang_load_file (*argv);
120 }
121
122 fputs("Type 'help();' for help and a list of available functions.\n", stdout);
123 fputs("All statements must end with a ';' character, e.g, 2*7+3;\n", stdout);
124 fputs("\nType `quit;' to exit this program.\n", stdout);
125
126 while (1)
127 {
128 if (SLang_Error)
129 {
130 SLang_doerror (NULL);
131 SLang_restart (1);
132 }
133
134 SLKeyBoard_Quit = SLang_Error = 0;
135 take_input ();
136 }
137 }
138
139 /* For a detailed explanation of all of this, see slang/demo/useropen.c */
140
141 static SLang_RLine_Info_Type Calc_RLI;
142 static unsigned char Calc_RLI_Buf[256];
143 SLang_Load_Type *Readline_Load_Object;
144
read_using_readline(SLang_Load_Type * x)145 static char *read_using_readline (SLang_Load_Type *x)
146 {
147 int n;
148 static char *input_hook = "calc_take_input_hook";
149
150 Calc_RLI_Buf[0] = 0;
151
152 if (x->parse_level == 0)
153 {
154 if ((input_hook != NULL)
155 && (-1 == SLang_run_hooks (input_hook, 0)))
156 {
157 input_hook = NULL;
158 return NULL;
159 }
160
161 Calc_RLI.prompt = "Calc> ";
162 }
163 else Calc_RLI.prompt = " ";
164
165 n = SLang_read_line (&Calc_RLI);
166 putc ('\n', stdout); fflush (stdout);
167
168 if (n < 0) return NULL;
169 if ((n == 0)
170 && (SLang_Last_Key_Char == SLang_RL_EOF_Char))
171 return "quit;";
172
173 SLang_rline_save_line (&Calc_RLI);
174 return (char *) Calc_RLI_Buf;
175 }
176
open_readline(void)177 static int open_readline (void)
178 {
179 if (SLang_init_tty (-1, 0, 1))
180 {
181 fprintf(stderr, "Unable to initialize tty.\n");
182 return -1;
183 }
184 SLang_set_abort_signal (NULL);
185
186 Calc_RLI.buf = Calc_RLI_Buf;
187 Calc_RLI.buf_len = 255;
188 Calc_RLI.tab = 8;
189 Calc_RLI.edit_width = 79;
190 Calc_RLI.dhscroll = 20;
191 Calc_RLI.prompt = "Calc> ";
192 Calc_RLI.getkey = SLang_getkey;
193 Calc_RLI.flags = SL_RLINE_BLINK_MATCH;
194 Calc_RLI.input_pending = SLang_input_pending;
195
196 #ifndef IBMPC_SYSTEM
197 Calc_RLI.flags |= SL_RLINE_USE_ANSI;
198 #endif
199
200 if (-1 == SLang_init_readline (&Calc_RLI))
201 {
202 close_readline ();
203 return -1;
204 }
205
206 if (NULL == (Readline_Load_Object = SLallocate_load_type ("<stdin>")))
207 {
208 close_readline ();
209 return -1;
210 }
211
212 Readline_Load_Object->read = read_using_readline;
213 return 0;
214 }
215
close_readline(void)216 static void close_readline (void)
217 {
218 if (Readline_Load_Object != NULL)
219 {
220 SLdeallocate_load_type (Readline_Load_Object);
221 Readline_Load_Object = NULL;
222 }
223
224 SLang_reset_tty ();
225 }
226
take_input(void)227 static int take_input (void)
228 {
229 return SLang_load_object (Readline_Load_Object);
230 }
231