interpretor.cc

00001 /* interpretor -- Simple Command Interpretor
00002    Copyright 2002, 2003 Free Software Foundation, Inc.
00003    Written by Stephane Carrez (stcarrez@nerim.fr)
00004 
00005 This file is part of GEL.
00006 
00007 GEL is free software; you can redistribute it and/or modify
00008 it under the terms of the GNU General Public License as published by
00009 the Free Software Foundation; either version 2, or (at your option)
00010 any later version.
00011 
00012 GEL is distributed in the hope that it will be useful,
00013 but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 GNU General Public License for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with GEL; see the file COPYING.  If not, write to
00019 the Free Software Foundation, 59 Temple Place - Suite 330,
00020 Boston, MA 02111-1307, USA.  */
00021 
00035 #include "interpretor.h"
00036 #include <sys/sio.h>
00037 #include <stdio.h>
00038 #include <stdlib.h>
00039 #include <assert.h>
00040 #include "expr.h"
00041 
00042 // Simple Memory Allocator
00043 class Allocator {
00044 
00045   // A memory slot can contain any object created by this example.
00046   union MemSlot {
00047     char buffer;
00048     char _b_Expression[sizeof (Expression)];
00049     char _b_BinaryExpression[sizeof (BinaryExpression)];
00050     char _b_UnaryExpression[sizeof (UnaryExpression)];
00051     char _b_ValueExpression[sizeof (ValueExpression)];
00052   };
00053 
00054   // Allow up to 100 instances
00055   MemSlot exprMemoryPool[100];
00056   unsigned last;
00057 public:
00058   Allocator()
00059     {
00060       last = 0;
00061     }
00062 
00063   void reset()
00064     {
00065       last = 0;
00066     }
00067 
00068   void* allocate(size_t size)
00069     {
00070       assert(size <= sizeof (MemSlot));
00071       assert(last < 100);
00072 
00073       char* slot = &exprMemoryPool[last].buffer;
00074       last++;
00075       return slot;
00076     }
00077 };
00078 
00079 Allocator allocator;
00080 
00081 void* near
00082 operator new (size_t len)
00083 {
00084   return allocator.allocate(len);
00085 }
00086 
00087 void near
00088 operator delete (void *ptr)
00089 {
00090 }
00091 
00092 void print (const char* p)
00093 {
00094    serial_print (p);
00095 }
00096 
00097 /* Implementation of some libc methods. */
00098 int
00099 strcmp (const char* s1, const char* s2)
00100 {
00101   while (*s1 && (*s1 == *s2))
00102     s1++, s2++;
00103 
00104   return *s1 - *s2;
00105 }
00106 
00107 int interpretor::execute(const char* line)
00108 {
00109   if (line == 0)
00110     return 0;
00111 
00112   Expression* e = Expression::parse(line);
00113   if (e)
00114     {
00115       Value v = e->evaluate();
00116       printf(" Result = %ld\n", (long) v);
00117       delete e;
00118     }
00119   else
00120     {
00121       printf("Invalid expression\n");
00122     }
00123   return 0;
00124 }
00125 
00126 /* Busy loop to wait for a command or a valid number. */
00127 void
00128 interpretor::get_command (char *buf)
00129 {
00130   int pos;
00131   char c;
00132 
00133   while (1)
00134     {
00135       pos = 0;
00136       while (1)
00137         {
00138           c = serial_recv ();
00139           if (c == '\r' || c == '\n')
00140             break;
00141 
00142           if (c == '\b')
00143             {
00144               printf ("\b \b");
00145               pos--;
00146               if (pos < 0)
00147                 pos = 0;
00148             }
00149           else
00150             {
00151               buf[pos] = c;
00152               buf[pos+1] = 0;
00153               printf (&buf[pos]);
00154               pos++;
00155             }
00156         }
00157 
00158       printf ("\n");
00159       buf[pos] = 0;
00160       break;
00161     }
00162 }
00163 
00164 void
00165 interpretor::main_loop()
00166 {
00167   static char buf[100];
00168 
00169   while (1)
00170     {
00171       // Reset the allocator before each computation.
00172       allocator.reset();
00173 
00174       // Get expression to evaluate.
00175       printf ("> ");
00176       get_command (buf);
00177       if (strcmp (buf, "quit") == 0)
00178         break;
00179 
00180       execute (buf);
00181     }
00182 }
00183 
00184 int
00185 main()
00186 {
00187   interpretor interp;
00188 
00189   serial_init ();
00190 
00191   printf ("Simple Interpretor Program\n");
00192   interp.main_loop ();
00193   return 0;
00194 }