import { PElementResult, PRuleResult } from './../parser/PObjectMap'; import ParserState from "./ParserState"; import IElementState from "./IElementState"; import RuleState from "./RuleState"; import { GElement } from "../parser/grammar/GRule"; import Assert from '@cafetextual/util/dist/src/assert/Assert'; export default class ElementState extends ParserState implements IElementState { constructor() { super() } // from parent stack parentRuleState:RuleState; isElementState():boolean { return true } // when multiplicity > 0, isFirst is used in determining when at least one element has matched isFirst():boolean { return this.parentRuleState.isFirst(); } // core state element:GElement; // recursing downwards childRuleState:RuleState; // result elementResult:PElementResult; childResult:PRuleResult; // intermediary processing state -- prefixProcessed:boolean = false; // token used in switching during recursion varStr:string = null; contentStart:number = -1; // these should be set directly on result contentEnd:number = -1; suffixStart:number = -1; // preserve across recursion static create(parentRuleState:RuleState):ElementState { var o:ElementState = new ElementState; o.elementResult = new PElementResult; o.parentRuleState = parentRuleState; o.element = parentRuleState.element; //o.isFirst = parentRuleState.isFirst(); o.p = parentRuleState.p; o.pos0 = parentRuleState.p.getPos(); o.line0 = parentRuleState.p.getCurrentLineIndex(); return o; } // create addErrorResult(estate:ElementState, element:GElement, valid:boolean = true, err:string = null, childResult:PRuleResult = null):void { Assert.assert(estate == this); Assert.assert(element == this.element); // Assert.assert(childResult == this.childResult) ? would be nice to assume this var e:PElementResult = null; e = estate.elementResult; e.element = element; e.valid = valid; e.err = err; // TODO - set this earlier // Assert.assert(e.childResult == childResult) e.childResult = childResult; e.startIndex = estate.pos0; e.startLineIndex = this.p.getCurrentLineIndex(); } // addErrorResult clone(fromCurrentElementState:any/*ElementState*/ = null, fromChildRuleState:any/*RuleState*/ = null, fromParentRuleState:any/*RuleState*/ = null, fromParentElementState:any/*ElementState*/ = null, stack:Array = null):ParserState { if (stack.indexOf(this) >= 0) { console.log("bug"); } stack.push(this); var es:ElementState = new ElementState; // ----- from superclass ----- es.rulePos0 = this.rulePos0; es.line0 = this.line0; es.pos0 = this.pos0; es.p = this.p; es.breakpoint = this.breakpoint; es.continueFn = this.continueFn; // ----- from superclass ---- if (fromParentRuleState) { es.parentRuleState = fromParentRuleState; } else { es.parentRuleState = this.parentRuleState.clone(es, null, null, null, stack) as RuleState; } es.element = this.element if (fromChildRuleState) { es.childRuleState = fromChildRuleState } else if (this.childRuleState) { es.childRuleState = this.childRuleState.clone(null, null, null, es, stack) as RuleState; } es.elementResult = this.elementResult; es.childResult = this.childResult; es.prefixProcessed = this.prefixProcessed; es.varStr = this.varStr; es.contentStart = this.contentStart; es.contentEnd = this.contentEnd; es.suffixStart = this.suffixStart; return es; } // clone eq(s:ElementState):boolean { var ok:boolean = true; ok = ok && this.parentRuleState.eq(s.parentRuleState); ok = ok && (this.element == s.element); return ok; } // eq setError(errCode:number, valid:boolean = true, err:string = null, childResult:PRuleResult = null):void { this.populateElement(this.elementResult, errCode, this, this.element, valid, err, childResult ); } // setError toTraceString():string { let {element} = this; return " + " + (element.tokenName ? element.tokenName : "") + "(" + (element.varName ? element.varName : "") + ")" + (element.childRuleName ? (":" + element.childRuleName) : "" ) + (element.multiplicity ? element.multiplicity : ""); } parent():ParserState { return this.parentRuleState; } showItem():string { let {element, elementResult} = this; return " + " + ( element ? element.tr() : " ") + ( (elementResult && elementResult.varStr) ? ( " = \"" + elementResult.varStr + "\"") : "") } } // class