├── BASICInterpreter.cpp └── README.md /BASICInterpreter.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | using namespace std; 14 | 15 | //Exception declarations 16 | class EndQuotesException{}; 17 | class InitialQuotesException{}; 18 | class NumberInputException{}; 19 | class ENDIFException{}; 20 | class GOTOEXException{}; 21 | class WrongstatementException{}; 22 | class Nonexistentvariable{}; 23 | 24 | //Abstract base class// 25 | class base{ 26 | 27 | public: 28 | //virtual function is overidden by each of the derived classes 29 | virtual void execute(std::vector >arr,map &variables,int &line,int lines)=0; 30 | }; 31 | 32 | //Derived IF statement Class// 33 | class IF:public base 34 | { 35 | private: 36 | string input; //Input string to IF 37 | string A,B; //string to store separated arguments 38 | int A1,A2; //Arguments converted into integer for comparison 39 | int operator1; //operator 40 | 41 | public: 42 | //execute Function shared with all the derived classes and base class// 43 | void execute(std::vector >arr,map &variables,int &line,int lines); 44 | 45 | void checkOperator(); 46 | int checkCondition(int A,int B,int Operator); 47 | inline bool isInteger(const std::string & s); 48 | int checkVariable(map variables); 49 | int findEndIF(std::vector >arr,int line,int lines); 50 | ~IF(); 51 | }; 52 | 53 | //Checks the conditions once the operator and the Arguments are assigned as integers 54 | int IF::checkCondition(int A,int B,int Operator){ 55 | if (Operator==1){if(A>B){return 1;} else{return 0;}} 56 | if(Operator==2){if(A','<','='}; 66 | char *pch; 67 | string words[2]; 68 | int found; 69 | for(i=0;i<3;i++){ 70 | found=input.find(operators1[i]); 71 | if(input[found]>0){ 72 | operator1=i+1; 73 | }} 74 | i=0; 75 | pch=strtok(str,">=<"); 76 | while(pch !=NULL){ 77 | words[i]=pch; 78 | pch=strtok(NULL,">=<"); 79 | i++; 80 | } 81 | A=words[0]; 82 | B=words[1]; 83 | 84 | } 85 | //checks whether an argument is an integer or not 86 | inline bool IF:: isInteger(const std::string & s) 87 | { 88 | if(s.empty() || ((!isdigit(s[0])) && (s[0] != '-') && (s[0] != '+'))) return false ; 89 | char * p ; 90 | strtol(s.c_str(), &p, 10) ; 91 | return (*p == 0) ; 92 | } 93 | 94 | //check variables uses isInteger to check whether the argument is a variable or number and assigns A and B accordignly 95 | int IF::checkVariable(map variables){ 96 | 97 | if(isInteger(A)==false){ 98 | 99 | A1=variables[A]; 100 | } 101 | else{ 102 | std::istringstream ss(A); 103 | ss >> A1; 104 | } 105 | if(isInteger(B)==false){ 106 | A2=variables[B]; 107 | } 108 | else{ 109 | std::istringstream ss(B); 110 | ss >> A2; 111 | } 112 | } 113 | //Counts EndiF from the IF line and checks whether there are enough and ENDIF and returns the positions of ENDIF 114 | int IF::findEndIF(std::vector >arr,int line,int lines){ 115 | 116 | int countifs=1; 117 | int i; 118 | for(i=line+1;i >arr,map &variables,int &line,int lines){ 140 | 141 | input=arr[line][2]; 142 | checkOperator(); 143 | checkVariable(variables); 144 | if(checkCondition(A1,A2,operator1)==1&&findEndIF(arr,line,lines)>0){ 145 | 146 | line++; //uses the reference from execute to increment line number in program class to proceed to the next line 147 | } 148 | if(checkCondition(A1,A2,operator1)==0&&findEndIF(arr,line,lines)>0){ 149 | 150 | line=findEndIF(arr,line,lines); //if If statement not satisfied, line number set to the corresponding ENDIF 151 | } 152 | } 153 | 154 | 155 | 156 | 157 | 158 | //LET FUNCTION 159 | class let:public base{ 160 | private: 161 | string input; 162 | int operator1; 163 | string A; //Arguments extracted as strings/ 164 | string B; 165 | int A1; //Arguments assigned as integers// 166 | int A2; 167 | string Result; //Variable being assigned the value used as the key for MAP// 168 | int inresult; //assigned value for key in map// 169 | 170 | 171 | public: 172 | void checkOperator(); 173 | inline bool isInteger(const std::string & s); 174 | int checkVariable(map &variables,int Operator,int &line ,int lines); 175 | int compute(int A,int B,int Operator); 176 | void execute(std::vector >arr,map &variables,int &line,int lines); 177 | ~let(); 178 | 179 | }; 180 | //Same process as the one in IF, checks Operator such as *,+..// 181 | void let::checkOperator(){ 182 | char str[input.length()]; 183 | strcpy(str,input.c_str()); 184 | int i; 185 | char operators1[4]={'+','*','-','/'}; 186 | char *pch; 187 | int equal; 188 | string words[3]; 189 | int found; 190 | found=0; 191 | for(i=0;i<4;i++){ 192 | found=input.find(operators1[i]); 193 | if(input[found]>0){ 194 | operator1=i+1; 195 | }} 196 | i=0; 197 | 198 | equal=input.find('=');// 199 | 200 | pch=strtok(str,"+*-/="); 201 | while(pch !=NULL){ 202 | words[i]=pch; 203 | pch=strtok(NULL,"+*-/="); 204 | i++; 205 | } 206 | if (found==0){ 207 | Result=words[0]; 208 | operator1=5; 209 | A=words[1]; 210 | } 211 | else{ 212 | Result=words[0]; 213 | A=words[1]; //assigns arguments to strings A and B 214 | B=words[2]; 215 | } 216 | 217 | 218 | } 219 | //checks whether an argument is an integer or not 220 | inline bool let:: isInteger(const std::string & s) 221 | { 222 | if(s.empty() || ((!isdigit(s[0])) && (s[0] != '-') && (s[0] != '+'))) return false ; 223 | char * p ; 224 | strtol(s.c_str(), &p, 10) ; 225 | return (*p == 0) ; 226 | } 227 | //check variables uses isInteger to check whether the argument is a variable or number and assigns A and B accordignly 228 | int let::checkVariable(map &variables,int Operator,int &line,int lines){ 229 | 230 | if(isInteger(A)==false) 231 | { 232 | line=lines+1; throw Nonexistentvariable(); 233 | } 234 | 235 | else{ 236 | std::istringstream ss(A); 237 | ss >> A1; 238 | } 239 | 240 | if(Operator!=5){ 241 | if(isInteger(B)==false) 242 | { 243 | A2=variables[B]; 244 | } 245 | else{ 246 | std::istringstream ss(B); 247 | ss >> A2; 248 | } 249 | } 250 | } 251 | //uses the operator assigned to compute the let 252 | int let::compute(int A,int B,int Operator){ 253 | if (Operator==1){return A+B;} 254 | if(Operator==2){return A*B;} 255 | if(Operator==3){return A-B;} 256 | if(Operator==4){return A/B;} 257 | if(Operator==0){return A;} 258 | 259 | return -1; 260 | //else{return A;} 261 | } 262 | //execute function 263 | void let::execute(std::vector >arr,map &variables,int &line,int lines){ 264 | 265 | input=arr[line][2]; //assigns string Input 266 | checkOperator(); 267 | checkVariable(variables,operator1,line,lines); 268 | inresult=compute(A1,A2,operator1); //stores the computed result into inresult 269 | variables[Result]=inresult; //inresult is assigned to map with key// 270 | if(inresult!=-1){ 271 | line++; 272 | } 273 | else{line=lines+1;} //increments line to the end of the program// 274 | } 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | //INPUT FUNCTION 283 | class INPUT:public base 284 | { 285 | public: 286 | void execute(std::vector >arr,map &variables,int &line,int lines){ 287 | 288 | //extract value from string and assign to map 289 | string key = arr[line][2]; 290 | //checks if inputed value is integer// 291 | if (isInteger(key)==false){ 292 | double val; 293 | cin >> val; 294 | variables[key] = val; 295 | line++; 296 | } 297 | else{ 298 | line=lines+1; 299 | throw NumberInputException(); //throws exeception 300 | } 301 | 302 | } 303 | inline bool isInteger(const std::string & s); 304 | 305 | ~INPUT(); 306 | }; 307 | //checks whether an argument is an integer or not 308 | inline bool INPUT:: isInteger(const std::string & s) 309 | { 310 | if(s.empty() || ((!isdigit(s[0])) && (s[0] != '-') && (s[0] != '+'))) return false ; 311 | char * p ; 312 | strtol(s.c_str(), &p, 10) ; 313 | return (*p == 0) ; 314 | } 315 | 316 | 317 | 318 | 319 | 320 | 321 | //GOTO CLASS 322 | class GOTO:public base{ 323 | public: 324 | inline bool isInteger(const std::string & s); 325 | void execute(std::vector >arr,map &variables,int &line,int lines); 326 | ~GOTO(); 327 | }; 328 | //checks whether an argument is an integer or not 329 | inline bool GOTO::isInteger(const std::string & s) 330 | { 331 | if(s.empty() || ((!isdigit(s[0])) && (s[0] != '-') && (s[0] != '+'))) return false ; 332 | 333 | char * p ; 334 | strtol(s.c_str(), &p, 10) ; 335 | 336 | return (*p == 0) ; 337 | } 338 | //execute checks if line number is a number and finds the corresponding line with the same characters in the stored vector 339 | void GOTO::execute(std::vector >arr,map &variables,int &line,int lines) 340 | { 341 | string element = arr[line][2]; 342 | int temp; 343 | temp=line; 344 | int i; 345 | if (isInteger(element)==1) 346 | { 347 | for(i=0;i >arr,map &variables,int &line,int lines){ 377 | int length = arr[line].size()-1; 378 | if(variables.find(arr[line][2])==variables.end()){ 379 | 380 | //Check that there are quotation marks in the beginning of the statement 381 | if(arr[line][2].at(0)== '\"'){ 382 | 383 | //Check that there are quotation marks at the end of the statement 384 | if (arr[line][length][arr[line][length].size() - 1]== '\"'){ 385 | 386 | //remove quotes from first element of string to print 387 | arr[line][2].erase( 388 | remove( arr[line][2].begin(), arr[line][2].end(), '\"' ), 389 | arr[line][2].end() 390 | ); 391 | 392 | //remove quotes from last element of string to print 393 | arr[line][length].erase( 394 | remove(arr[line][length].begin(), arr[line][length].end(), '\"' ), 395 | arr[line][length].end() 396 | ); 397 | 398 | //Check for newline character and print correct strings 399 | while (i != length+1){ 400 | string str2 = arr[line][i]; 401 | int pos = 0; 402 | bool state = true; 403 | while (pos != str2.length()) 404 | { 405 | if(str2.at(pos) == '\\' && str2.at(pos+1) == 'n') 406 | { 407 | cout << endl; 408 | state =false; 409 | pos++; 410 | } 411 | else 412 | { 413 | cout << str2.at(pos); 414 | } 415 | pos++; 416 | } 417 | if (state == true) 418 | { 419 | cout << " "; 420 | } 421 | i++; 422 | } 423 | } 424 | 425 | else 426 | { 427 | line=lines+1; 428 | throw EndQuotesException(); 429 | } 430 | } 431 | else{ 432 | 433 | line=lines+1; 434 | throw InitialQuotesException(); 435 | } 436 | } 437 | else{ 438 | cout < >arr; 460 | map mymap; 461 | std::map lines; 462 | int line=0; 463 | int length=0; 464 | public: 465 | 466 | void File(const char* const FileName); 467 | string *separate(string line,int *count2); 468 | void create(); 469 | int errorcheck(int i); 470 | void execute(); 471 | 472 | }; 473 | //Create function checks the second element within the vector and assigns a pointer to a new (derived Class) for functions. 474 | // The the pointer is then stored within the map(for base class pointers) and line executed with the execute function // 475 | //Create passes on the required references and variables to the base class pointer execute// 476 | //The execute function within the derived class overrides this and carries out its process.// 477 | void program::create(){ 478 | 479 | if(arr[line][1]=="LET") 480 | { 481 | let* ptr=new let(); 482 | lines[line]=ptr; 483 | lines[line]->execute(arr,mymap,line,length); 484 | } 485 | 486 | if(arr[line][1]=="IF") 487 | { 488 | IF* ptr=new IF(); 489 | lines[line]=ptr; 490 | lines[line]->execute(arr,mymap,line,length); 491 | } 492 | if(arr[line][1]=="ENDIF") 493 | { 494 | line++; 495 | } 496 | 497 | if(arr[line][1]=="INPUT") 498 | { 499 | INPUT* ptr=new INPUT(); 500 | lines[line]=ptr; 501 | lines[line]->execute(arr,mymap,line,length); 502 | } 503 | if(arr[line][1]=="GOTO") 504 | { 505 | GOTO* ptr=new GOTO(); 506 | lines[line]=ptr; 507 | lines[line]->execute(arr,mymap,line,length); 508 | 509 | } 510 | 511 | if(arr[line][1]=="PRINT") 512 | { 513 | Print* ptr=new Print(); 514 | lines[line]=ptr; 515 | lines[line]->execute(arr,mymap,line,length); 516 | } 517 | } 518 | //separates the each line by spaces and returns the words within a line as an array. 519 | string *program::separate(string line,int *count2) 520 | { 521 | 522 | string buff; 523 | string *words; 524 | int count1=0; 525 | int i; 526 | stringstream ss(line); 527 | vectortokens; 528 | while(ss>>buff){ 529 | tokens.push_back((buff)); 530 | count1++; 531 | } 532 | words=new string[count1]; 533 | 534 | for(i=0;i sub; 548 | std::ifstream infile(FileName); 549 | string *words; 550 | string line1; 551 | int words2; 552 | length=0; 553 | 554 | while (std::getline(infile, line1)) 555 | { 556 | length++; 557 | string *words=separate(line1 ,&words2); 558 | for(int j=0;j