From c6dedb754ea3d81ec6fdb6a71b3045f4594835cd Mon Sep 17 00:00:00 2001 From: Raekye Date: Sun, 9 Nov 2014 19:07:08 -0500 Subject: [PATCH] remove old stuff --- calc/.gitignore | 7 - calc/Makefile | 21 -- calc/codegen.cpp | 298 ------------------- calc/codegen.h | 50 ---- calc/codescope.cpp | 44 --- calc/codescope.h | 21 -- calc/hm.h | 8 - calc/kaleidoscope.cpp | 615 ---------------------------------------- calc/lexer.l | 47 --- calc/main.cpp | 112 -------- calc/node.cpp | 123 -------- calc/node.h | 100 ------- calc/number.cpp | 192 ------------- calc/number.h | 83 ------ calc/parser.y | 104 ------- calc/playground.cpp | 20 -- calc/script.txt | 1 - rpn_calc/.gitignore | 1 - rpn_calc/Makefile | 15 - rpn_calc/expression.cpp | 74 ----- rpn_calc/expression.h | 33 --- rpn_calc/lexer.l | 44 --- rpn_calc/main.c | 78 ----- rpn_calc/number.cpp | 1 - rpn_calc/number.h | 75 ----- rpn_calc/parser.y | 75 ----- 26 files changed, 2242 deletions(-) delete mode 100644 calc/.gitignore delete mode 100644 calc/Makefile delete mode 100644 calc/codegen.cpp delete mode 100644 calc/codegen.h delete mode 100644 calc/codescope.cpp delete mode 100644 calc/codescope.h delete mode 100644 calc/hm.h delete mode 100644 calc/kaleidoscope.cpp delete mode 100644 calc/lexer.l delete mode 100644 calc/main.cpp delete mode 100644 calc/node.cpp delete mode 100644 calc/node.h delete mode 100644 calc/number.cpp delete mode 100644 calc/number.h delete mode 100644 calc/parser.y delete mode 100644 calc/playground.cpp delete mode 100644 calc/script.txt delete mode 100644 rpn_calc/.gitignore delete mode 100644 rpn_calc/Makefile delete mode 100644 rpn_calc/expression.cpp delete mode 100644 rpn_calc/expression.h delete mode 100644 rpn_calc/lexer.l delete mode 100644 rpn_calc/main.c delete mode 100644 rpn_calc/number.cpp delete mode 100644 rpn_calc/number.h delete mode 100644 rpn_calc/parser.y diff --git a/calc/.gitignore b/calc/.gitignore deleted file mode 100644 index b3a570e..0000000 --- a/calc/.gitignore +++ /dev/null @@ -1,7 +0,0 @@ -calc -lexer.h -lex.yy.c -lexer.cpp -parser.hpp -parser.cpp -kaleidoscope.o diff --git a/calc/Makefile b/calc/Makefile deleted file mode 100644 index d729332..0000000 --- a/calc/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -FILES = lexer.cpp parser.cpp main.cpp node.cpp codegen.cpp codescope.cpp number.cpp -CC = g++ -CFLAGS = -g -fexceptions - -lexer.cpp: lexer.l - flex -o lexer.cpp --header-file=lexer.h lexer.l - -parser.cpp: parser.y lexer.cpp - bison -d -o parser.cpp parser.y - -build: $(FILES) - $(CC) $(FILES) -o calc `llvm-config --libs core jit native --cxxflags --ldflags` $(CFLAGS) - -clean: - rm -f *.o *~ lexer.cpp lexer.h parser.cpp parser.hpp calc - -kaleidoscope: - clang++ -g kaleidoscope.cpp `llvm-config --cppflags --ldflags --libs core jit native` -rdynamic -O3 -o kaleidoscope.o - -playground: - g++ playground.cpp -o playground.o diff --git a/calc/codegen.cpp b/calc/codegen.cpp deleted file mode 100644 index 407734d..0000000 --- a/calc/codegen.cpp +++ /dev/null @@ -1,298 +0,0 @@ -#include "node.h" -#include "codegen.h" -#include "parser.hpp" -#include -#include -#include "number.h" -#include "hm.h" - -extern "C" { - pointer_t number_add(Number* x, Number* y) { - return (pointer_t) x->add(y); - } - pointer_t number_sub(Number* x, Number* y) { - return (pointer_t) x->sub(y); - } - pointer_t number_mul(Number* x, Number* y) { - return (pointer_t) x->mul(y); - } - pointer_t number_div(Number* x, Number* y) { - return (pointer_t) x->div(y); - } - pointer_t number_create() { - UNumberValue val; - val.l = 17; - return (pointer_t) new PrimitiveNumber(eLONG, val); - } -} - -static void Error(const char* str) { - std::cout << str << std::endl; -} - -static llvm::Value* ErrorV(const char* str) { - Error(str); - return NULL; -} - -llvm::Type* llvm_pointer_ty() { - static llvm::Type* ty = NULL; - if (ty == NULL) { - if (sizeof(void*) == 8) { - ty = llvm::Type::getInt64Ty(llvm::getGlobalContext()); - } else if (sizeof(void*) == 4) { - ty = llvm::Type::getInt32Ty(llvm::getGlobalContext()); - } else { - // TODO: error - } - } - return ty; -} - -static llvm::IRBuilder<> builder(llvm::getGlobalContext()); - -// static llvm::Value* llvm_value_for_primitive_number(std::string type, NPrimitiveNumber* num) { -// if (type == "byte") { -// return llvm::ConstantInt::get(llvm::Type::getInt8Ty(llvm::getGlobalContext()), boost::lexical_cast(num->str), true); -// } else if (type == "ubyte") { -// return llvm::ConstantInt::get(llvm::Type::getInt8Ty(llvm::getGlobalContext()), boost::lexical_cast(num->str), false); -// } else if (type == "short") { -// return llvm::ConstantInt::get(llvm::Type::getInt16Ty(llvm::getGlobalContext()), boost::lexical_cast(num->str), true); -// } else if (type == "ushort") { -// return llvm::ConstantInt::get(llvm::Type::getInt16Ty(llvm::getGlobalContext()), boost::lexical_cast(num->str), false); -// } else if (type == "int") { -// return llvm::ConstantInt::get(llvm::Type::getInt32Ty(llvm::getGlobalContext()), boost::lexical_cast(num->str), true); -// } else if (type == "uint") { -// return llvm::ConstantInt::get(llvm::Type::getInt32Ty(llvm::getGlobalContext()), boost::lexical_cast(num->str), false); -// } else if (type == "long") { -// return llvm::ConstantInt::get(llvm::Type::getInt64Ty(llvm::getGlobalContext()), boost::lexical_cast(num->str), true); -// } else if (type == "ulong") { -// return llvm::ConstantInt::get(llvm::Type::getInt64Ty(llvm::getGlobalContext()), boost::lexical_cast(num->str), false); -// } if (type == "float") { -// return llvm::ConstantFP::get(llvm::Type::getFloatTy(llvm::getGlobalContext()), boost::lexical_cast(num->str)); -// } else if (type == "double") { -// return llvm::ConstantFP::get(llvm::Type::getDoubleTy(llvm::getGlobalContext()), boost::lexical_cast(num->str)); -// } -// return NULL; -// } - -static llvm::Value* llvm_value_for_primitive_number(NPrimitiveNumber* num) { - if (num->type == eBYTE) { - return llvm::ConstantInt::get(llvm::Type::getInt8Ty(llvm::getGlobalContext()), num->val.b, true); - } else if (num->type == eUBYTE) { - return llvm::ConstantInt::get(llvm::Type::getInt8Ty(llvm::getGlobalContext()), num->val.ub, false); - } else if (num->type == eSHORT) { - return llvm::ConstantInt::get(llvm::Type::getInt16Ty(llvm::getGlobalContext()), num->val.s, true); - } else if (num->type == eUSHORT) { - return llvm::ConstantInt::get(llvm::Type::getInt16Ty(llvm::getGlobalContext()), num->val.us, false); - } else if (num->type == eINT) { - return llvm::ConstantInt::get(llvm::Type::getInt32Ty(llvm::getGlobalContext()), num->val.i, true); - } else if (num->type == eUINT) { - return llvm::ConstantInt::get(llvm::Type::getInt32Ty(llvm::getGlobalContext()), num->val.ui, false); - } else if (num->type == eLONG) { - return llvm::ConstantInt::get(llvm::Type::getInt64Ty(llvm::getGlobalContext()), num->val.l, true); - } else if (num->type == eULONG) { - return llvm::ConstantInt::get(llvm::Type::getInt64Ty(llvm::getGlobalContext()), num->val.ul, false); - } else if (num->type == eFLOAT) { - return llvm::ConstantFP::get(llvm::Type::getFloatTy(llvm::getGlobalContext()), num->val.f); - } else if (num->type == eDOUBLE) { - return llvm::ConstantFP::get(llvm::Type::getDoubleTy(llvm::getGlobalContext()), num->val.d); - } - return NULL; -} - -static llvm::Type* llvm_type_for_primitive_number(std::string type) { - if (type == "byte") { - return llvm::Type::getInt8Ty(llvm::getGlobalContext()); - } else if (type == "ubyte") { - return llvm::Type::getInt8Ty(llvm::getGlobalContext()); - } else if (type == "short") { - return llvm::Type::getInt16Ty(llvm::getGlobalContext()); - } else if (type == "ushort") { - return llvm::Type::getInt16Ty(llvm::getGlobalContext()); - } else if (type == "int") { - return llvm::Type::getInt32Ty(llvm::getGlobalContext()); - } else if (type == "uint") { - return llvm::Type::getInt32Ty(llvm::getGlobalContext()); - } else if (type == "long") { - return llvm::Type::getInt64Ty(llvm::getGlobalContext()); - } else if (type == "ulong") { - return llvm::Type::getInt64Ty(llvm::getGlobalContext()); - } if (type == "float") { - return llvm::Type::getFloatTy(llvm::getGlobalContext()); - } else if (type == "double") { - return llvm::Type::getDoubleTy(llvm::getGlobalContext()); - } - return NULL; -} - -static ENumberType enumbertype_from_llvm_type(llvm::Type* t) { - if (t == llvm_type_for_primitive_number("byte")) { - return eBYTE; - } else if (t == llvm_type_for_primitive_number("ubyte")) { - return eUBYTE; - } else if (t == llvm_type_for_primitive_number("short")) { - return eSHORT; - } else if (t == llvm_type_for_primitive_number("ushort")) { - return eUSHORT; - } else if (t == llvm_type_for_primitive_number("int")) { - return eINT; - } else if (t == llvm_type_for_primitive_number("uint")) { - return eUINT; - } else if (t == llvm_type_for_primitive_number("long")) { - return eLONG; - } else if (t == llvm_type_for_primitive_number("ulong")) { - return eULONG; - } else if (t == llvm_type_for_primitive_number("float")) { - return eFLOAT; - } else if (t == llvm_type_for_primitive_number("double")) { - return eDOUBLE; - } - // throw std::invalid_argument("Unknown type."); - return eBYTE; -} - -static bool llvm_type_can_assign_to(ENumberType source, ENumberType target) { - if (target == eDOUBLE) { - return true; - } - if (source > target) { - return false; - } - return true; -} - -CodeGen::CodeGen(llvm::Module* module) { - this->module = module; - //this->scope.push(); - //this->blocks.push(llvm::BasicBlock::Create(llvm::getGlobalContext())); -} - -void CodeGen::push_block(llvm::BasicBlock* block) { - this->blocks.push(block); -} - -void CodeGen::pop_block() { - //delete this->blocks.top(); - this->blocks.pop(); -} - -llvm::BasicBlock* CodeGen::current_block() { - return this->blocks.top(); -} - -void CodeGen::generate_code(NExpression* root) { -} - -void CodeGen::run_code() { -} - -llvm::Value* NPrimitiveNumber::gen_code(CodeGen* code_gen) { - std::cout << "Generating int..." << std::endl; - llvm::Function* number_create_fn = code_gen->module->getFunction("number_create"); - if (number_create_fn == NULL) { - return ErrorV("Unable to create number"); - } - return builder.CreateCall(number_create_fn, std::vector(), "calltmp"); - // return llvm_value_for_primitive_number(this); -} - -llvm::Value* NBinaryOperator::gen_code(CodeGen* code_gen) { - std::cout << "Generating binary operator..." << std::endl; - llvm::Value* l = this->lhs->gen_code(code_gen); - llvm::Value* r = this->rhs->gen_code(code_gen); - if (l == NULL || r == NULL) { - return NULL; - } - llvm::Function* number_binary_op_fn = NULL; - builder.SetInsertPoint(code_gen->current_block()); - switch (this->op) { - case eADD: - // return builder.CreateAdd(l, r, "addtmp"); - number_binary_op_fn = code_gen->module->getFunction("number_add"); - case eSUBTRACT: - // return builder.CreateSub(l, r, "subtmp"); - number_binary_op_fn = code_gen->module->getFunction("number_sub"); - case eMULTIPLY: - // return builder.CreateMul(l, r, "multmp"); - number_binary_op_fn = code_gen->module->getFunction("number_mul"); - case eDIVIDE: - // return builder.CreateSDiv(l, r, "divtmp"); - number_binary_op_fn = code_gen->module->getFunction("number_div"); - case eRAISE: - // return builder.CreateAdd(l, r, "powtmp"); - number_binary_op_fn = code_gen->module->getFunction("number_add"); - } - if (number_binary_op_fn == NULL) { - return ErrorV("Unable to get number binary operator"); - } - std::vector args; - args.push_back(l); - args.push_back(r); - return builder.CreateCall(number_binary_op_fn, args, "calltmp"); - // return ErrorV("Invalid binary operator."); -} - -llvm::Value* NFunction::gen_code(CodeGen* code_gen) { - std::vector arg_types; - llvm::FunctionType* fn_type = llvm::FunctionType::get(llvm::Type::getInt64Ty(llvm::getGlobalContext()), arg_types, false); - llvm::Function* fn = llvm::Function::Create(fn_type, llvm::Function::ExternalLinkage, "", code_gen->module); - - llvm::BasicBlock* basic_block = llvm::BasicBlock::Create(llvm::getGlobalContext(), "entry", fn); - code_gen->push_block(basic_block); - code_gen->scope.push(); - builder.SetInsertPoint(basic_block); - - llvm::Value* ret_val = this->body->gen_code(code_gen); - if (ret_val != NULL) { - builder.CreateRet(ret_val); - llvm::verifyFunction(*fn); - code_gen->pop_block(); - code_gen->scope.pop(); - return fn; - } - code_gen->pop_block(); - code_gen->scope.pop(); - return ErrorV("Error generating function"); -} - -llvm::Value* NIdentifier::gen_code(CodeGen* code_gen) { - llvm::Value* val = code_gen->scope.get(this->name); - if (val == NULL) { - std::cout << "Undeclared variable " << this->name << std::endl; - return NULL; - } - //return builder.CreateLoad(val, false, ""); - return new llvm::LoadInst(val, "", false, code_gen->current_block()); -} - -llvm::Value* NAssignment::gen_code(CodeGen* code_gen) { - std::cout << "Generating assignment for " << this->lhs->name << "..." << std::endl; - llvm::Value* val = code_gen->scope.get(this->lhs->name); - if (val == NULL) { - std::cout << "Undeclared variable " << this->lhs->name << std::endl; - return NULL; - } - llvm::Value* rhs_val = this->rhs->gen_code(code_gen); - builder.SetInsertPoint(code_gen->current_block()); - builder.CreateStore(rhs_val, val, false); - return rhs_val; -} - -llvm::Value* NVariableDeclaration::gen_code(CodeGen* code_gen) { - std::cout << "Generating variable declaration for " << this->var_name->name << ", type " << this->type->name << "..." << std::endl; - builder.SetInsertPoint(code_gen->current_block()); - llvm::Type* declared_type = llvm_type_for_primitive_number(this->type->name); - llvm::AllocaInst* alloc = new llvm::AllocaInst(declared_type, this->var_name->name.c_str(), code_gen->current_block()); //builder.CreateAlloca(llvm::Type::getInt64Ty(llvm::getGlobalContext()), 0, this->var_name->name.c_str()); - code_gen->scope.put(this->var_name->name, alloc); - //return llvm::ConstantInt::get(llvm::Type::getInt64Ty(llvm::getGlobalContext()), 0, true); - return alloc; -} - -llvm::Value* NBlock::gen_code(CodeGen* code_gen) { - llvm::Value* last = NULL; - for (std::vector::iterator it = this->statements.begin(); it != this->statements.end(); it++) { - last = (*it)->gen_code(code_gen); - } - return last; -} diff --git a/calc/codegen.h b/calc/codegen.h deleted file mode 100644 index a831d70..0000000 --- a/calc/codegen.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef __CODEGEN_H_ -#define __CODEGEN_H_ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "codescope.h" -#include "hm.h" -#include "number.h" - -class CodeGen { -public: - llvm::Module* module; - std::stack blocks; - CodeScope scope; - CodeGen(llvm::Module*); - - void generate_code(NExpression* root); - void run_code(); // GenericValue - - void push_block(llvm::BasicBlock*); - void pop_block(); - llvm::BasicBlock* current_block(); -}; - -extern "C" { - pointer_t number_add(Number* x, Number* y); - pointer_t number_sub(Number* x, Number* y); - pointer_t number_mul(Number* x, Number* y); - pointer_t number_div(Number* x, Number* y); - pointer_t number_create(); -} -llvm::Type* llvm_pointer_ty(); - -#endif // __CODEGEN_H_ diff --git a/calc/codescope.cpp b/calc/codescope.cpp deleted file mode 100644 index 03077fd..0000000 --- a/calc/codescope.cpp +++ /dev/null @@ -1,44 +0,0 @@ -#include "codescope.h" -#include - -// TODO: freeing stl - -CodeScope::CodeScope() { -} - -CodeScope::~CodeScope() { - // while (this->stacks.size() > 0) { - // this->pop(); - // } -} - -void CodeScope::put(std::string key, llvm::Value* val) { - (*this->stacks.back())[key] = val; -} - -llvm::Value* CodeScope::get(std::string key) { - for (std::deque*>::reverse_iterator it = this->stacks.rbegin(); it != this->stacks.rend(); it++) { - std::map::iterator found = (*it)->find(key); - if (found != (*it)->end()) { - return found->second; - } - } - return NULL; -} - -bool CodeScope::contains(std::string key) { - return this->get(key) != NULL; -} - -void CodeScope::push() { - std::map* scope = new std::map(); - this->stacks.push_back(scope); -} - -void CodeScope::pop() { - for (std::map::iterator it = this->stacks.back()->begin(); it != this->stacks.back()->end(); it++) { - std::cout << "Deleting " << it->second << std::endl; - //delete it->second; - } - this->stacks.pop_back(); -} \ No newline at end of file diff --git a/calc/codescope.h b/calc/codescope.h deleted file mode 100644 index 023708a..0000000 --- a/calc/codescope.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef __CODESCOPE_H_ -#define __CODESCOPE_H_ - -#include -#include -#include - -class CodeScope { -public: - CodeScope(); - ~CodeScope(); - void put(std::string, llvm::Value*); - llvm::Value* get(std::string); - bool contains(std::string); - void push(); - void pop(); -private: - std::deque*> stacks; -}; - -#endif // __CODESCOPE_H_ \ No newline at end of file diff --git a/calc/hm.h b/calc/hm.h deleted file mode 100644 index acb5a45..0000000 --- a/calc/hm.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef __HM_H_ -#define __HM_H_ - -#include - -typedef int64_t pointer_t; - -#endif // __HM_H_ diff --git a/calc/kaleidoscope.cpp b/calc/kaleidoscope.cpp deleted file mode 100644 index 528b2c2..0000000 --- a/calc/kaleidoscope.cpp +++ /dev/null @@ -1,615 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace llvm; - -//===----------------------------------------------------------------------===// -// Lexer -//===----------------------------------------------------------------------===// - -// The lexer returns tokens [0-255] if it is an unknown character, otherwise one -// of these for known things. -enum Token { - tok_eof = -1, - - // commands - tok_def = -2, tok_extern = -3, - - // primary - tok_identifier = -4, tok_number = -5 -}; - -static std::string IdentifierStr; // Filled in if tok_identifier -static double NumVal; // Filled in if tok_number - -/// gettok - Return the next token from standard input. -static int gettok() { - static int LastChar = ' '; - - // Skip any whitespace. - while (isspace(LastChar)) - LastChar = getchar(); - - if (isalpha(LastChar)) { // identifier: [a-zA-Z][a-zA-Z0-9]* - IdentifierStr = LastChar; - while (isalnum((LastChar = getchar()))) - IdentifierStr += LastChar; - - if (IdentifierStr == "def") return tok_def; - if (IdentifierStr == "extern") return tok_extern; - return tok_identifier; - } - - if (isdigit(LastChar) || LastChar == '.') { // Number: [0-9.]+ - std::string NumStr; - do { - NumStr += LastChar; - LastChar = getchar(); - } while (isdigit(LastChar) || LastChar == '.'); - - NumVal = strtod(NumStr.c_str(), 0); - return tok_number; - } - - if (LastChar == '#') { - // Comment until end of line. - do LastChar = getchar(); - while (LastChar != EOF && LastChar != '\n' && LastChar != '\r'); - - if (LastChar != EOF) - return gettok(); - } - - // Check for end of file. Don't eat the EOF. - if (LastChar == EOF) - return tok_eof; - - // Otherwise, just return the character as its ascii value. - int ThisChar = LastChar; - LastChar = getchar(); - return ThisChar; -} - -//===----------------------------------------------------------------------===// -// Abstract Syntax Tree (aka Parse Tree) -//===----------------------------------------------------------------------===// -namespace { -/// ExprAST - Base class for all expression nodes. -class ExprAST { -public: - virtual ~ExprAST() {} - virtual Value *Codegen() = 0; -}; - -/// NumberExprAST - Expression class for numeric literals like "1.0". -class NumberExprAST : public ExprAST { - double Val; -public: - NumberExprAST(double val) : Val(val) {} - virtual Value *Codegen(); -}; - -/// VariableExprAST - Expression class for referencing a variable, like "a". -class VariableExprAST : public ExprAST { - std::string Name; -public: - VariableExprAST(const std::string &name) : Name(name) {} - virtual Value *Codegen(); -}; - -/// BinaryExprAST - Expression class for a binary operator. -class BinaryExprAST : public ExprAST { - char Op; - ExprAST *LHS, *RHS; -public: - BinaryExprAST(char op, ExprAST *lhs, ExprAST *rhs) - : Op(op), LHS(lhs), RHS(rhs) {} - virtual Value *Codegen(); -}; - -/// CallExprAST - Expression class for function calls. -class CallExprAST : public ExprAST { - std::string Callee; - std::vector Args; -public: - CallExprAST(const std::string &callee, std::vector &args) - : Callee(callee), Args(args) {} - virtual Value *Codegen(); -}; - -/// PrototypeAST - This class represents the "prototype" for a function, -/// which captures its name, and its argument names (thus implicitly the number -/// of arguments the function takes). -class PrototypeAST { - std::string Name; - std::vector Args; -public: - PrototypeAST(const std::string &name, const std::vector &args) - : Name(name), Args(args) {} - - Function *Codegen(); -}; - -/// FunctionAST - This class represents a function definition itself. -class FunctionAST { - PrototypeAST *Proto; - ExprAST *Body; -public: - FunctionAST(PrototypeAST *proto, ExprAST *body) - : Proto(proto), Body(body) {} - - Function *Codegen(); -}; -} // end anonymous namespace - -//===----------------------------------------------------------------------===// -// Parser -//===----------------------------------------------------------------------===// - -/// CurTok/getNextToken - Provide a simple token buffer. CurTok is the current -/// token the parser is looking at. getNextToken reads another token from the -/// lexer and updates CurTok with its results. -static int CurTok; -static int getNextToken() { - return CurTok = gettok(); -} - -/// BinopPrecedence - This holds the precedence for each binary operator that is -/// defined. -static std::map BinopPrecedence; - -/// GetTokPrecedence - Get the precedence of the pending binary operator token. -static int GetTokPrecedence() { - if (!isascii(CurTok)) - return -1; - - // Make sure it's a declared binop. - int TokPrec = BinopPrecedence[CurTok]; - if (TokPrec <= 0) return -1; - return TokPrec; -} - -/// Error* - These are little helper functions for error handling. -ExprAST *Error(const char *Str) { fprintf(stderr, "Error: %s\n", Str);return 0;} -PrototypeAST *ErrorP(const char *Str) { Error(Str); return 0; } -FunctionAST *ErrorF(const char *Str) { Error(Str); return 0; } - -static ExprAST *ParseExpression(); - -/// identifierexpr -/// ::= identifier -/// ::= identifier '(' expression* ')' -static ExprAST *ParseIdentifierExpr() { - std::string IdName = IdentifierStr; - - getNextToken(); // eat identifier. - - if (CurTok != '(') // Simple variable ref. - return new VariableExprAST(IdName); - - // Call. - getNextToken(); // eat ( - std::vector Args; - if (CurTok != ')') { - while (1) { - ExprAST *Arg = ParseExpression(); - if (!Arg) return 0; - Args.push_back(Arg); - - if (CurTok == ')') break; - - if (CurTok != ',') - return Error("Expected ')' or ',' in argument list"); - getNextToken(); - } - } - - // Eat the ')'. - getNextToken(); - - return new CallExprAST(IdName, Args); -} - -/// numberexpr ::= number -static ExprAST *ParseNumberExpr() { - ExprAST *Result = new NumberExprAST(NumVal); - getNextToken(); // consume the number - return Result; -} - -/// parenexpr ::= '(' expression ')' -static ExprAST *ParseParenExpr() { - getNextToken(); // eat (. - ExprAST *V = ParseExpression(); - if (!V) return 0; - - if (CurTok != ')') - return Error("expected ')'"); - getNextToken(); // eat ). - return V; -} - -/// primary -/// ::= identifierexpr -/// ::= numberexpr -/// ::= parenexpr -static ExprAST *ParsePrimary() { - switch (CurTok) { - default: return Error("unknown token when expecting an expression"); - case tok_identifier: return ParseIdentifierExpr(); - case tok_number: return ParseNumberExpr(); - case '(': return ParseParenExpr(); - } -} - -/// binoprhs -/// ::= ('+' primary)* -static ExprAST *ParseBinOpRHS(int ExprPrec, ExprAST *LHS) { - // If this is a binop, find its precedence. - while (1) { - int TokPrec = GetTokPrecedence(); - - // If this is a binop that binds at least as tightly as the current binop, - // consume it, otherwise we are done. - if (TokPrec < ExprPrec) - return LHS; - - // Okay, we know this is a binop. - int BinOp = CurTok; - getNextToken(); // eat binop - - // Parse the primary expression after the binary operator. - ExprAST *RHS = ParsePrimary(); - if (!RHS) return 0; - - // If BinOp binds less tightly with RHS than the operator after RHS, let - // the pending operator take RHS as its LHS. - int NextPrec = GetTokPrecedence(); - if (TokPrec < NextPrec) { - RHS = ParseBinOpRHS(TokPrec+1, RHS); - if (RHS == 0) return 0; - } - - // Merge LHS/RHS. - LHS = new BinaryExprAST(BinOp, LHS, RHS); - } -} - -/// expression -/// ::= primary binoprhs -/// -static ExprAST *ParseExpression() { - ExprAST *LHS = ParsePrimary(); - if (!LHS) return 0; - - return ParseBinOpRHS(0, LHS); -} - -/// prototype -/// ::= id '(' id* ')' -static PrototypeAST *ParsePrototype() { - if (CurTok != tok_identifier) - return ErrorP("Expected function name in prototype"); - - std::string FnName = IdentifierStr; - getNextToken(); - - if (CurTok != '(') - return ErrorP("Expected '(' in prototype"); - - std::vector ArgNames; - while (getNextToken() == tok_identifier) - ArgNames.push_back(IdentifierStr); - if (CurTok != ')') - return ErrorP("Expected ')' in prototype"); - - // success. - getNextToken(); // eat ')'. - - return new PrototypeAST(FnName, ArgNames); -} - -/// definition ::= 'def' prototype expression -static FunctionAST *ParseDefinition() { - getNextToken(); // eat def. - PrototypeAST *Proto = ParsePrototype(); - if (Proto == 0) return 0; - - if (ExprAST *E = ParseExpression()) - return new FunctionAST(Proto, E); - return 0; -} - -/// toplevelexpr ::= expression -static FunctionAST *ParseTopLevelExpr() { - if (ExprAST *E = ParseExpression()) { - // Make an anonymous proto. - PrototypeAST *Proto = new PrototypeAST("", std::vector()); - return new FunctionAST(Proto, E); - } - return 0; -} - -/// external ::= 'extern' prototype -static PrototypeAST *ParseExtern() { - getNextToken(); // eat extern. - return ParsePrototype(); -} - -//===----------------------------------------------------------------------===// -// Code Generation -//===----------------------------------------------------------------------===// - -static Module *TheModule; -static IRBuilder<> Builder(getGlobalContext()); -static std::map NamedValues; -static FunctionPassManager *TheFPM; - -Value *ErrorV(const char *Str) { Error(Str); return 0; } - -Value *NumberExprAST::Codegen() { - return ConstantFP::get(getGlobalContext(), APFloat(Val)); -} - -Value *VariableExprAST::Codegen() { - // Look this variable up in the function. - Value *V = NamedValues[Name]; - return V ? V : ErrorV("Unknown variable name"); -} - -Value *BinaryExprAST::Codegen() { - Value *L = LHS->Codegen(); - Value *R = RHS->Codegen(); - if (L == 0 || R == 0) return 0; - - switch (Op) { - case '+': return Builder.CreateFAdd(L, R, "addtmp"); - case '-': return Builder.CreateFSub(L, R, "subtmp"); - case '*': return Builder.CreateFMul(L, R, "multmp"); - case '<': - L = Builder.CreateFCmpULT(L, R, "cmptmp"); - // Convert bool 0/1 to double 0.0 or 1.0 - return Builder.CreateUIToFP(L, Type::getDoubleTy(getGlobalContext()), - "booltmp"); - default: return ErrorV("invalid binary operator"); - } -} - -Value *CallExprAST::Codegen() { - // Look up the name in the global module table. - Function *CalleeF = TheModule->getFunction(Callee); - if (CalleeF == 0) - return ErrorV("Unknown function referenced"); - - // If argument mismatch error. - if (CalleeF->arg_size() != Args.size()) - return ErrorV("Incorrect # arguments passed"); - - std::vector ArgsV; - for (unsigned i = 0, e = Args.size(); i != e; ++i) { - ArgsV.push_back(Args[i]->Codegen()); - if (ArgsV.back() == 0) return 0; - } - - return Builder.CreateCall(CalleeF, ArgsV, "calltmp"); -} - -Function *PrototypeAST::Codegen() { - // Make the function type: double(double,double) etc. - std::vector Doubles(Args.size(), - Type::getDoubleTy(getGlobalContext())); - FunctionType *FT = FunctionType::get(Type::getDoubleTy(getGlobalContext()), - Doubles, false); - - Function *F = Function::Create(FT, Function::ExternalLinkage, Name, TheModule); - - // If F conflicted, there was already something named 'Name'. If it has a - // body, don't allow redefinition or reextern. - if (F->getName() != Name) { - // Delete the one we just made and get the existing one. - F->eraseFromParent(); - F = TheModule->getFunction(Name); - - // If F already has a body, reject this. - if (!F->empty()) { - ErrorF("redefinition of function"); - return 0; - } - - // If F took a different number of args, reject. - if (F->arg_size() != Args.size()) { - ErrorF("redefinition of function with different # args"); - return 0; - } - } - - // Set names for all arguments. - unsigned Idx = 0; - for (Function::arg_iterator AI = F->arg_begin(); Idx != Args.size(); - ++AI, ++Idx) { - AI->setName(Args[Idx]); - - // Add arguments to variable symbol table. - NamedValues[Args[Idx]] = AI; - } - - return F; -} - -Function *FunctionAST::Codegen() { - NamedValues.clear(); - - Function *TheFunction = Proto->Codegen(); - if (TheFunction == 0) - return 0; - - // Create a new basic block to start insertion into. - BasicBlock *BB = BasicBlock::Create(getGlobalContext(), "entry", TheFunction); - Builder.SetInsertPoint(BB); - - if (Value *RetVal = Body->Codegen()) { - // Finish off the function. - Builder.CreateRet(RetVal); - - // Validate the generated code, checking for consistency. - verifyFunction(*TheFunction); - - // Optimize the function. - TheFPM->run(*TheFunction); - - return TheFunction; - } - - // Error reading body, remove function. - TheFunction->eraseFromParent(); - return 0; -} - -//===----------------------------------------------------------------------===// -// Top-Level parsing and JIT Driver -//===----------------------------------------------------------------------===// - -static ExecutionEngine *TheExecutionEngine; - -static void HandleDefinition() { - if (FunctionAST *F = ParseDefinition()) { - if (Function *LF = F->Codegen()) { - fprintf(stderr, "Read function definition:"); - LF->dump(); - } - } else { - // Skip token for error recovery. - getNextToken(); - } -} - -static void HandleExtern() { - if (PrototypeAST *P = ParseExtern()) { - if (Function *F = P->Codegen()) { - fprintf(stderr, "Read extern: "); - F->dump(); - } - } else { - // Skip token for error recovery. - getNextToken(); - } -} - -static void HandleTopLevelExpression() { - // Evaluate a top-level expression into an anonymous function. - if (FunctionAST *F = ParseTopLevelExpr()) { - if (Function *LF = F->Codegen()) { - // JIT the function, returning a function pointer. - void *FPtr = TheExecutionEngine->getPointerToFunction(LF); - - // Cast it to the right type (takes no arguments, returns a double) so we - // can call it as a native function. - double (*FP)() = (double (*)())(intptr_t)FPtr; - fprintf(stderr, "Evaluated to %f\n", FP()); - } - } else { - // Skip token for error recovery. - getNextToken(); - } -} - -/// top ::= definition | external | expression | ';' -static void MainLoop() { - while (1) { - fprintf(stderr, "ready> "); - switch (CurTok) { - case tok_eof: return; - case ';': getNextToken(); break; // ignore top-level semicolons. - case tok_def: HandleDefinition(); break; - case tok_extern: HandleExtern(); break; - default: HandleTopLevelExpression(); break; - } - } -} - -//===----------------------------------------------------------------------===// -// "Library" functions that can be "extern'd" from user code. -//===----------------------------------------------------------------------===// - -/// putchard - putchar that takes a double and returns 0. -extern "C" -double putchard(double X) { - putchar((char)X); - return 0; -} - -//===----------------------------------------------------------------------===// -// Main driver code. -//===----------------------------------------------------------------------===// - -int main() { - InitializeNativeTarget(); - LLVMContext &Context = getGlobalContext(); - - // Install standard binary operators. - // 1 is lowest precedence. - BinopPrecedence['<'] = 10; - BinopPrecedence['+'] = 20; - BinopPrecedence['-'] = 20; - BinopPrecedence['*'] = 40; // highest. - - // Prime the first token. - fprintf(stderr, "ready> "); - getNextToken(); - - // Make the module, which holds all the code. - TheModule = new Module("my cool jit", Context); - - // Create the JIT. This takes ownership of the module. - std::string ErrStr; - TheExecutionEngine = EngineBuilder(TheModule).setErrorStr(&ErrStr).create(); - if (!TheExecutionEngine) { - fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str()); - exit(1); - } - - FunctionPassManager OurFPM(TheModule); - - // Set up the optimizer pipeline. Start with registering info about how the - // target lays out data structures. - OurFPM.add(new DataLayout(*TheExecutionEngine->getDataLayout())); - // Provide basic AliasAnalysis support for GVN. - OurFPM.add(createBasicAliasAnalysisPass()); - // Do simple "peephole" optimizations and bit-twiddling optzns. - OurFPM.add(createInstructionCombiningPass()); - // Reassociate expressions. - OurFPM.add(createReassociatePass()); - // Eliminate Common SubExpressions. - OurFPM.add(createGVNPass()); - // Simplify the control flow graph (deleting unreachable blocks, etc). - OurFPM.add(createCFGSimplificationPass()); - - OurFPM.doInitialization(); - - // Set the global so the code gen can use this. - TheFPM = &OurFPM; - - // Run the main "interpreter loop" now. - MainLoop(); - - TheFPM = 0; - - // Print out all of the generated code. - TheModule->dump(); - - return 0; -} diff --git a/calc/lexer.l b/calc/lexer.l deleted file mode 100644 index c780454..0000000 --- a/calc/lexer.l +++ /dev/null @@ -1,47 +0,0 @@ -%{ - -#include "node.h" -#include "parser.hpp" -#include - -#define SAVE_TOKEN yylval->str = new std::string(yytext, yyleng) - -%} - -%option reentrant noyywrap never-interactive nounistd -%option bison-bridge - -LPAREN "(" -RPAREN ")" -SEMICOLON ";" -ADD "+" -MULTIPLY "*" -SUBTRACT "-" -DIVIDE "/" -RAISE "*\\*" -EQUALS "=" - -DIGIT [0-9] -IDENTIFIER [a-zA-Z_][a-zA-Z0-9_]* - -NUMBER {DIGIT}+ -WS [ \r\n\t]* - -%% - -{WS} { /* pass */ } -{NUMBER} { SAVE_TOKEN; return TOKEN_NUMBER; } - -{MULTIPLY} { return TOKEN_MULTIPLY; } -{DIVIDE} { return TOKEN_DIVIDE; } -{ADD} { return TOKEN_ADD; } -{SUBTRACT} { return TOKEN_SUBTRACT; } -{RAISE} { return TOKEN_RAISE; } -{LPAREN} { return TOKEN_LPAREN; } -{RPAREN} { return TOKEN_RPAREN; } -{SEMICOLON} { return TOKEN_SEMICOLON; } -{IDENTIFIER} { SAVE_TOKEN; return TOKEN_IDENTIFIER; } -{EQUALS} { return TOKEN_EQUALS; } -. { printf("Unknown token!"); } - -%% \ No newline at end of file diff --git a/calc/main.cpp b/calc/main.cpp deleted file mode 100644 index 2236b51..0000000 --- a/calc/main.cpp +++ /dev/null @@ -1,112 +0,0 @@ -#include "node.h" -#include "parser.hpp" -#include "codegen.h" -#include "lexer.h" - -#include -#include -#include -#include - -int yyparse(NExpression** expression, yyscan_t scanner); - -extern NExpression* programBlock; - -NExpression* getAST(const char* str) { - NExpression* expr; - yyscan_t scanner; - YY_BUFFER_STATE state; - if (yylex_init(&scanner)) { - return NULL; - } - - state = yy_scan_string(str, scanner); - - if (yyparse(&expr, scanner)) { - return NULL; - } - - yy_delete_buffer(state, scanner); - yylex_destroy(scanner); - - return expr; -} - -void run_code(const char* code) { - NExpression* root_expr = getAST(code); - if (root_expr == NULL) { - std::cout << "Root expression was null! Ahhhhhhhhhhhhh!" << std::endl; - return; - } - - std::string error_str; - llvm::Module* module = new llvm::Module("top", llvm::getGlobalContext()); - llvm::ExecutionEngine* execution_engine = llvm::EngineBuilder(module).setErrorStr(&error_str).setEngineKind(llvm::EngineKind::JIT).create(); - std::vector number_binary_op_fn_args(2, llvm_pointer_ty()); - llvm::FunctionType* number_binary_op_fn_ty = llvm::FunctionType::get(llvm_pointer_ty(), number_binary_op_fn_args, false); - llvm::Function* number_binary_op_add = llvm::Function::Create(number_binary_op_fn_ty, llvm::Function::ExternalLinkage, "number_add", module); - llvm::Function* number_binary_op_sub = llvm::Function::Create(number_binary_op_fn_ty, llvm::Function::ExternalLinkage, "number_sub", module); - llvm::Function* number_binary_op_mul = llvm::Function::Create(number_binary_op_fn_ty, llvm::Function::ExternalLinkage, "number_mul", module); - llvm::Function* number_binary_op_div = llvm::Function::Create(number_binary_op_fn_ty, llvm::Function::ExternalLinkage, "number_div", module); - llvm::FunctionType* number_create_fn_ty = llvm::FunctionType::get(llvm_pointer_ty(), std::vector(), false); - llvm::Function* number_create_fn = llvm::Function::Create(number_create_fn_ty, llvm::Function::ExternalLinkage, "number_create", module); - execution_engine->addGlobalMapping(number_binary_op_add, (void*) &number_add); - execution_engine->addGlobalMapping(number_binary_op_sub, (void*) &number_sub); - execution_engine->addGlobalMapping(number_binary_op_mul, (void*) &number_mul); - execution_engine->addGlobalMapping(number_binary_op_div, (void*) &number_div); - execution_engine->addGlobalMapping(number_create_fn, (void*) &number_create); - CodeGen code_gen(module); - - std::cout << "execution engine " << execution_engine << std::endl; - if (execution_engine == NULL) { - std::cout << "Unable to create execution engine." << std::endl; - return; - } - - NFunction main_fn(root_expr); - - // llvm::Value* root_val = root_expr->gen_code(&code_gen); - - // std::cout << "Root val code:" << std::endl; - // root_val->dump(); - - llvm::Function* main_fn_val = (llvm::Function*) main_fn.gen_code(&code_gen); - std::cout << "Main fn code:" << std::endl; - main_fn_val->dump(); - void* fn_ptr = execution_engine->getPointerToFunction(main_fn_val); - int64_t (*fn_ptr_native)() = (int64_t (*)())(intptr_t) fn_ptr; - int64_t ret = fn_ptr_native(); - PrimitiveNumber* pn = (PrimitiveNumber*) ret; - std::cout << "Main fn at " << fn_ptr << "; executed: " << ret << "; was " << pn->val.l << std::endl; - - // code_gen.generate_code(programBlock); - // code_gen.run_code(); -} - -int main(int argc, char* argv[]) { - llvm::InitializeNativeTarget(); - std::cout << "Started." << std::endl; - if (argc > 1) { - std::string str = ""; - std::ifstream f(argv[1]); - if (f.is_open()) { - std::string line; - while (std::getline(f, line)) { - str += line + "\n"; - } - } - std::cout << "Reading from file, contents:\n" << str << std::endl; - run_code(str.c_str()); - } else { - std::string line; - while (true) { - std::cout << "> "; - if (!std::getline(std::cin, line)) { - break; - } - run_code(line.c_str()); - } - } - std::cout << "Done." << std::endl; - return 0; -} diff --git a/calc/node.cpp b/calc/node.cpp deleted file mode 100644 index f73c17b..0000000 --- a/calc/node.cpp +++ /dev/null @@ -1,123 +0,0 @@ -#include "node.h" -#include -#include -#include - -Node::~Node() { - return; -} - -NPrimitiveNumber::~NPrimitiveNumber() { - return; -} - -NPrimitiveNumber::NPrimitiveNumber(std::string str/*UNumberValue val, ENumberType type*/) { - // this->val = val; - // this->type = type; - this->str = str; - // double d = boost::lexical_cast(this->str); - double d = atof(this->str.c_str()); - if (this->str.find(".") != std::string::npos || this->str.find("E") != std::string::npos || this->str.find("E+") != std::string::npos || this->str.find("E-") != std::string::npos) { - if (FLT_MIN <= d && d <= FLT_MAX) { - this->type = eFLOAT; - this->val.f = (float) d; - } else { - this->type = eDOUBLE; - this->val.d = d; - } - return; - } - if (-1 << 7 <= d && d < 1 << 7) { - this->type = eBYTE; - this->val.b = (int8_t) d; - } else if (0 <= d && d < 1 << 8) { - this->type = eUBYTE; - this->val.ub = (uint8_t) d; - } else if (-1 << 15 <= d && d < 1 << 15) { - this->type = eSHORT; - this->val.s = (int16_t) d; - } else if (0 <= d && d < 1 << 16) { - this->type = eUSHORT; - this->val.us = (uint16_t) d; - } else if (-1 << 31 <= d && d < 1 << 31) { - this->type = eINT; - this->val.i = (int32_t) d; - } else if (0 <= d && d < 1UL << 32) { - this->type = eUINT; - this->val.ui = (uint32_t) d; - } else if (-1LL << 63 <= d && d < 1LL << 63) { - this->type = eLONG; - this->val.l = (int64_t) d; - } else if (0 <= d && d < (1ULL << 32) + ((1ULL << 32) - 1)) { - this->type = eULONG; - this->val.ul = (uint64_t) d; - } else if (FLT_MIN <= d && d <= FLT_MAX) { - this->type = eFLOAT; - this->val.f = (float) d; - } else if (DBL_MIN < d && d <= DBL_MAX) { - this->type = eDOUBLE; - this->val.d = (double) d; - } else { - std::cout << "Error parsing number." << std::endl; - this->type = eINT; - this->val.i = 0; - } -} - -NBinaryOperator::NBinaryOperator(EBinaryOperationType op, NExpression* lhs, NExpression* rhs) { - this->op = op; - this->lhs = lhs; - this->rhs = rhs; -} - -NBinaryOperator::~NBinaryOperator() { - delete this->lhs; - delete this->rhs; -} - -NPrimitiveNumber* NPrimitiveNumber::parse(std::string str) { - return new NPrimitiveNumber(str); -} - -NFunction::NFunction(NExpression* body) { - this->body = body; -} - -NFunction::~NFunction() { - delete this->body; -} - -NIdentifier::NIdentifier(std::string name) { - this->name = name; -} - -NAssignment::NAssignment(NIdentifier* lhs, NExpression* rhs) { - this->lhs = lhs; - this->rhs = rhs; -} - -NAssignment::~NAssignment() { - delete this->lhs; - delete this->rhs; -} - -NVariableDeclaration::NVariableDeclaration(NIdentifier* type, NIdentifier* var_name) { - this->type = type; - this->var_name = var_name; -} - -NVariableDeclaration::~NVariableDeclaration() { - delete this->type; - delete this->var_name; -} - -NBlock::NBlock() { - return; -} - -NPrimitiveNumber* NPrimitiveNumber_construct(UNumberValue val, ENumberType type) { - return new NPrimitiveNumber(""/*val, type*/); -} -void NPrimitiveNumber_destruct(NPrimitiveNumber* num) { - num->~NPrimitiveNumber(); -} \ No newline at end of file diff --git a/calc/node.h b/calc/node.h deleted file mode 100644 index 148ee16..0000000 --- a/calc/node.h +++ /dev/null @@ -1,100 +0,0 @@ -#ifndef __NODE_H_ -#define __NODE_H_ - -#include -#include -#include -#include "number.h" - -class CodeGen; -class NExpression; - -typedef enum tagEBinaryOperationType { - eMULTIPLY, - eADD, - eSUBTRACT, - eDIVIDE, - eRAISE, -} EBinaryOperationType; - -class Node { -public: - virtual ~Node(); - virtual llvm::Value* gen_code(CodeGen*) = 0; -}; - -class NExpression : public Node { -}; - -class NNumber : public NExpression { -}; - -class NPrimitiveNumber : public NNumber { -public: - //NPrimitiveNumber(UNumberValue, ENumberType); - NPrimitiveNumber(std::string str); - UNumberValue val; - ENumberType type; - std::string str; - virtual llvm::Value* gen_code(CodeGen*); - virtual ~NPrimitiveNumber(); - - static NPrimitiveNumber* parse(std::string); -}; - -class NBinaryOperator : public NExpression { -public: - EBinaryOperationType op; - NExpression* lhs; - NExpression* rhs; - NBinaryOperator(EBinaryOperationType, NExpression*, NExpression*); - virtual llvm::Value* gen_code(CodeGen*); - virtual ~NBinaryOperator(); -}; - -class NFunction : public NExpression { -public: - NExpression* body; - NFunction(NExpression*); - virtual llvm::Value* gen_code(CodeGen*); - virtual ~NFunction(); -}; - -class NIdentifier : public NExpression { -public: - std::string name; - NIdentifier(std::string); - virtual llvm::Value* gen_code(CodeGen*); -}; - -class NAssignment : public NExpression { -public: - NIdentifier* lhs; - NExpression* rhs; - NAssignment(NIdentifier*, NExpression*); - ~NAssignment(); - virtual llvm::Value* gen_code(CodeGen*); -}; - -class NVariableDeclaration : public NExpression { -public: - NIdentifier* type; - NIdentifier* var_name; - NVariableDeclaration(NIdentifier*, NIdentifier*); - ~NVariableDeclaration(); - virtual llvm::Value* gen_code(CodeGen*); -}; - -class NBlock : public NExpression { -public: - std::vector statements; - NBlock(); - virtual llvm::Value* gen_code(CodeGen*); -}; - -extern "C" { - NPrimitiveNumber* NPrimitiveNumber_construct(UNumberValue, ENumberType); - void NPrimitiveNumber_destruct(NPrimitiveNumber*); -} - -#endif // __NODE_H_ diff --git a/calc/number.cpp b/calc/number.cpp deleted file mode 100644 index a36b812..0000000 --- a/calc/number.cpp +++ /dev/null @@ -1,192 +0,0 @@ -#include "number.h" -#include -#include -#include - -static ENumberType primitive_number_normalized_type(ENumberType, ENumberType); -static double primitive_number_double_value(PrimitiveNumber*); -static int64_t primitive_number_long_value(PrimitiveNumber*); - -PrimitiveNumber::PrimitiveNumber(ENumberType type, UNumberValue val) { - this->type = type; - this->val = val; -} - -PrimitiveNumber::~PrimitiveNumber() { - return; -} - -Number* PrimitiveNumber::add(Number* y) { - PrimitiveNumber* pn = (PrimitiveNumber*) y;//dynamic_cast(y); - if (pn != NULL) { - ENumberType larger = primitive_number_normalized_type(this->type, pn->type); - if (larger == eLONG) { - int64_t x = primitive_number_long_value(this); - int64_t z = primitive_number_long_value(pn); - UNumberValue val; - val.l = x + z; - return new PrimitiveNumber(larger, val); - } else if (larger == eDOUBLE) { - double x = primitive_number_double_value(this); - double z = primitive_number_double_value(pn); - UNumberValue val; - val.d = x + z; - return new PrimitiveNumber(larger, val); - } - } - throw std::logic_error("Unhandled class"); - return NULL; -} - -Number* PrimitiveNumber::sub(Number* y) { - PrimitiveNumber* pn = dynamic_cast(y); - if (pn != NULL) { - ENumberType larger = primitive_number_normalized_type(this->type, pn->type); - if (larger == eLONG) { - int64_t x = primitive_number_long_value(this); - int64_t z = primitive_number_long_value(pn); - UNumberValue val; - val.l = x - z; - return new PrimitiveNumber(larger, val); - } else if (larger == eDOUBLE) { - double x = primitive_number_double_value(this); - double z = primitive_number_double_value(pn); - UNumberValue val; - val.d = x - z; - return new PrimitiveNumber(larger, val); - } - } - throw std::logic_error("Unhandled class"); - return NULL; -} - -Number* PrimitiveNumber::mul(Number* y) { - PrimitiveNumber* pn = dynamic_cast(y); - if (pn != NULL) { - ENumberType larger = primitive_number_normalized_type(this->type, pn->type); - if (larger == eLONG) { - int64_t x = primitive_number_long_value(this); - int64_t z = primitive_number_long_value(pn); - UNumberValue val; - val.f = x * z; - return new PrimitiveNumber(larger, val); - } else if (larger == eDOUBLE) { - double x = primitive_number_double_value(this); - double z = primitive_number_double_value(pn); - UNumberValue val; - val.d = x * z; - return new PrimitiveNumber(larger, val); - } - } - throw std::logic_error("Unhandled class"); - return NULL; -} - -Number* PrimitiveNumber::div(Number* y) { - PrimitiveNumber* pn = dynamic_cast(y); - if (pn != NULL) { - ENumberType larger = primitive_number_normalized_type(this->type, pn->type); - if (larger == eLONG) { - int64_t x = primitive_number_long_value(this); - int64_t z = primitive_number_long_value(pn); - UNumberValue val; - val.l = x / z; - return new PrimitiveNumber(larger, val); - } else if (larger == eDOUBLE) { - double x = primitive_number_double_value(this); - double z = primitive_number_double_value(pn); - UNumberValue val; - val.d = x / z; - return new PrimitiveNumber(larger, val); - } - } - throw std::logic_error("Unhandled class"); - return NULL; -} - -Number* PrimitiveNumber::pow(Number* y) { - PrimitiveNumber* pn = dynamic_cast(y); - if (pn != NULL) { - ENumberType larger = primitive_number_normalized_type(this->type, pn->type); - if (larger == eLONG) { - int64_t x = primitive_number_long_value(this); - int64_t z = primitive_number_long_value(pn); - UNumberValue val; - val.l = x + z; - return new PrimitiveNumber(larger, val); - } else if (larger == eDOUBLE) { - double x = primitive_number_double_value(this); - double z = primitive_number_double_value(pn); - UNumberValue val; - val.d = x + z; - return new PrimitiveNumber(larger, val); - } - } - throw std::logic_error("Unhandled class"); - return NULL; -} - -static ENumberType primitive_number_normalized_type(ENumberType a, ENumberType b) { - if (a == b) { - return a; - } - ENumberType larger = std::max(a, b); - if (larger < eLONG) { - return eLONG; - } - return eDOUBLE; -} - -static double primitive_number_double_value(PrimitiveNumber* x) { - switch (x->type) { - case eBYTE: - return (double) x->val.b; - case eUBYTE: - return (double) x->val.ub; - case eSHORT: - return (double) x->val.s; - case eUSHORT: - return (double) x->val.us; - case eINT: - return (double) x->val.i; - case eUINT: - return (double) x->val.ui; - case eLONG: - return (double) x->val.l; - case eULONG: - return (double) x->val.ul; - case eFLOAT: - return (double) x->val.f; - case eDOUBLE: - return x->val.d; - } - throw std::logic_error("Unhandled type"); - return 0; -} - -static int64_t primitive_number_long_value(PrimitiveNumber* x) { - switch (x->type) { - case eBYTE: - return (int64_t) x->val.b; - case eUBYTE: - return (int64_t) x->val.ub; - case eSHORT: - return (int64_t) x->val.s; - case eUSHORT: - return (int64_t) x->val.us; - case eINT: - return (int64_t) x->val.i; - case eUINT: - return (int64_t) x->val.ui; - case eLONG: - return (int64_t) x->val.l; - case eULONG: - return x->val.ul; - case eFLOAT: - return (int64_t) x->val.f; - case eDOUBLE: - return (int64_t) x->val.d; - } - throw std::logic_error("Unhandled type"); - return 0; -} diff --git a/calc/number.h b/calc/number.h deleted file mode 100644 index 3a415fc..0000000 --- a/calc/number.h +++ /dev/null @@ -1,83 +0,0 @@ -#ifndef __NUMBER_H_ -#define __NUMBER_H_ - -#include - -typedef union tagNumberValue { - int8_t b; - uint8_t ub; - int16_t s; - uint16_t us; - int32_t i; - uint32_t ui; - int64_t l; - uint64_t ul; - float f; - double d; -} UNumberValue; - -typedef enum tagNumberType { - eBYTE = 0, - eUBYTE = 1, - eSHORT = (1 << 1), - eUSHORT = (1 << 1) | 1, - eINT = (1 << 2), - eUINT = (1 << 2) | 1, - eLONG = (1 << 3), - eULONG = (1 << 3) | 1, - eFLOAT = (1 << 4), - eDOUBLE = (1 << 5), -} ENumberType; - -/* - * - primitive <-> primitive closed - * - primitive integral <-> bigint closed - * - number -> complex closed - * - rational <-> primitive closed - * - rational <-> bigint closed - * - * - byte -> short -> int -> long -> float -> double - * - anything -> complex - * - primitive -> rational - * - primitive -> bigint - * - rational <-> bigint (strong) - */ - -class Number { -public: - virtual Number* add(Number*) = 0; - virtual Number* sub(Number*) = 0; - virtual Number* mul(Number*) = 0; - virtual Number* div(Number*) = 0; - virtual Number* pow(Number*) = 0; -}; - -class PrimitiveNumber : Number { -public: - PrimitiveNumber(ENumberType, UNumberValue); - ~PrimitiveNumber(); - virtual Number* add(Number*) override; - virtual Number* sub(Number*) override; - virtual Number* mul(Number*) override; - virtual Number* div(Number*) override; - virtual Number* pow(Number*) override; - ENumberType type; - UNumberValue val; -}; - -class ComplexNumber : Number { -private: - Number* real; - Number* imag; -}; - -class RationalNumber : Number { -private: - -}; - -class BigIntNumber : Number { -private: -}; - -#endif // __NUMBER_H_ diff --git a/calc/parser.y b/calc/parser.y deleted file mode 100644 index 4fe5205..0000000 --- a/calc/parser.y +++ /dev/null @@ -1,104 +0,0 @@ -%{ - -#include "node.h" -#include "parser.hpp" -#include "lexer.h" -#include - -void yyerror(NExpression**, yyscan_t scanner, const char *s) { - fprintf(stderr, "YYERROR: %s!", s); -} - -NExpression* programBlock; - -%} - -%code requires { - -#ifndef YY_TYPEDEF_YY_SCANNER_T -#define YY_TYPEDEF_YY_SCANNER_T -typedef void* yyscan_t; -#endif - -} - -%define api.pure -%lex-param { yyscan_t scanner } -%parse-param { NExpression** expression } -%parse-param { yyscan_t scanner } - -%union { - Node* node; - NExpression* expr; - NBlock* block; - NIdentifier* identifier; - std::string* str; -} - -%left TOKEN_ADD TOKEN_SUBTRACT TOKEN_MULTIPLY TOKEN_DIVIDE TOKEN_RAISE - -%token TOKEN_LPAREN TOKEN_RPAREN TOKEN_SEMICOLON TOKEN_EQUALS -%token TOKEN_ADD TOKEN_MULTIPLY TOKEN_DIVIDE TOKEN_SUBTRACT TOKEN_RAISE -%token TOKEN_NUMBER TOKEN_IDENTIFIER - -%type program expr number_expr number_expr2 number_expr3 number_expr4 number assignment_expr variable_declaration_expr -%type stmts -%type identifier - -%start program - -%% - -program - : stmts { *expression = $1; } - ; - -stmts - : expr TOKEN_SEMICOLON { $$ = new NBlock(); $$->statements.push_back($1); } - | stmts expr TOKEN_SEMICOLON { $$->statements.push_back($2); } - -expr - : number_expr { $$ = $1; } - | assignment_expr { $$ = $1; } - | variable_declaration_expr { $$ = $1; } - ; - -identifier - : TOKEN_IDENTIFIER { $$ = new NIdentifier(*$1); delete $1; } - ; - -assignment_expr - : identifier TOKEN_EQUALS expr { $$ = new NAssignment($1, $3); } - ; - -variable_declaration_expr - : identifier identifier { $$ = new NVariableDeclaration($1, $2); } - | identifier identifier TOKEN_EQUALS expr { NBlock* block = new NBlock(); block->statements.push_back(new NVariableDeclaration($1, $2)); block->statements.push_back(new NAssignment($2, $4)); $$ = block; } - ; - -number_expr - : number_expr2 { $$ = $1; } - | number_expr TOKEN_ADD number_expr2 { $$ = new NBinaryOperator(eADD, $1, $3); } - | number_expr TOKEN_SUBTRACT number_expr2 { $$ = new NBinaryOperator(eSUBTRACT, $1, $3); } - ; - -number_expr2 - : number_expr3 { $$ = $1; } - | number_expr2 TOKEN_DIVIDE number_expr3 { $$ = new NBinaryOperator(eDIVIDE, $1, $3); } - | number_expr2 TOKEN_MULTIPLY number_expr3 { $$ = new NBinaryOperator(eMULTIPLY, $1, $3); } - ; - -number_expr3 - : number_expr4 { $$ = $1; } - | number_expr3 TOKEN_RAISE number_expr4 { $$ = new NBinaryOperator(eRAISE, $1, $3); } - ; - -number_expr4 - : number { $$ = $1; } - | identifier { $$ = $1; } - | TOKEN_LPAREN number_expr TOKEN_RPAREN { $$ = $2; } - ; - -number - : TOKEN_NUMBER { $$ = NPrimitiveNumber::parse(*$1); delete $1; } - ; \ No newline at end of file diff --git a/calc/playground.cpp b/calc/playground.cpp deleted file mode 100644 index ae35c9d..0000000 --- a/calc/playground.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#include -#include -#include - -void test_map_nonexisting_key() { - std::cout << "Testing map non-existing key" << std::endl; - std::map m; - std::cout << "Is: " << m["what"] << std::endl; -} - -void test_pointer_size() { - std::cout << "Testing pointer size" << std::endl; - std::cout << sizeof(int*) << std::endl; -} - -int main() { - test_map_nonexisting_key(); - test_pointer_size(); - return 0; -} diff --git a/calc/script.txt b/calc/script.txt deleted file mode 100644 index 0986c87..0000000 --- a/calc/script.txt +++ /dev/null @@ -1 +0,0 @@ -1 + 2 - 3 * 4 / 2 diff --git a/rpn_calc/.gitignore b/rpn_calc/.gitignore deleted file mode 100644 index b6e1bb4..0000000 --- a/rpn_calc/.gitignore +++ /dev/null @@ -1 +0,0 @@ -rpn_calc diff --git a/rpn_calc/Makefile b/rpn_calc/Makefile deleted file mode 100644 index 60d39ea..0000000 --- a/rpn_calc/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -FILES = lexer.c parser.c expression.cpp main.c number.cpp -CC = g++ -CFLAGS = -g -ansi - -lexer.c: lexer.l - flex lexer.l - -parser.c: parser.y lexer.c - bison parser.y - -build: $(FILES) - $(CC) $(CFLAGS) $(FILES) -o rpn_calc - -clean: - rm -f *.o *~ lexer.c lexer.h parser.c parser.h rpn_calc \ No newline at end of file diff --git a/rpn_calc/expression.cpp b/rpn_calc/expression.cpp deleted file mode 100644 index 6dd39a9..0000000 --- a/rpn_calc/expression.cpp +++ /dev/null @@ -1,74 +0,0 @@ -#include "expression.h" - -#include - -static SExpression* allocateExpression() { - SExpression* expr = (SExpression*) malloc(sizeof *expr); - if (expr == NULL) { - return NULL; - } - expr->type = eVALUE; - expr->value = 0; - expr->left = NULL; - expr->right = NULL; - expr->cdr = NULL; - return expr; -} - -SExpression* createNumber(int value) { - SExpression* expr = allocateExpression(); - if (expr == NULL) { - return NULL; - } - expr->type = eVALUE; - expr->value = value; - return expr; -} - -SExpression* createOperation(EOperationType type, SExpression* left, SExpression* right) { - SExpression* expr = allocateExpression(); - if (expr == NULL) { - return NULL; - } - expr->type = type; - expr->left = left; - expr->right = right; - return expr; -} - -void deleteExpression(SExpression* expr) { - if (expr == NULL) { - return; - } - deleteExpression(expr->left); - deleteExpression(expr->right); - if (expr->cdr != NULL) { - for (int i = 0; i < expr->cdr->size(); i++) { - deleteExpression((*(expr->cdr))[i]); - } - } - free(expr); -} - -SExpression* createVector(SExpression* car) { - SExpression* expr = allocateExpression(); - if (expr == NULL) { - return NULL; - } - std::vector* vec = new std::vector(); - if (vec == NULL) { - return NULL; - } - vec->push_back(car); - expr->type = eCDR; - expr->cdr = vec; - return expr; -} - -SExpression* appendVector(SExpression* expr, SExpression* vec) { - if (vec == NULL) { - return NULL; - } - vec->cdr->push_back(expr); - return vec; -} \ No newline at end of file diff --git a/rpn_calc/expression.h b/rpn_calc/expression.h deleted file mode 100644 index 5bd3d29..0000000 --- a/rpn_calc/expression.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef __EXPRESSION_H_ -#define __EXPRESSION_H_ - -#include - -typedef enum tagEOperationType { - eVALUE, - eMULTIPLY, - eADD, - eSUBTRACT, - eDIVIDE, - eCDR, -} EOperationType; - -typedef struct tagSExpression { - EOperationType type; - int value; - struct tagSExpression* left; - struct tagSExpression* right; - std::vector* cdr; -} SExpression; - -SExpression* createNumber(int value); - -SExpression* createOperation(EOperationType type, SExpression* left, SExpression* right); - -void deleteExpression(SExpression* expr); - -SExpression* createVector(SExpression* expr); - -SExpression* appendVector(SExpression* expr, SExpression* vec); - -#endif // __EXPRESSION_H_ \ No newline at end of file diff --git a/rpn_calc/lexer.l b/rpn_calc/lexer.l deleted file mode 100644 index 8b7959a..0000000 --- a/rpn_calc/lexer.l +++ /dev/null @@ -1,44 +0,0 @@ -%{ - -#include "expression.h" -#include "parser.h" -#include - -#define SAVE_TOKEN yyval.string = new std::string(yytext, yyleng) - -%} - -%option outfile="lexer.c" header-file="lexer.h" -%option reentrant noyywrap never-interactive nounistd -%option bison-bridge - -LPAREN "(" -RPAREN ")" -ADD "+" -MULTIPLY "*" -SUBTRACT "-" -DIVIDE "/" - -DIGIT [0-9] - -NUMBER {DIGIT}+ -WS [ \r\n\t]* - -%% - -{WS} { /* pass */ } -{NUMBER} { sscanf(yytext, "%d", &yylval->value); return TOKEN_NUMBER; } - -{MULTIPLY} { return TOKEN_MULTIPLY; } -{DIVIDE} { return TOKEN_DIVIDE; } -{ADD} { return TOKEN_ADD; } -{SUBTRACT} { return TOKEN_SUBTRACT; } -{LPAREN} { return TOKEN_LPAREN; } -{RPAREN} { return TOKEN_RPAREN; } - -%% - -int yyerror(const char* msg) { - fprintf(stderr, "Error: %s\n", msg); - return 0; -} \ No newline at end of file diff --git a/rpn_calc/main.c b/rpn_calc/main.c deleted file mode 100644 index 3b5850d..0000000 --- a/rpn_calc/main.c +++ /dev/null @@ -1,78 +0,0 @@ -#include "expression.h" -#include "parser.h" -#include "lexer.h" - -#include - -int yyparse(SExpression** expr, yyscan_t scanner); - -int evaluate(SExpression* expr); - -int add(int x, int y) { - return x + y; -} - -int subtract(int x, int y) { - return x - y; -} - -int multiply(int x, int y) { - return x * y; -} - -int divide(int x, int y) { - return x / y; -} - -int map(int (*fn)(int, int), SExpression* initial, std::vector* vec) { - int accumulator = evaluate(initial); - for (int i = 0; i < vec->size(); i++) { - accumulator = fn(accumulator, evaluate((*vec)[i])); - } - return accumulator; -} - -SExpression* getAST(const char* str) { - SExpression* expr = NULL; - yyscan_t scanner; - YY_BUFFER_STATE state; - if (yylex_init(&scanner)) { - return NULL; - } - state = yy_scan_string(str, scanner); - if (yyparse(&expr, scanner)) { - return NULL; - } - yy_delete_buffer(state, scanner); - yylex_destroy(scanner); - return expr; -} - -int evaluate(SExpression* expr) { - switch (expr->type) { - case eVALUE: - return expr->value; - case eMULTIPLY: - return map(&multiply, expr->left, expr->right->cdr); - case eADD: - return map(&add, expr->left, expr->right->cdr); - case eSUBTRACT: - return map(&subtract, expr->left, expr->right->cdr); - case eDIVIDE: - return map(÷, expr->left, expr->right->cdr); - default: - return 0; - } -} - -int main() { - SExpression* expr = NULL; - //char test[] = " (4 + 2*10 + 3*( 5 + 1 )) / (4 - 2) + 21"; - char test[] = " + 4 5 (- 7 5) (* 3 4) (/ 38 2)"; - //char test[] = "+ 4 5"; - expr = getAST(test); - int result = evaluate(expr); - printf("Result of '%s' is %d\n", test, result); - deleteExpression(expr); - return 0; -} \ No newline at end of file diff --git a/rpn_calc/number.cpp b/rpn_calc/number.cpp deleted file mode 100644 index 11b4292..0000000 --- a/rpn_calc/number.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "number.h" \ No newline at end of file diff --git a/rpn_calc/number.h b/rpn_calc/number.h deleted file mode 100644 index 49b5f87..0000000 --- a/rpn_calc/number.h +++ /dev/null @@ -1,75 +0,0 @@ -#ifndef __NUMBER_H_ -#define __NUMBER_H_ - -#include - -typedef union tagNumberValue { - int8_t b; - uint8_t ub; - int16_t is; - uint16_t us; - int32_t i; - uint32_t ui; - int64_t l; - uint64_t ul; - float f; - double d; -} UNumberValue; - -typedef enum tagNumberType { - eBYTE, - eUBYTE, - eSHORT, - eUSHORT, - eINT, - eUINT, - eLONG, - eULONG, - eFLOAT, - eDOUBLE, -} ENumberType; - -/* - * - primitive <-> primitive closed - * - primitive integral <-> bigint closed - * - number -> complex closed - * - rational <-> primitive closed - * - rational <-> bigint closed - * - * - byte -> short -> int -> long -> float -> double - * - anything -> complex - * - primitive -> rational - * - primitive -> bigint - * - rational <-> bigint (strong) - */ - -class Number { -public: - static virtual Number add(Number, Number); - static virtual Number subtract(Number, Number); - static virtual Number multiply(Number, Number); - static virtual Number divide(Number, Number); -} - -class PrimitiveNumber : Number { -private: - UNumberValue val; - ENumberType type; -} - -class ComplexNumber : Number { -private: - Number real; - Number imaginary; -} - -class RationalNumber : Number { -private: - -} - -class BigIntNumber : Number { - -} - -#endif // __NUMBER_H_ \ No newline at end of file diff --git a/rpn_calc/parser.y b/rpn_calc/parser.y deleted file mode 100644 index c8ff2e4..0000000 --- a/rpn_calc/parser.y +++ /dev/null @@ -1,75 +0,0 @@ -%{ - -#include "expression.h" -#include "parser.h" -#include "lexer.h" - -int yyerror(SExpression** expr, yyscan_t scanner, const char* msg) { - // error handling -} - -%} - -%code requires { - -#ifndef YY_TYPEDEF_YY_SCANNER_T -#define YY_TYPEDEF_YY_SCANNER_T -typedef void* yyscan_t; -#endif - -} - -%output "parser.c" -%defines "parser.h" - -%define api.pure -%lex-param { yyscan_t scanner } -%parse-param { SExpression** expression } -%parse-param { yyscan_t scanner } - -%union { - int value; - SExpression* expression; - SExpression* single_element; - SExpression* multiple_elements; -} - -%left '+' TOKEN_ADD -%left '*' TOKEN_MULTIPLY -%left '/' TOKEN_DIVIDE -%left '-' TOKEN_SUBTRACT - -%token TOKEN_LPAREN -%token TOKEN_RPAREN -%token TOKEN_ADD -%token TOKEN_MULTIPLY -%token TOKEN_DIVIDE -%token TOKEN_SUBTRACT -%token TOKEN_NUMBER - -%type expr -%type single_element -%type multiple_elements - -%% - -input - : expr { *expression = $1; } - ; - -expr - : TOKEN_ADD single_element multiple_elements { $$ = createOperation(eADD, $2, $3); } - | TOKEN_SUBTRACT single_element multiple_elements { $$ = createOperation(eSUBTRACT, $2, $3); } - | TOKEN_MULTIPLY single_element multiple_elements { $$ = createOperation(eMULTIPLY, $2, $3); } - | TOKEN_DIVIDE single_element multiple_elements { $$ = createOperation(eDIVIDE, $2, $3); } - ; - -single_element - : TOKEN_LPAREN expr TOKEN_RPAREN { $$ = $2; } - | TOKEN_NUMBER { $$ = createNumber($1); } - ; - -multiple_elements - : single_element multiple_elements { $$ = appendVector($1, $2); } - | single_element { $$ = createVector($1); } - ; \ No newline at end of file