From 8b5d99802e2293c3e606551ab49e9d92192d6f37 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Tue, 14 Apr 1998 11:17:00 -0700
Subject: [PATCH] hilfe split up into a module and a stub program

Rev: bin/hilfe:1.15
Rev: lib/modules/Tools.pmod/Hilfe.pmod:1.1
---
 bin/hilfe                         | 558 +-------------------------
 lib/modules/Tools.pmod/Hilfe.pmod | 635 ++++++++++++++++++++++++++++++
 2 files changed, 636 insertions(+), 557 deletions(-)
 create mode 100644 lib/modules/Tools.pmod/Hilfe.pmod

diff --git a/bin/hilfe b/bin/hilfe
index 6e5cb7e541..bbd44cc59d 100755
--- a/bin/hilfe
+++ b/bin/hilfe
@@ -1,563 +1,7 @@
 #!/usr/local/bin/pike
 
-/* Incremental Pike evaluator */
-
-#include <simulate.h>
-#include <stdio.h>
-import Array;
-#include <string.h>
-#include <getopt.h>
-
-/* todo:
- *  return (void)1; will give me problems.
- *  strstr(string,string *) -> return first occurance of first string...
- *  inherit doesn't work
- *  preprocessor stuff
- */
-
-#!define catch(X) ((X),0)
-
-#pragma all_inline
-
-/* #define DEBUG */
-
-
-mapping variables=([]);
-mapping constants=([]);
-string *functions=({});
-string *function_names=({});
-mapping query_variables() { return variables; }
-/* do nothing */
-
-void my_write(mixed x)
-{
-  write(sprintf("%O",x));
-}
-
-
-object eval(string f)
-{
-  string prog,file;
-  object o;
-  mixed err;
-  prog=("#pragma unpragma_strict_types\n#pragma all_inline\n"+
-	"static mapping ___variables=___hilfe->query_variables();\n"+
-	map(indices(constants),lambda(string f)
-	    { return constants[f]&&sprintf("constant %s=%s;",f,constants[f]); })*"\n"+
-	map(indices(variables),lambda(string f)
-	    { return sprintf("mixed %s=___variables[\"%s\"];",f,f); })*"\n"+
-	"\nmapping query_variables() { return ([\n"+
-        map(indices(variables),lambda(string f)
-            { return sprintf("    \"%s\":%s,",f,f); })*"\n"+
-	    "\n  ]);\n}\n"+
-        functions*"\n"+
-	"\n# 1\n"+
-	 f+"\n");
-
-#ifdef DEBUG
-  write("program:"+prog);
-#endif
-  program p;
-  if(err=catch(p=compile_string(prog)))
-  {
-#ifdef DEBUG
-    write(describe_backtrace(err));
-    write("Couldn't compile expression.\n");
-#endif
-    return 0;
-  }
-  if(err=catch(o=clone(p)))
-  {
-    trace(0);
-    write(describe_backtrace(err));
-    return 0;
-  }
-  return o;
-}
-
-mixed do_evaluate(string a, int show_result)
-{
-  mixed foo, c;
-  if(foo=eval(a))
-  {
-    if(c=catch(a=sprintf("%O",foo->___Foo4711())))
-    {
-      trace(0);
-      if(arrayp(c) && sizeof(c)==2 && arrayp(c[1]))
-      {
-	c[1]=c[1][sizeof(backtrace())..];
-	write(describe_backtrace(c));
-      }else{
-	write(sprintf("Error in evalutation: %O\n",c));
-      }
-    }else{
-      if(show_result)
-	write("Result: "+a+"\n");
-      else
-	write("Ok.\n");
-      variables=foo->query_variables();
-    }
-  }
-}
-
-string input="";
-
-string skipwhite(string f)
-{
-  while(sscanf(f,"%*[ \r\n\t]%s",f) && sscanf(f,"/*%*s*/%s",f));
-  return f;
-}
-
-int find_next_comma(string s)
-{
-  int e, p, q;
-
-  for(e=0;e<strlen(s);e++)
-  {
-    switch(s[e])
-    {
-    case '"':
-      for(e++;s[e]!='"';e++)
-      {
-        switch(s[e])
-        {
-	case 0: return 0;
-	case '\\': e++; break;
-        }
-      }
-      break;
-
-    case '{':
-    case '(':
-    case '[':
-      p++;
-      break;
-
-    case ',':
-      if(!p) return e;
-      break;
-
-    case '/':
-      if(s[e+1]=='*')
-	while(s[e-1..e]!="*/" && e<strlen(s)) e++;
-      break;
-
-    case '}':
-    case ')':
-    case ']':
-      p--;
-      if(p<0)
-      {
-	write("Syntax errror.\n");
-	input="";
-	return 0;
-      }
-      break;
-
-    }
-  }
-  return 0;
-}
-
-string *get_name(string f)
-{
-  int e,d;
-  string rest;
-  
-  f=skipwhite(f);
-  if(sscanf(f,"*%s",f)) f=skipwhite(f);
-  sscanf(f,"%[a-zA-Z0-9_]%s",f,rest);
-  rest=skipwhite(rest);
-  return ({f,rest});
-}
-
-string first_word=0;
-int pos=0;
-int parenthese_level=0;
-int in_comment=0;
-int in_string=0;
-int in_quote=0;
-int eq_pos=-1;
-int do_parse();
-mixed parse_function(string s);
-mixed parse_statement(string s);
-
-void set_buffer(string s,int parsing)
-{
-  input=s;
-  first_word=0;
-  pos=-1;
-  parenthese_level=0;
-  in_comment=0;
-  in_quote=0;
-  in_string=0;
-  eq_pos=-1;
-  if(!parsing) do_parse();
-}
-
-void clean_buffer() { set_buffer("",0);  }
-
-void add_buffer(string s)
-{
-  input+=s;
-  do_parse();
-  input=skipwhite(input);
-}
-
-void cut_buffer(int where)
-{
-  int old,new;
-  old=strlen(input);
-  input=skipwhite(input[where..old-1]);
-  new=strlen(input);
-  if(where>1) first_word=0;
-  pos-=old-new; if(pos<0) pos=0;
-  eq_pos-=old-new; if(eq_pos<0) eq_pos=-1;
-#ifdef DEBUG
-  write("CUT input = "+my_write(input)+"  pos="+pos+"\n");
-#endif
-}
-
-void print_version()
-{
-  write(version()+
-	" running Hilfe v1.7 (Incremental Pike Frontend)\n");
-}
-
-
-int do_parse()
-{
-  string tmp;
-  if(pos<0) pos=0;
-  for(;pos<strlen(input);pos++)
-  {
-    if(in_quote) { in_quote=0; continue; }
-//    trace(99);
-    if(!first_word)
-    {
-      int d;
-      if(!strlen(input) && pos)
-      {
-	werror("Error in optimizer.\n");
-	exit(1);
-      }
-
-      d=input[pos];
-      if(d==' ' && !pos)
-      {
-	cut_buffer(1);
-	continue;
-      }
-      if((d<'a' || d>'z') && (d<'A' || d>'Z') && (d<'0' || d>'9') && d!='_')
-      {
-	first_word=input[0..pos-1];
-#ifdef DEBUG
-	write("First = "+my_write(first_word)+"  pos="+pos+"\n");
-	write("input = "+my_write(input)+"\n");
-#endif
-	switch(first_word)
-	{
-	case "quit":
-	  write("Exiting.\n");
-	  exit(0);
-	case ".":
-	  clean_buffer();
-	  write("Input buffer flushed.\n");
-	  continue;
-
-	case "new":
-	  this_object()->__INIT();
-	  continue;
-
-	case "dump":
-	  sum_arrays(lambda(string var,mixed foo)
-		   {
-		     write(sprintf("%-15s:%s\n",var,sprintf("%O",foo)));
-		   },
-		     indices(variables),
-		     values(variables));
-	  cut_buffer(4);
-	  continue;
-
-	case "help":
-	  print_version();
-	  write("Hilfe is a tool to evaluate Pike interactively and incrementally.\n"
-		"Any Pike function, expression or variable declaration can be entered\n"
-		"at the command line. There are also a few extra commands:\n"
-		" help       - show this text\n"
-		" quit       - exit this program\n"
-		" .          - abort current input batch\n"
-		" dump       - dump variables\n"
-		" new        - clear all function and variables\n"
-		"See the Pike reference manual for more information.\n"
-		);
-	  cut_buffer(4);
-	  continue;
-	  
-	}
-      }
-    }
-
-    switch(input[pos])
-    {
-    case '\\':
-      in_quote=1;
-      break;
-	
-    case '=':
-      if(in_string || in_comment  || parenthese_level || eq_pos!=-1) break;
-      eq_pos=pos;
-      break;
-      
-    case '"':
-      if(in_comment) break;
-      in_string=!in_string;
-      break;
-
-    case '{':
-    case '(':
-    case '[':
-      if(in_string || in_comment) break;
-      parenthese_level++;
-      break;
-
-    case '}':
-    case ')':
-    case ']':
-      if(in_string || in_comment) break;
-      if(--parenthese_level<0)
-      {
-	write("Syntax error.\n");
-	clean_buffer();
-	return 0;
-      }
-      if(!parenthese_level && input[pos]=='}')
-      {
-	if(tmp=parse_function(input[0..pos]))
-	{
-	  cut_buffer(pos+1);
-	  if(stringp(tmp))
-	    set_buffer(tmp+input,1);
-	}
-      }
-      break;
-
-    case ';':
-      if(in_string || in_comment || parenthese_level) break;
-      if(tmp=parse_statement(input[0..pos]))
-      {
-	cut_buffer(pos+1);
-	if(stringp(tmp))
-	  set_buffer(tmp+input,1);
-      }
-      break;
-      
-    case '*':
-      if(in_string || in_comment) break;
-      if(input[pos-1]=='/') in_comment=1;
-      break;
-
-    case '/':
-      if(in_string) break;
-      if(input[pos-1]=='*') in_comment=0;
-      break;
-    }
-  }
-  if(pos>strlen(input)) pos=strlen(input);
-  return -1;
-}
-
-
-mixed parse_function(string fun)
-{
-  string name,a,b;
-  object foo;
-  mixed c;
-#ifdef DEBUG
-  write("Parsing block ("+first_word+")\n");
-#endif
-
-  switch(first_word)
-  {
-  case "if":
-  case "for":
-  case "do":
-  case "while":
-  case "foreach":
-    /* parse loop */
-    do_evaluate("mixed ___Foo4711() { "+fun+" ; }\n",0);
-    return 1;
-
-  case "int":
-  case "void":
-  case "object":
-  case "array":
-  case "mapping":
-  case "string":
-  case "multiset":
-  case "float":
-  case "mixed":
-  case "program":
-  case "function":
-  case "class":
-    /* parse function */
-    if(eq_pos!=-1) break;  /* it's a variable */
-    sscanf(fun,first_word+"%s",name);
-
-    c=get_name(name);
-    name=c[0];
-    c=c[1];
-
-    int i;
-    if((i=member_array(name,function_names))!=-1)
-    {
-      b=functions[i];
-      functions[i]=fun;
-      if(!eval(""))  functions[i]=b;
-    }else{
-      if(eval(fun))
-      {
-	functions+=({fun});
-	function_names+=({name});
-      }
-    }
-    return 1;
-  }
-}
-
-mixed parse_statement(string ex)
-{
-  string a,b,name;
-  mixed c;
-  object foo;
-  int e;
-#ifdef DEBUG
-  write("Parsing statement ("+first_word+")\n");
-#endif
-  switch(first_word)
-  {
-    case "if":
-    case "for":
-    case "do":
-    case "while":
-    case "foreach":
-      /* parse loop */
-      do_evaluate("mixed ___Foo4711() { "+ex+" ; }\n",0);
-      return 1;
-      
-    case "constant":
-      /* parse variable def. */
-      sscanf(ex,first_word+"%s",b);
-      b=skipwhite(b);
-      c=get_name(b);
-      name=c[0];
-      sscanf(c[1],"=%s",c[1]);
-      a=constants[name];
-      constants[name]=c[1];
-      if(!eval("")) constants[name]=a;
-      return 1;
-      
-    case "int":
-    case "void":
-    case "object":
-    case "array":
-    case "mapping":
-    case "string":
-    case "multiset":
-    case "float":
-    case "mixed":
-    case "program":
-    case "function":
-      /* parse variable def. */
-      sscanf(ex,first_word+"%s",b);
-      b=skipwhite(b);
-      c=get_name(b);
-      name=c[0];
-      c=c[1];
-      
-#ifdef DEBUG
-      write("Variable def.\n");
-#endif
-      if(name=="") 
-      {
-	return 1;
-      }else{
-	string f;
-	variables[name]=0;
-	
-	if(sscanf(c,"=%s",c))
-	{
-#ifdef DEBUG
-	  write("Variable def. with assign. ("+name+")\n");
-#endif
-	  if(e=find_next_comma(c))
-	  {
-	    return name+"="+c[0..e-1]+";\n"+
-	      first_word+" "+c[e+1..strlen(c)-1];
-	  }else{
-	    return name+"="+c;
-	  }
-#ifdef DEBUG
-	  write("Input buffer = '"+input+"'\n");
-#endif
-	  
-	}else{
-	  sscanf(c,",%s",c);
-	  return first_word+" "+c;
-	}
-      }
-      
-      return 1;
-      
-    default:
-      if(ex==";") return 1;
-      /* parse expressions */
-    do_evaluate("mixed ___Foo4711() { return (mixed)("+ex[0..strlen(ex)-2]+"); }\n",1);
-    return 1;
-  }
-}
-
-void stdin(string s)
-{
-  string *tmp,a,b,c,f,name;
-  int e,d;
-  object foo;
-
-#ifdef DEBUG
-  write("input: '"+my_write(s)+"'\n");
-#endif
-  s=skipwhite(s);
-
-  if(s[0..1]==".\n")
-  {
-    clean_buffer();
-    write("Input buffer flushed.\n");
-    s=s[2..strlen(s)-1];
-  }
-  add_buffer(s);
-//  if(!strlen(input))  write("> ");
-}
-
-void signal_trap(int s)
-{
-  clean_buffer();
-  throw("**Break\n");
-}
-
 void main(int argc,string *argv)
 {
-  string s;
-  add_efun("write",my_write);
-  add_efun("___hilfe",this_object());
-
-  print_version();
-  while(s=readline(strlen(input) ? ">> " : "> "))
-  {
-    signal(signum("SIGINT"),signal_trap);
-    stdin(s+"\n");
-    signal(signum("SIGINT"));
-  }
-  write("Terminal closed.\n");
-  return 0;
+  Tools.Hilfe.StdinHilfe();
 }
 
diff --git a/lib/modules/Tools.pmod/Hilfe.pmod b/lib/modules/Tools.pmod/Hilfe.pmod
new file mode 100644
index 0000000000..1dcae84d95
--- /dev/null
+++ b/lib/modules/Tools.pmod/Hilfe.pmod
@@ -0,0 +1,635 @@
+class Evaluator
+{
+/* Incremental Pike evaluator */
+
+#include <simulate.h>
+#include <stdio.h>
+import Array;
+#include <string.h>
+#include <getopt.h>
+
+/* todo:
+ *  return (void)1; will give me problems.
+ *  strstr(string,string *) -> return first occurance of first string...
+ *  inherit doesn't work
+ *  preprocessor stuff
+ */
+
+#!define catch(X) ((X),0)
+
+#pragma all_inline
+
+/* #define DEBUG */
+
+  mapping variables=([]);
+  mapping constants=([]);
+  string *functions=({});
+  string *function_names=({});
+  mapping query_variables() { return variables; }
+/* do nothing */
+  
+  function write;
+  
+  object eval(string f)
+  {
+    string prog,file;
+    object o;
+    mixed err;
+    prog=("#pragma unpragma_strict_types\n#pragma all_inline\n"+
+	  "function write;\n"+
+	  map(indices(constants),lambda(string f)
+	      { return constants[f]&&sprintf("constant %s=%s;",f,constants[f]); })*"\n"+
+	      map(indices(variables),lambda(string f)
+		  { return sprintf("mixed %s;",f,f); })*"\n"+
+		  "\nmapping query_variables() { return ([\n"+
+		  map(indices(variables),lambda(string f)
+		      { return sprintf("    \"%s\":%s,",f,f); })*"\n"+
+		      "\n  ]);\n}\n"+
+		      functions*"\n"+
+		      "\n# 1\n"+
+		      f+"\n");
+    
+#ifdef DEBUG
+    write("program:"+prog);
+#endif
+    program p;
+    if(err=catch(p=compile_string(prog)))
+    {
+#ifdef DEBUG
+      write(describe_backtrace(err));
+      write("Couldn't compile expression.\n");
+#endif
+      return 0;
+    }
+    if(err=catch(o=clone(p)))
+    {
+      trace(0);
+      write(describe_backtrace(err));
+      return 0;
+    }
+    foreach(indices(variables), string f) o[f]=variables[f];
+    o->write=write;
+    return o;
+  }
+  
+  mixed do_evaluate(string a, int show_result)
+  {
+    mixed foo, c;
+    if(foo=eval(a))
+    {
+      if(c=catch(a=sprintf("%O",foo->___Foo4711())))
+      {
+	trace(0);
+	if(arrayp(c) && sizeof(c)==2 && arrayp(c[1]))
+	{
+	  c[1]=c[1][sizeof(backtrace())..];
+	  write(describe_backtrace(c));
+	}else{
+	  write(sprintf("Error in evalutation: %O\n",c));
+	}
+      }else{
+	if(show_result)
+	  write("Result: "+a+"\n");
+	else
+	  write("Ok.\n");
+	variables=foo->query_variables();
+      }
+    }
+  }
+
+  string input="";
+  
+  string skipwhite(string f)
+  {
+    while(sscanf(f,"%*[ \r\n\t]%s",f) && sscanf(f,"/*%*s*/%s",f));
+    return f;
+  }
+  
+  int find_next_comma(string s)
+  {
+    int e, p, q;
+    
+    for(e=0;e<strlen(s);e++)
+    {
+      switch(s[e])
+      {
+	case '"':
+	  for(e++;s[e]!='"';e++)
+	  {
+	    switch(s[e])
+	    {
+	      case 0: return 0;
+	      case '\\': e++; break;
+	    }
+	  }
+	  break;
+	  
+	case '{':
+	case '(':
+	case '[':
+	  p++;
+	  break;
+	  
+	case ',':
+	  if(!p) return e;
+	  break;
+	  
+	case '/':
+	  if(s[e+1]=='*')
+	    while(s[e-1..e]!="*/" && e<strlen(s)) e++;
+	  break;
+	  
+	case '}':
+	case ')':
+	case ']':
+	  p--;
+	  if(p<0)
+	  {
+	    write("Syntax errror.\n");
+	    input="";
+	    return 0;
+	  }
+	  break;
+	  
+      }
+    }
+    return 0;
+  }
+  
+  string *get_name(string f)
+  {
+    int e,d;
+    string rest;
+    
+    f=skipwhite(f);
+    if(sscanf(f,"*%s",f)) f=skipwhite(f);
+    sscanf(f,"%[a-zA-Z0-9_]%s",f,rest);
+    rest=skipwhite(rest);
+    return ({f,rest});
+  }
+
+  string first_word=0;
+  int pos=0;
+  int parenthese_level=0;
+  int in_comment=0;
+  int in_string=0;
+  int in_quote=0;
+  int eq_pos=-1;
+  int do_parse();
+  mixed parse_function(string s);
+  mixed parse_statement(string s);
+  
+  void set_buffer(string s,int parsing)
+  {
+    input=s;
+    first_word=0;
+    pos=-1;
+    parenthese_level=0;
+    in_comment=0;
+    in_quote=0;
+    in_string=0;
+    eq_pos=-1;
+    if(!parsing) do_parse();
+  }
+  
+  void clean_buffer() { set_buffer("",0);  }
+
+  void add_buffer(string s)
+  {
+    input+=s;
+    do_parse();
+    input=skipwhite(input);
+  }
+
+  void cut_buffer(int where)
+  {
+    int old,new;
+    old=strlen(input);
+    input=skipwhite(input[where..old-1]);
+    new=strlen(input);
+    if(where>1) first_word=0;
+    pos-=old-new; if(pos<0) pos=0;
+    eq_pos-=old-new; if(eq_pos<0) eq_pos=-1;
+  }
+  
+  void print_version()
+  {
+    write(version()+
+	  " running Hilfe v2.0 (Incremental Pike Frontend)\n");
+  }
+  
+  
+  int do_parse()
+  {
+    string tmp;
+    if(pos<0) pos=0;
+    for(;pos<strlen(input);pos++)
+    {
+      if(in_quote) { in_quote=0; continue; }
+//    trace(99);
+      if(!first_word)
+      {
+	int d;
+	if(!strlen(input) && pos)
+	{
+	  werror("Error in optimizer.\n");
+	  exit(1);
+	}
+	
+	d=input[pos];
+	if(d==' ' && !pos)
+	{
+	  cut_buffer(1);
+	  continue;
+	}
+	if((d<'a' || d>'z') && (d<'A' || d>'Z') && (d<'0' || d>'9') && d!='_')
+	{
+	  first_word=input[0..pos-1];
+#ifdef DEBUG
+	  write("First = "+first_word+"  pos="+pos+"\n");
+	  write("input = "+input+"\n");
+#endif
+	  switch(first_word)
+	  {
+	    case "quit":
+	      write("Exiting.\n");
+	      exit(0);
+	    case ".":
+	      clean_buffer();
+	      write("Input buffer flushed.\n");
+	      continue;
+	      
+	    case "new":
+	      this_object()->__INIT();
+	      continue;
+	      
+	    case "dump":
+	      sum_arrays(lambda(string var,mixed foo)
+			 {
+			   write(sprintf("%-15s:%s\n",var,sprintf("%O",foo)));
+			 },
+			   indices(variables),
+			   values(variables));
+	      cut_buffer(4);
+	      continue;
+	      
+	    case "help":
+	      print_version();
+	      write("Hilfe is a tool to evaluate Pike interactively and incrementally.\n"
+		    "Any Pike function, expression or variable declaration can be entered\n"
+		    "at the command line. There are also a few extra commands:\n"
+		    " help       - show this text\n"
+		    " quit       - exit this program\n"
+		    " .          - abort current input batch\n"
+		    " dump       - dump variables\n"
+		    " new        - clear all function and variables\n"
+		    "See the Pike reference manual for more information.\n"
+		);
+	      cut_buffer(4);
+	      continue;
+	      
+	  }
+	}
+      }
+      
+      switch(input[pos])
+      {
+	case '\\':
+	  in_quote=1;
+	  break;
+	  
+	case '=':
+	  if(in_string || in_comment  || parenthese_level || eq_pos!=-1) break;
+	  eq_pos=pos;
+	  break;
+	  
+	case '"':
+	  if(in_comment) break;
+	  in_string=!in_string;
+	  break;
+	  
+	case '{':
+	case '(':
+	case '[':
+	  if(in_string || in_comment) break;
+	  parenthese_level++;
+	  break;
+	  
+	case '}':
+	case ')':
+	case ']':
+	  if(in_string || in_comment) break;
+	  if(--parenthese_level<0)
+	  {
+	    write("Syntax error.\n");
+	    clean_buffer();
+	    return 0;
+	  }
+	  if(!parenthese_level && input[pos]=='}')
+	  {
+	    if(tmp=parse_function(input[0..pos]))
+	    {
+	      cut_buffer(pos+1);
+	      if(stringp(tmp))
+		set_buffer(tmp+input,1);
+	    }
+	  }
+	  break;
+	  
+	case ';':
+	  if(in_string || in_comment || parenthese_level) break;
+	  if(tmp=parse_statement(input[0..pos]))
+	  {
+	    cut_buffer(pos+1);
+	    if(stringp(tmp))
+	      set_buffer(tmp+input,1);
+	  }
+	  break;
+	  
+	case '*':
+	  if(in_string || in_comment) break;
+	  if(input[pos-1]=='/') in_comment=1;
+	  break;
+	  
+	case '/':
+	  if(in_string) break;
+	  if(input[pos-1]=='*') in_comment=0;
+	  break;
+      }
+    }
+    if(pos>strlen(input)) pos=strlen(input);
+    return -1;
+  }
+
+
+  mixed parse_function(string fun)
+  {
+    string name,a,b;
+    object foo;
+    mixed c;
+#ifdef DEBUG
+    write("Parsing block ("+first_word+")\n");
+#endif
+    
+    switch(first_word)
+    {
+      case "if":
+      case "for":
+      case "do":
+      case "while":
+      case "foreach":
+	/* parse loop */
+	do_evaluate("mixed ___Foo4711() { "+fun+" ; }\n",0);
+	return 1;
+	
+      case "int":
+      case "void":
+      case "object":
+      case "array":
+      case "mapping":
+      case "string":
+      case "multiset":
+      case "float":
+      case "mixed":
+      case "program":
+      case "function":
+      case "class":
+	/* parse function */
+	if(eq_pos!=-1) break;  /* it's a variable */
+	sscanf(fun,first_word+"%s",name);
+	
+	c=get_name(name);
+	name=c[0];
+	c=c[1];
+	
+	int i;
+	if((i=member_array(name,function_names))!=-1)
+	{
+	  b=functions[i];
+	  functions[i]=fun;
+	  if(!eval(""))  functions[i]=b;
+	}else{
+	  if(eval(fun))
+	  {
+	    functions+=({fun});
+	    function_names+=({name});
+	  }
+	}
+	return 1;
+    }
+  }
+
+  mixed parse_statement(string ex)
+  {
+    string a,b,name;
+    mixed c;
+    object foo;
+    int e;
+#ifdef DEBUG
+    write("Parsing statement ("+first_word+")\n");
+#endif
+    switch(first_word)
+    {
+      case "if":
+      case "for":
+      case "do":
+      case "while":
+      case "foreach":
+	/* parse loop */
+	do_evaluate("mixed ___Foo4711() { "+ex+" ; }\n",0);
+	return 1;
+	
+      case "constant":
+	/* parse variable def. */
+	sscanf(ex,first_word+"%s",b);
+	b=skipwhite(b);
+	c=get_name(b);
+	name=c[0];
+	sscanf(c[1],"=%s",c[1]);
+	a=constants[name];
+	constants[name]=c[1];
+	if(!eval("")) constants[name]=a;
+	return 1;
+	
+      case "int":
+      case "void":
+      case "object":
+      case "array":
+      case "mapping":
+      case "string":
+      case "multiset":
+      case "float":
+      case "mixed":
+      case "program":
+      case "function":
+	/* parse variable def. */
+	sscanf(ex,first_word+"%s",b);
+	b=skipwhite(b);
+	c=get_name(b);
+	name=c[0];
+	c=c[1];
+	
+#ifdef DEBUG
+	write("Variable def.\n");
+#endif
+	if(name=="") 
+	{
+	  return 1;
+	}else{
+	  string f;
+	  variables[name]=0;
+	  
+	  if(sscanf(c,"=%s",c))
+	  {
+#ifdef DEBUG
+	    write("Variable def. with assign. ("+name+")\n");
+#endif
+	    if(e=find_next_comma(c))
+	    {
+	      return name+"="+c[0..e-1]+";\n"+
+		first_word+" "+c[e+1..strlen(c)-1];
+	    }else{
+	      return name+"="+c;
+	    }
+#ifdef DEBUG
+	    write("Input buffer = '"+input+"'\n");
+#endif
+	    
+	  }else{
+	    sscanf(c,",%s",c);
+	    return first_word+" "+c;
+	  }
+	}
+	
+	return 1;
+	
+      default:
+	if(ex==";") return 1;
+	/* parse expressions */
+	do_evaluate("mixed ___Foo4711() { return (mixed)("+ex[0..strlen(ex)-2]+"); }\n",1);
+	return 1;
+    }
+  }
+  
+  void add_input_line(string s)
+  {
+    string *tmp,a,b,c,f,name;
+    int e,d;
+    object foo;
+    
+    s=skipwhite(s);
+    
+    if(s[0..1]==".\n")
+    {
+      clean_buffer();
+      write("Input buffer flushed.\n");
+      s=s[2..strlen(s)-1];
+    }
+    add_buffer(s);
+//  if(!strlen(input))  write("> ");
+  }
+
+  void create()
+  {
+    print_version();
+  }
+}
+
+class StdinHilfe
+{
+  inherit Evaluator;
+
+  void signal_trap(int s)
+    {
+      clean_buffer();
+      throw("**Break\n");
+    }
+  
+  void create()
+    {
+      write=predef::write;
+      ::create();
+
+      while(string s=readline(strlen(input) ? ">> " : "> "))
+      {
+	signal(signum("SIGINT"),signal_trap);
+	add_input_line(s+"\n");
+	signal(signum("SIGINT"));
+      }
+      write("Terminal closed.\n");
+    }
+}
+
+class GenericHilfe
+{
+  inherit Evaluator;
+  
+  void create(object(Stdio.FILE) in, object(Stdio.File) out)
+  {
+    write=out->write;
+    ::create();
+
+    while(1)
+    {
+      write(strlen(input) ? ">> " : "> ");
+      if(string s=in->gets())
+      {
+	add_input_line(s+"\n");
+      }else{
+	write("Terminal closed.\n");
+	return;
+      }
+    }
+  }
+}
+
+
+class GenericAsyncHilfe
+{
+  inherit Evaluator;
+  object(Stdio.File) infile, outfile;
+
+  string outbuffer="";
+  void write_callback()
+  {
+    int i=outfile->write(outbuffer);
+    outbuffer=outbuffer[i..];
+  }
+  void send_output(string s, mixed ... args)
+  {
+    outbuffer+=sprintf(s,@args);
+    write_callback();
+  }
+
+  string inbuffer="";
+  void read_callback(mixed id, string s)
+  {
+    inbuffer+=s;
+    foreach(inbuffer/"\n",string s)
+      {
+	add_input_line(s);
+	write(strlen(input) ? ">> " : "> ");
+      }
+  }
+
+  void close_callback()
+  {
+    write("Terminal closed.\n");
+    destruct(this_object());
+    destruct(infile);
+    if(outfile) destruct(outfile);
+  }
+  
+  void create(object(Stdio.File) in, object(Stdio.File) out)
+  {
+    infile=in;
+    outfile=out;
+    in->set_nonblocking(read_callback, 0, close_callback);
+    out->set_write_callback(write_callback);
+
+    write=send_output;
+    ::create();
+    write(strlen(input) ? ">> " : "> ");
+  }
+}
+
-- 
GitLab