view anagram/agcore/rule.cpp @ 21:1c9dac05d040

Add lint-style FALLTHROUGH annotations to fallthrough cases. (in the parse engine and thus the output code) Document this, because the old output causes warnings with gcc10.
author David A. Holland
date Mon, 13 Jun 2022 00:04:38 -0400 (2022-06-13)
parents 607e3be6bad8
children
line wrap: on
line source
/*
 * AnaGram, A System for Syntax Directed Programming
 * Copyright 1993-2002 Parsifal Software. All Rights Reserved.
 * See the file COPYING for license and usage terms.
 *
 * rule.cpp
 */

#include "agdict.h"
#include "config.h"
#include "data.h"
#include "error.h"
#include "q1glbl.h"
#include "rproc.h"
#include "rule.h"
#include "stacks.h"

//#define INCLUDE_LOGGING
#include "log.h"


Rule::Map map_form_number;
const int Rule::first = 1;

RuleDescriptor::RuleDescriptor()
  : line(0) , col(0)
  , proc_name(0)
  , non_vanishing_length(0)
  , op_bias(0)
  , precedence_level(0)
  , not_unique_reduction(0)
  , error_mask(0)
  , left_associative(0)
  , right_associative(0)
  , fast_loop(0)
  , immediate_proc(0)
  , lexical(0)
  , nonLexical(0)
  , reductionRequired(0)
{
  // Nothing to do
}

Rule::Rule() : ObjectRegister<RuleDescriptor>() {}
Rule::Rule(int x) : ObjectRegister<RuleDescriptor>(x) {}
Rule::Rule(const Rule &t) : ObjectRegister<RuleDescriptor>(t) {}
void Rule::operator = (const Rule &t) {
   ObjectRegister<RuleDescriptor>::operator = (t);
}

  
RuleDescriptor &Rule::Map::operator [] (unsigned x) {
  //LOGSECTION("RuleDescriptor::operator[]");
  //LOGV(x) LCV(Rule::descriptorList.size());
  assert(x < Rule::descriptorList.size());
  return Rule::descriptorList[x];
}

Rule Rule::create() {
  LOGSECTION("Rule::create");
  nforms = descriptorList.size();
  descriptorList.push(RuleDescriptor());
  Rule rule(nforms);
  LOGV(nforms) LCV(descriptorList.size());
  return rule;
}

void Rule::reset() {
  LOGSECTION("Rule::reset");
  descriptorList.reset();
  nforms = descriptorList.size();
  LOGV(nforms) LCV(descriptorList.size());
}

Token &RuleDescriptor::token(int x) {
  assert((unsigned) x < elementList.size());
  return elementList[x].token;
}

Token &Rule::token(int x) const {
  return descriptor->token(x);
}

AgStringDictionary cVariableList;
const int Cast::first = 1;
static AgString compareObject;

int treeCompare(AgStack<AgString> &descriptorList, const int &x, const int &y){
  LOGSECTION("treeCompare");
  const AgString &dx = 
    (unsigned) x < descriptorList.size() ? descriptorList[x] : compareObject;
  const AgString &dy = 
    (unsigned) y < descriptorList.size() ? descriptorList[y] : compareObject;
  int flag = dx < dy ? -1 : dy < dx;
  LOGV(x) LCV(y) LCV(flag);
  return flag;
}

CastDescriptor::CastDescriptor() : wrapper(0) {}
CastDescriptor::CastDescriptor(const char *s) : name(s), wrapper(0) {}

Cast::Cast() : KeyedObjectRegister<CastDescriptor>() {}
Cast::Cast(const int x) : KeyedObjectRegister<CastDescriptor>(x) {}

Cast::Cast(const char *s)
  : KeyedObjectRegister<CastDescriptor>(s)
{
  LOGSECTION("Cast::Cast(const char *)");
  LOGV(index) LCV(s);
#if 0 /* NOTUSED */
  compareObject = s;
  for (int i = 0; i < count(); i++) {
    LOGV(i) LCV(descriptorList[i]) LCV(descriptorList[i].size());
    int indexI = treeCompare(descriptorList, index, i);
    int iIndex = treeCompare(descriptorList, i, index);
    LOGV(indexI) LCV(iIndex);
  }
#endif
  // Nothing to do
}

Cast::Cast(const AgString s)
  : KeyedObjectRegister<CastDescriptor>(s.pointer())
{
#if 0 /* NOTUSED */
  LOGSECTION("Cast::Cast(const AgString)");
  LOGV(index) LCV(s);
  compareObject = s;
  for (int i = 0; i < count(); i++) {
    LOGV(i) LCV(descriptorList[i]) LCV(descriptorList[i].size());
    int indexI = treeCompare(descriptorList, index, i);
    int iIndex = treeCompare(descriptorList, i, index);
    LOGV(indexI) LCV(iIndex);
  }
#endif
  // Nothing to do
}

void Cast::reset() {
  KeyedObjectRegister<CastDescriptor>::reset();
  Cast nullCast = "";
  voidCast = Cast("void");
  intCast = Cast("int");
  longCast = Cast("long");
  nWrappers = 0;
#if 0 /* NOTUSED */
  for (unsigned i = 0; i < count(); i++) {
    LOGV(i) LCV(descriptorList[i]) LCV(descriptorList[i].size());
  }
#endif
  default_token_type = void_token_type = voidCast;
  default_input_type =  int_token_type = intCast;
  parser_stack_alignment = long_token_type = longCast;
  LOGV((int) voidCast) LCV((AgString)voidCast);
  LOGV((int) intCast) LCV((AgString)intCast);
  LOGV(default_token_type);
  LOGV(default_input_type);
  LOGV(int_token_type);
}

void Cast::requireWrapper() {
  if (index == default_token_type) {
    log_error("Cannot make wrapper for default token type");
    return;
  }
  nWrappers++;
  descriptor->wrapper = 1;
}

int Cast::wrapperRequired() {
  return descriptor->wrapper != 0;
}

Cast Cast::voidCast;
Cast Cast::intCast;
Cast Cast::longCast;
int Cast::nWrappers = 0;

Cast Cast::create() {
  LOGSECTION("Cast::create");
#if 0
  for (int i = 0; i < count(); i++) {
    LOGV(i) LCV(descriptorList[i]) LCV(descriptorList[i].size());
  }
#endif
  tss();
  Cast type = string_base;
  //char *string = string_base;
  LOGV(string_base) LCV(tis()) LCV((int) type) LCV((AgString)type);
  rcs();
#if 0
  for (int i = 0; i < count(); i++) {
    LOGV(i) LCV(descriptorList[i]) LCV(descriptorList[i].size());
  }
#endif

  return type;
}

int Cast::operator <(const Cast x) const {
  return *descriptor < *x.descriptor;
}

RuleElement::RuleElement(const Token &t, int x) : token(t), cVariable(x) {}

int RuleElement::operator < (const RuleElement x) const {
  if (token < x.token) return 1;
  if (x.token < token) return 0;
  return cVariable < x.cVariable;
}

VpRuleDescriptor::VpRuleDescriptor() : procedureName(0) {}
VpRuleDescriptor::VpRuleDescriptor(AgStack<RuleElement> &stack, int pn)
  : elementList(stack), procedureName(pn)
{
  // Nothing to do
}

int VpRuleDescriptor::operator < (const VpRuleDescriptor x) const {
  if (elementList < x.elementList) return 1;
  if (x.elementList < elementList) return 0;
  return procedureName < x.procedureName;
}

VpRule::VpRule() : KeyedObjectRegister<VpRuleDescriptor>() {}
VpRule::VpRule(const int x) : KeyedObjectRegister<VpRuleDescriptor>(x) {}
VpRule::VpRule(const VpRule &x) : KeyedObjectRegister<VpRuleDescriptor>(x) {}
VpRule::VpRule(AgStack<RuleElement> &stack, int pn)
  : KeyedObjectRegister<VpRuleDescriptor>(VpRuleDescriptor(stack, pn))
{
  // Nothing to do
}

void VpRule::reset() {
  KeyedObjectRegister<VpRuleDescriptor>::reset();
  AgStack<RuleElement> emptyStack;
  VpRule rule(emptyStack, 0);
}

Procedure::Procedure(const int x) : ObjectRegister<ProcedureDescriptor>(x) {}

Procedure::Procedure(const CSegment &t)
  : ObjectRegister<ProcedureDescriptor>(ProcedureDescriptor(t))
{
  LOGSECTION("Procedure::Procedure");
  LOGV(index);
  // Nothing to do
}

ProcedureDescriptor::ProcedureDescriptor()
  : cast(0)
  , alias(0)
  , line(0)
  , col(0)
  , form_number(0)
  , macro_flag(0)
  , value_flag(0)
{
  // Nothing to do
}

ProcedureDescriptor::ProcedureDescriptor(const CSegment &s)
  : cast(0)
  , alias(0)
  , line(0)
  , col(0)
  , form_number(0)
  , cSegment(s)
  , macro_flag(0)
  , value_flag(0)
{
  // Nothing to do
}

const int Procedure::first = 1;

void Procedure::reset() {
  LOGSECTION("Procedure::reset");
  descriptorList.reset();
  CSegment segment;
  segment.line = 0;
  segment.begin = segment.end = 0;
  Procedure nullProc(segment);
  LOGV(nullProc) LCV(descriptorList.size());
}

int Procedure::operator < (const Procedure p) const {
  return *descriptor < *p.descriptor;
}