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