blob: 7fadd46d1c05007d83e74809297bf2d05fdf434a [file] [log] [blame]
MG Mud User88f12472016-06-24 23:31:02 +02001// MICROCODE.C -- lisp microcode
2// (c) 1994 by Hate@MorgenGrauen, TUBmud, NightFall
3// --
4// Copy, change and distribute this bit of software as much as you like,
5// but keep the name of the original author in the header.
6
7#pragma strong_types
8
9#include "tweak.h"
10#include "types.h"
11
12private nosave mapping memory; // contains function information
13private nosave string *G_input; // global input stack
14private nosave string *history; // input history
15
16nomask static public string output(mixed res);
17
18#define CODE 0
19#define QUOTE 1
20
21static void create()
22{
23 memory = m_allocate(0, 2);
24 G_input = ({});
25}
26
27nomask static closure get_function(string str)
28{
29 closure sym;
30 if((sym = symbol_function(str, this_object())) || // FUNCTIONS
31 (sym = symbol_function(str)) ||
32 (sym = symbol_variable(str)))
33 return sym;
34#if defined(symbol_variable)
35 if(str == "memory") return #'memory;
36#endif
37 return 0;
38}
39
40// pre_parse() -- parse code before examination by a code generator
41nomask static public int pre_parse(mixed code)
42{
43 if(pointerp(code) && sizeof(code) &&
44 (closurep(code[0]) || symbolp(code[0])))
45 {
46 mixed idx, tmp;
47 if(sizeof(tmp = old_explode(sprintf("%O", code[0]), "->")) > 1)
48 idx = tmp[1];
49 else idx = code[0];
50 // warning only the setting of bit 0 or 1 is allowed, not 0 and 1
51 // thus 01 leads to normal quote, 10 for special, 11 not quote at all
52 return (memory[idx, QUOTE] & (3<<2*(sizeof(code)-1)))>>2*(sizeof(code)-1);
53 }
54}
55
56// prog_parse() -- examine a token and take actions
57//
58nomask varargs static public mixed prog_parse(mixed token, int func)
59{
60 if(symbolp(token))
61 if(!member(memory, token))
62 token = ({#'?, ({#'member, ({#'memory}), quote(token)}),
63 ({#'[, ({#'memory}), quote(token)}),
64 ({#'raise_error,
65 sprintf("Symbol %O' not bound\n", token) }) });
66 else token = func ? token : memory[token];
67 return token;
68}
69
70// evaluate compiled code
71nomask static public mixed eval(mixed code)
72{
73 mapping sym;
74 sym = filter_indices(memory, #'symbolp);
75 return apply(lambda(m_indices(sym), code), m_values(sym));
76}
77
78// add new lines to input stack
79nomask static public void add_input(string input)
80{
81 if(!stringp(input)) return;
82 G_input += old_explode(input, "\n");
83}
84
85// clear the input stack
86nomask static public void clear_input()
87{
88 G_input = ({});
89}
90
91// get a line from input stack
92// and save it into the history
93nomask varargs string get_line()
94{
95 if(sizeof(G_input))
96 {
97 if(!pointerp(history)) history = ({});
98 history += ({ G_input[0] });
99 G_input[0..0] = ({});
100 return history[<1];
101 }
102 return 0;
103}
104
105// transform() -- transforms some of the output strings
106nomask private string transform(string e)
107{
108 switch(e)
109 {
110 case "({": return "(";
111 case "})": return ")";
112 case "([": return "[";
113 case "])": return "]";
114 }
115 if(strstr(e, " /* sizeof() == ") != -1) return "";
116 if(strstr(e, "\n") != -1) if(e[0] == ',') return " "; else return "";
117 return e;
118}
119
120// output() -- prints given data in a clean way
121nomask static public string output(mixed res)
122{
123 res = regexplode(sprintf("%O", res),
124 "\n[ ]*|[,]\n[ ]*|[(][{\[]|[\]}][)]|[#][']|"
125 +" [/][*] sizeof[(][)] == [0-9][0-9]* [*][/]")
126 - ({"\n", ",\n", "#'"});
127 res = map(res, #'transform);
128 return sprintf("%s\n", implode(res, ""));
129}