blob: dc47d653f08fd5e5fe4c18b8b04da9165822bbf6 [file] [log] [blame]
MG Mud User88f12472016-06-24 23:31:02 +02001// PARSER.C -- parser for parenthesis expressions
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
11private inherit HOME("lex");
12
13#include "stack.h"
14#include "types.h"
15
16private nosave mixed code;
17private nosave mixed stack;
18private nosave int quot, assume;
19
20nomask static void initialize()
21{
22 INITSTACK(stack);
23 code = ({});
24 quot = 0;
25}
26
27static void create()
28{
29 lex::create();
30 initialize();
31}
32
33nomask private mixed CodeGen(mixed token)
34{
35 switch(pre_parse(&code))
36 {
37 case 1: PUSH(stack, "'"); // standard autoquote
38 quot++;
39 break;
40 case 2: PUSH(stack, "'CODE"); // special QUOTE for code generation
41 break;
42 }
43 if(stringp(token))
44 switch(token)
45 {
46 case "'": PUSH(stack, token); quot++; return;
47 case "(": PUSH(stack, code); code = ({}); break;
48 case ")":
49 {
50 mixed tmp;
51 if(SP(stack) && pointerp(TOP(stack))) POP(stack, tmp);
52 else tmp = ({});
53 if(SP(stack) && TOP(stack) == "'")
54 /* do nothing */ ;
55 else
56 if(sizeof(code))
57 {
58 code[0] = prog_parse(code[0]);
59 if(CL_LAMBDA(code[0]) || symbolp(code[0]) || pointerp(code[0]))
60 code = ({#'funcall}) + code;
61 }
62 code = tmp + ({ code });
63 break;
64 }
65 default : code += ({ token[1..<2] }); break;
66 }
67 else
68 code += ({ quot ? token : prog_parse(token, !sizeof(code)) });
69
70 while(SP(stack) && (TOP(stack) == "'" || TOP(stack) == "'CODE") &&
71 sizeof(code))
72 {
73 int q;
74 if(stringp(code[<1]) || symbolp(code[<1]) || pointerp(code[<1]) ||
75 get_type_info(code[<1])[0] == 10) // quoted array
76 code[<1] = quote(code[<1]);
77 POPX(stack);
78 }
79}
80
81// parse() -- non-threaded parsing (continue on input)
82nomask static int parse(mixed msg, int interactive)
83{
84 mixed token, res;
85 int lexing, missing_par;
86 do {
87 if(lexing = lex(&token))
88 { // try to assume outer "("
89 if(!SP(stack) && token != "(") { CodeGen("("); assume = 1; }
90 CodeGen(token);
91 }
92 else // add ")" if "(" is assumed
93 if(sizeof(stack) == 1 && assume) { CodeGen(")"); assume = 0; lexing = 1; }
94 if(lexing && !SP(stack)) // complete expression found
95 {
96 mixed exec_code; exec_code = code; initialize();
97 if(sizeof(exec_code) && pointerp(exec_code[0]))
98 exec_code = ({#',}) + exec_code;// more than one expr on one line
99 if(msg = catch(res = eval(exec_code)))
100 return -2; // execution error
101 if(interactive) printf(output(res));
102 else msg = res;
103 }
104 }
105 while(lexing);
106 if(missing_par = SP(stack))
107 return (msg = sprintf("*Missing %d )\n", missing_par), -3);
108 return 0;
109}