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 }