Browse Source

First version of Basic Compiler

AbderFaiz 5 months ago
parent
commit
4284817373
4 changed files with 32 additions and 6 deletions
  1. 4 4
      Makefile
  2. 17 0
      TODO.md
  3. 1 0
      examples/factorial
  4. 10 2
      src/Parser.cpp

+ 4 - 4
Makefile

@@ -22,11 +22,11 @@ Parser.o : src/Parser.cpp src/Parser.hpp Lexer.o Token.o Symbol.o Emitter.o
 test.out: src/main.cpp Token.o Lexer.o Parser.o Symbol.o Emitter.o
 	$(CC) $(FLAGS) $^ -o $@
 	./$@ $(EXAMPLE)
-	cat out.c
+	$(CC) out.c
 
-test: test.out
-	./$^ $(EXAMPLE)
-	cat out.c
+exec: test.out
+	./a.out
+	
 
 clean:
 	rm -f test.out *.o

+ 17 - 0
TODO.md

@@ -0,0 +1,17 @@
+- [ ]   Parentheses for expressions
+- [ ]   Logical operators (and, or, not)
+- [ ]   ELSE IF and ELSE
+- [ ]   FOR loop
+- [ ]   Number literals written in binary, hex, and octal
+- [ ]   Better compiler errors (e.g., what line the error occurred)
+- [ ]   Allow multiple code files
+- [ ]   Functions with parameters and return values
+- [ ]   Lexical scope (see [scope](https://en.wikipedia.org/wiki/Scope_(computer_science)))
+- [ ]   Standard library (e.g., file operations)
+- [ ]   [Abstract syntax tree](https://en.wikipedia.org/wiki/Abstract_syntax_tree) representation
+- [ ]   More primitive types (e.g., integer, strings, boolean)
+- [ ]   Arrays
+- [ ]   Record types (i.e., structs or tuples)
+- [ ]   Type checking (see [type systems](https://en.wikipedia.org/wiki/Type_system))
+- [ ]   Compiler optimizations (e.g., [constant folding](https://en.wikipedia.org/wiki/Constant_folding))
+- [ ]   Test cases for the compiler (see [unit testing](https://en.wikipedia.org/wiki/Unit_testing) and [test-driven development](https://en.wikipedia.org/wiki/Test-driven_development))

+ 1 - 0
examples/factorial

@@ -11,4 +11,5 @@ WHILE n > 1 REPEAT
 ENDWHILE
 PRINT "The factorial is:"
 PRINT result
+PRINT ""
 GOTO START

+ 10 - 2
src/Parser.cpp

@@ -92,7 +92,7 @@ void Parser::statement()
 
     if (checkToken(TokenType::STRING))
     {
-      this->emitter->emitLine("printf(\"" + this->curToken.get_text() + "\\n\")");
+      this->emitter->emitLine("printf(\"" + this->curToken.get_text() + "\\n\");");
       ;
       nextToken();
     }
@@ -164,6 +164,7 @@ void Parser::statement()
     match(TokenType::EQ);
     this->emitter->emit(" = ");
     expression();
+    this->emitter->emitLine(";");
   }
   // "INPUT" ident
   else if (checkToken(TokenType::INPUT))
@@ -175,7 +176,6 @@ void Parser::statement()
     ident(SymbolKind::VARIABLE);
     this->emitter->emitLine(")){");
     this->emitter->emitLine(identext + " = 0;");
-    this->emitter->emitLine("}");
     this->emitter->emitLine("scanf(\"\%*s\");\n}");
   }
 
@@ -193,6 +193,7 @@ void Parser::comparison()
   expression();
   if (isComparisonOperator())
   {
+    this->emitter->emit(this->curToken.get_text());
     nextToken();
     expression();
   }
@@ -203,6 +204,7 @@ void Parser::comparison()
 
   while (isComparisonOperator())
   {
+    this->emitter->emit(this->curToken.get_text());
     nextToken();
     expression();
   }
@@ -214,6 +216,7 @@ void Parser::term()
   unary();
   while (checkToken(TokenType::ASTERISK) || checkToken(TokenType::SLASH))
   {
+    this->emitter->emit(this->curToken.get_text());
     nextToken();
     unary();
   }
@@ -224,6 +227,7 @@ void Parser::unary()
   // std::cout << "UNARY" << std::endl;
   if (checkToken(TokenType::PLUS) || checkToken(TokenType::MINUS))
   {
+    this->emitter->emit(this->curToken.get_text());
     nextToken();
   }
   primary();
@@ -234,6 +238,7 @@ void Parser::primary()
   // std::cout << "PRIMARY" << " (" << (this->curToken).get_text() << ")" << std::endl;
   if (checkToken(TokenType::NUMBER))
   {
+    this->emitter->emit(this->curToken.get_text());
     nextToken();
   }
   else if (checkToken(TokenType::IDENT))
@@ -244,6 +249,7 @@ void Parser::primary()
     {
       abort("Underclared variable " + this->curToken.get_text());
     }
+    this->emitter->emit(identext);
     nextToken();
   }
   else
@@ -258,9 +264,11 @@ void Parser::expression()
   term();
   while (checkToken(TokenType::PLUS) || checkToken(TokenType::MINUS))
   {
+    this->emitter->emit(this->curToken.get_text());
     nextToken();
     term();
   }
+  //this->emitter->emitLine(";");
 }
 
 void Parser::ident(SymbolKind k)