private uint _tempBlockNum = 0; // used for constructing the sequence number jump table public override void ExitBlock([NotNull] FanucGCodeParser.BlockContext context) { if (context.sequenceNumber() != null) { _seqNumToBlockIdxMap[uint.Parse(context.sequenceNumber().DIGITS().GetText())] = _tempBlockNum; } _tempBlockNum++; base.ExitBlock(context); }
// Visit a gcode block public override object VisitBlock([NotNull] FanucGCodeParser.BlockContext context) { if (context.blockContent() == null) { return(null); // empty block (possibly with sequence number) } var statement = context.blockContent().statement(); var expr = context.blockContent().expr(); var comment = context.blockContent().comment(); // are we dealing with a statement, with a set of gcode addresses and parameter? if so, work out what the IMachineToolRuntime command should be, and execute it. // resolve sub-expressions to doubles or integers. error out if they can't be resolved to these. if (statement != null) { var gcodeStatement = statement.gcode(); if (gcodeStatement.Length > 0) { // build a map of gcode prefixes (note multiple codes may be specified in certain cases, eg multiple preparatory 'G' addresses) var gcodePrefixMap = new Dictionary <string, List <double> >(); foreach (var gcode in statement.gcode()) { var address = gcode.GCODE_PREFIX().GetText(); if (!gcodePrefixMap.ContainsKey(address)) { gcodePrefixMap[address] = new List <double>(); } var resolvedExpr = Visit(gcode.expr()); if (!resolvedExpr.IsNumeric()) { throw new GCodeException($"Cannot resolve {address} param to numeric type", _stack.Peek().Name, gcode.expr().Start.Line, gcode.expr().Start.Column); } gcodePrefixMap[address].Add((double)resolvedExpr); } // deal with preparatory codes first if (gcodePrefixMap.ContainsKey("G")) { var prepCodes = gcodePrefixMap["G"]; //... } // next get the feedrate if (gcodePrefixMap.ContainsKey("F")) { var feedrate = gcodePrefixMap["F"]; if (feedrate.Count > 1) { throw new GCodeException("Cannot specify multiple feedrates in a block", _stack.Peek().Name, context.Start.Line); } if (feedrate.Count() == 1) { try { Runtime.Feedrate = (int)feedrate.First(); } catch (Exception e) { throw new GCodeException("Could not adjust feedrate", _stack.Peek().Name, context.Start.Line, e); } } } // etc. add all the other possible codes, and then call Runtime methods } else { // it's a program flow control statement (IF, GOTO etc). // delegate to other rule handlers to carry out these actions Visit(statement); } } else if (expr != null) { // we have an expression (variable manipulation etc) // delegate to other rule handlers to carry out these actions Visit(expr); } if (comment != null) { // we're dealing with a comment. TRACE it out for a giggle. Debug.WriteLine(comment.CTRL_OUT_TEXT().GetText()); // TODO: if an alarm has been raised, this is the text for the alarm } return(null); }