#ifndef __SCANNER_OPERATORPRECEDENCELIST_H #define __SCANNER_OPERATORPRECEDENCELIST_H /* 5D programming language Copyright (C) 2011 Danny Milosavljevic This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include <5D/Values> #include "Values/Values" #include "Values/Symbols" namespace Scanners { #define SIMPLE_APPLICATION /* DIY cons for no good reason. TODO change? */ struct OperatorPrecedenceItem : Values::Node { struct OperatorPrecedenceItem* next; Values::NodeT operator_; Values::NodeT associativity; OperatorPrecedenceItem(struct OperatorPrecedenceItem* next, Values::NodeT operator_, Values::NodeT associativity) { this->next = next; this->operator_ = operator_; this->associativity = associativity; } }; #define MAX_PRECEDENCE_LEVELS 37 struct LOperatorPrecedenceList : Values::Node { int apply_level; int minus_level; short prefix_usages[256]; struct OperatorPrecedenceItem* levels[MAX_PRECEDENCE_LEVELS]; LOperatorPrecedenceList(bool bInitDefaults = true); int get_operator_precedence(Values::NodeT symbol) const; int get_operator_precedence_and_associativity(Values::NodeT symbol, Values::NodeT& associativity_out) const; int empty_P(int precedence_level) { return(precedence_level >= MAX_PRECEDENCE_LEVELS || levels[precedence_level] == NULL); } /* for speed reasons, it can happen that the same operator is present multiple times on the same level. */ Values::NodeT match_operator(int precedence_level, Values::NodeT operator_, Values::NodeT& associativity_out, bool& B_visible_operator) const { B_visible_operator = true; if(precedence_level < 0 || precedence_level >= MAX_PRECEDENCE_LEVELS) return(NULL); struct OperatorPrecedenceItem* precedence = levels[precedence_level]; for(; precedence; precedence = precedence->next) { if(precedence->operator_ == operator_ || (precedence->operator_ == Symbols::Sspace /* apply */ && !any_operator_P(operator_) && operator_ && operator_ != Symbols::Srightparen && operator_ != Symbols::Srightbracket && operator_ != Symbols::Sautorightparen)) { if(precedence->operator_ != operator_) B_visible_operator = false; associativity_out = precedence->associativity; return(operator_); } } associativity_out = NULL; return(NULL); } bool any_operator_P(Values::NodeT thingie) const { if(!this) // if we don't have LOperatorPrecedenceList, no point in checking it return(false); return(symbol_P(thingie) && get_operator_precedence(thingie) != -1); } int next_precedence_level(int precedence_level) const { ++precedence_level; /* skip empty levels */ while(precedence_level >= 0 && precedence_level < MAX_PRECEDENCE_LEVELS && levels[precedence_level] == NULL) ++precedence_level; return(precedence_level); } void cons(int precedence_level, Values::NodeT operator_, Values::NodeT associativity); void uncons(int precedence_level, Values::NodeT operator_, Values::NodeT associativity); Values::NodeT get_all_operators(int precedence_level) const; // Cons bool prefix_operator_P(Values::NodeT thingie) const { /* should be: '\\- unary- let let! import NOT [ */ //if(thingie == Symbols::Sdash) { // return true; /* shoot me... */ { Values::NodeT associativity = NULL; return(get_operator_precedence_and_associativity(thingie, associativity) != -1 && associativity == Symbols::Sprefix); } } }; Scanners::LOperatorPrecedenceList* legacyOPLFrom5DOPL(Values::NodeT source); }; /* end namespace Scanners */ #endif /*ndef __SCANNER_OPERATORPRECEDENCELIST_H*/