Skip to content
Snippets Groups Projects
Commit ad02a143 authored by caisilus's avatar caisilus
Browse files

Solve module 8

parent f9e945b5
Branches master
No related merge requests found
Pipeline #5904 passed with warnings with stages
in 8 minutes and 9 seconds
......@@ -160,4 +160,34 @@ namespace ProgramTree
v.VisitIfNode(this);
}
}
public class WhileNode : StatementNode
{
public ExprNode Expr { get; set; }
public StatementNode Stat { get; set; }
public WhileNode(ExprNode expr, StatementNode stat)
{
Expr = expr;
Stat = stat;
}
public override void Visit(Visitor v)
{
v.VisitWhileNode(this);
}
}
public class RepeatNode : StatementNode
{
public ExprNode Expr { get; set; }
public BlockNode StList { get; set; }
public RepeatNode(ExprNode expr, BlockNode stat)
{
Expr = expr;
StList = stat;
}
public override void Visit(Visitor v)
{
v.VisitRepeatNode(this);
}
}
}
\ No newline at end of file
//
// This CSharp output file generated by Gardens Point LEX
// Gardens Point LEX (GPLEX) is Copyright (c) John Gough, QUT 2006-2014.
// Output produced by GPLEX is the property of the user.
// See accompanying file GPLEXcopyright.rtf.
//
// GPLEX Version: 1.2.2
// Machine: MAINHOMEPC2
// DateTime: 30.09.2018 18:23:21
// UserName: someone
// GPLEX input file <SimpleLex.lex - 30.09.2018 18:22:46>
// Version: 1.1.3.301
// Machine: DESKTOP-ROQ28NF
// DateTime: 13.11.2022 20:28:56
// UserName: caisilus
// GPLEX input file <SimpleLex.lex>
// GPLEX frame file <embedded resource>
//
// Option settings: unicode, parser, minimize
......@@ -17,8 +13,8 @@
//
//
// Revised backup code
// Version 1.2.1 of 24-June-2013
// Experimental embedded frame
// Version 1.1.3 of 18-April-2010
//
//
#define BACKUP
......@@ -127,8 +123,8 @@ namespace SimpleScanner
enum Result {accept, noMatch, contextFound};
const int maxAccept = 17;
const int initial = 18;
const int maxAccept = 18;
const int initial = 19;
const int eofNum = 0;
const int goStart = -1;
const int INITIAL = 0;
......@@ -165,24 +161,24 @@ namespace SimpleScanner
}
};
static int[] startState = new int[] {18, 0};
static int[] startState = new int[] {19, 0};
#region CompressedCharacterMap
//
// There are 15 equivalence classes
// There are 16 equivalence classes
// There are 2 character sequence regions
// There are 1 tables, 123 entries
// There are 1 runs, 0 singletons
// Decision tree depth is 1
//
static sbyte[] mapC0 = new sbyte[123] {
/* '\0' */ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 14, 14, 0, 14, 14,
/* '\x10' */ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
/* '\x20' */ 0, 14, 14, 14, 14, 14, 14, 14, 11, 12, 9, 8, 13, 7, 2, 10,
/* '0' */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 6, 14, 5, 14, 14,
/* '@' */ 14, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
/* 'P' */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 14, 14, 14, 14, 3,
/* '`' */ 14, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
/* '\0' */ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 0, 15, 15,
/* '\x10' */ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
/* '\x20' */ 0, 15, 15, 15, 15, 14, 15, 15, 11, 12, 9, 8, 13, 7, 2, 10,
/* '0' */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 6, 15, 5, 15, 15,
/* '@' */ 15, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
/* 'P' */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 15, 15, 15, 15, 3,
/* '`' */ 15, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
/* 'p' */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 };
static sbyte MapC(int code)
......@@ -190,20 +186,20 @@ namespace SimpleScanner
if (code < 123) // '\0' <= code <= 'z'
return mapC0[code - 0];
else // '{' <= code <= '\U0010FFFF'
return (sbyte)14;
return (sbyte)15;
}
#endregion
static Table[] NxS = new Table[20] {
static Table[] NxS = new Table[21] {
/* NxS[ 0] */ new Table(0, 0, 0, null),
/* NxS[ 1] */ new Table(1, 2, -1, new sbyte[] {1, 19}),
/* NxS[ 1] */ new Table(1, 2, -1, new sbyte[] {1, 20}),
/* NxS[ 2] */ new Table(0, 0, -1, null),
/* NxS[ 3] */ new Table(1, 3, -1, new sbyte[] {3, -1, 3}),
/* NxS[ 4] */ new Table(5, 1, -1, new sbyte[] {16}),
/* NxS[ 4] */ new Table(5, 1, -1, new sbyte[] {17}),
/* NxS[ 5] */ new Table(0, 0, -1, null),
/* NxS[ 6] */ new Table(5, 1, -1, new sbyte[] {15}),
/* NxS[ 7] */ new Table(5, 1, -1, new sbyte[] {14}),
/* NxS[ 8] */ new Table(5, 1, -1, new sbyte[] {13}),
/* NxS[ 6] */ new Table(5, 1, -1, new sbyte[] {16}),
/* NxS[ 7] */ new Table(5, 1, -1, new sbyte[] {15}),
/* NxS[ 8] */ new Table(5, 1, -1, new sbyte[] {14}),
/* NxS[ 9] */ new Table(0, 0, -1, null),
/* NxS[ 10] */ new Table(0, 0, -1, null),
/* NxS[ 11] */ new Table(0, 0, -1, null),
......@@ -212,10 +208,11 @@ namespace SimpleScanner
/* NxS[ 14] */ new Table(0, 0, -1, null),
/* NxS[ 15] */ new Table(0, 0, -1, null),
/* NxS[ 16] */ new Table(0, 0, -1, null),
/* NxS[ 17] */ new Table(1, 1, -1, new sbyte[] {17}),
/* NxS[ 18] */ new Table(1, 14, -1, new sbyte[] {1, 2, 3, 4, 2, 5,
6, 7, 8, 9, 10, 11, 12, 2}),
/* NxS[ 19] */ new Table(1, 1, -1, new sbyte[] {17}),
/* NxS[ 17] */ new Table(0, 0, -1, null),
/* NxS[ 18] */ new Table(1, 1, -1, new sbyte[] {18}),
/* NxS[ 19] */ new Table(1, 15, -1, new sbyte[] {1, 2, 3, 4, 2, 5,
6, 7, 8, 9, 10, 11, 12, 13, 2}),
/* NxS[ 20] */ new Table(1, 1, -1, new sbyte[] {18}),
};
int NextState() {
......@@ -225,7 +222,7 @@ int NextState() {
unchecked {
int rslt;
int idx = MapC(code) - NxS[state].min;
if (idx < 0) idx += 15;
if (idx < 0) idx += 16;
if ((uint)idx >= (uint)NxS[state].rng) rslt = NxS[state].dflt;
else rslt = NxS[state].nxt[idx];
return rslt;
......@@ -305,7 +302,8 @@ int NextState() {
public Scanner(Stream file, string codepage) {
SetSource(file, CodePageHandling.GetCodePage(codepage));
}
}
#endif // !NOFILES
public Scanner() { }
......@@ -333,7 +331,7 @@ int NextState() {
if (next < 0xDC00 || next > 0xDFFF)
code = ScanBuff.UnicodeReplacementChar;
else
code = (0x10000 + ((code & 0x3FF) << 10) + (next & 0x3FF));
code = (0x10000 + (code & 0x3FF << 10) + (next & 0x3FF));
}
#endif
cCol++;
......@@ -386,7 +384,9 @@ int NextState() {
GetCode();
}
#if !NOFILES
// ================ LineBuffer Initialization ===================
/// <summary>
/// Create and initialize a LineBuff buffer object for this scanner
/// </summary>
......@@ -400,7 +400,6 @@ int NextState() {
GetCode();
}
#if !NOFILES
// =============== StreamBuffer Initialization ==================
/// <summary>
......@@ -502,12 +501,6 @@ int NextState() {
}
}
/// <summary>
/// Discards all but the first "n" codepoints in the recognized pattern.
/// Resets the buffer position so that only n codepoints have been consumed;
/// yytext is also re-evaluated.
/// </summary>
/// <param name="n">The number of codepoints to consume</param>
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
void yyless(int n)
{
......@@ -527,10 +520,6 @@ int NextState() {
// but it does not seem possible to re-establish
// the correct column counts except by going forward.
//
/// <summary>
/// Removes the last "n" code points from the pattern.
/// </summary>
/// <param name="n">The number to remove</param>
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
void _yytrunc(int n) { yyless(yyleng - n); }
......@@ -543,23 +532,18 @@ int NextState() {
// can't use (tokEPos - tokPos) because of the
// possibility of surrogate pairs in the token.
//
/// <summary>
/// The length of the pattern in codepoints (not the same as
/// string-length if the pattern contains any surrogate pairs).
/// </summary>
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
[SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yyleng")]
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yyleng")]
public int yyleng
{
get {
#if BYTEMODE
return tokEPos - tokPos;
#else
if (tokELin == tokLin)
return tokECol - tokCol;
else
#if BYTEMODE
return tokEPos - tokPos;
#else
{
else {
int ch;
int count = 0;
int save = buffer.Pos;
......@@ -568,7 +552,7 @@ int NextState() {
ch = buffer.Read();
if (!char.IsHighSurrogate((char)ch)) count++;
} while (buffer.Pos < tokEPos && ch != ScanBuff.EndOfFile);
buffer.Pos = save;
buffer.Pos = save;
return count;
}
#endif // BYTEMODE
......@@ -593,56 +577,65 @@ int NextState() {
// ============== The main tokenizer code =================
int Scan() {
int Scan()
{
try {
for (; ; ) {
int next; // next state to enter
for (; ; )
{
int next; // next state to enter
#if BACKUP
Result rslt = Result.noMatch;
#endif // BACKUP
#if LEFTANCHORS
for (;;) {
for (;;)
{
// Discard characters that do not start any pattern.
// Must check the left anchor condition after *every* GetCode!
state = ((cCol == 0) ? anchorState[currentScOrd] : currentStart);
if ((next = NextState()) != goStart) break; // LOOP EXIT HERE...
if ((next = NextState()) != goStart)
break; // LOOP EXIT HERE...
GetCode();
}
#else // !LEFTANCHORS
state = currentStart;
while ((next = NextState()) == goStart) {
while ((next = NextState()) == goStart)
// At this point, the current character has no
// transition from the current state. We discard
// the "no-match" char. In traditional LEX such
// characters are echoed to the console.
GetCode();
}
#endif // LEFTANCHORS
// At last, a valid transition ...
MarkToken();
state = next;
GetCode();
GetCode();
while ((next = NextState()) > eofNum) // Exit for goStart AND for eofNum
#if BACKUP
bool contextSaved = false;
while ((next = NextState()) > eofNum) { // Exit for goStart AND for eofNum
if (state <= maxAccept && next > maxAccept) { // need to prepare backup data
// Store data for the *latest* accept state that was found.
SaveStateAndPos( ref ctx );
contextSaved = true;
if (state <= maxAccept && next > maxAccept) // need to prepare backup data
{
// ctx is an object. The fields may be
// mutated by the call to Recurse2.
// On return the data in ctx is the
// *latest* accept state that was found.
rslt = Recurse2(ref ctx, next);
if (rslt == Result.noMatch)
RestoreStateAndPos(ref ctx);
break;
}
state = next;
GetCode();
}
if (state > maxAccept && contextSaved)
RestoreStateAndPos( ref ctx );
#else // BACKUP
while ((next = NextState()) > eofNum) { // Exit for goStart AND for eofNum
state = next;
GetCode();
}
else
#endif // BACKUP
if (state <= maxAccept) {
{
state = next;
GetCode();
}
if (state <= maxAccept)
{
MarkEnd();
#region ActionSwitch
#pragma warning disable 162, 1522
#pragma warning disable 162
switch (state)
{
case eofNum:
......@@ -688,25 +681,28 @@ return (int)Tokens.RPAREN;
return (int)Tokens.COLUMN;
break;
case 13:
return (int)Tokens.ASSIGNMULT;
return (int)Tokens.MOD;
break;
case 14:
return (int)Tokens.ASSIGNPLUS;
return (int)Tokens.ASSIGNMULT;
break;
case 15:
return (int)Tokens.ASSIGNMINUS;
return (int)Tokens.ASSIGNPLUS;
break;
case 16:
return (int)Tokens.ASSIGN;
return (int)Tokens.ASSIGNMINUS;
break;
case 17:
return (int)Tokens.ASSIGN;
break;
case 18:
yylval.dVal = double.Parse(yytext);
return (int)Tokens.RNUM;
break;
default:
break;
}
#pragma warning restore 162, 1522
#pragma warning restore 162
#endregion
}
}
......@@ -719,7 +715,29 @@ yylloc = new LexLocation(tokLin, tokCol, tokELin, tokECol);
}
#if BACKUP
void SaveStateAndPos(ref Context ctx) {
Result Recurse2(ref Context ctx, int next)
{
// Assert: at entry "state" is an accept state AND
// NextState(state, code) != goStart AND
// NextState(state, code) is not an accept state.
//
SaveStateAndPos(ref ctx);
state = next;
GetCode();
while ((next = NextState()) > eofNum)
{
if (state <= maxAccept && next > maxAccept) // need to update backup data
SaveStateAndPos(ref ctx);
state = next;
if (state == eofNum) return Result.accept;
GetCode();
}
return (state <= maxAccept ? Result.accept : Result.noMatch);
}
void SaveStateAndPos(ref Context ctx)
{
ctx.bPos = buffer.Pos;
ctx.rPos = readPos;
ctx.cCol = cCol;
......@@ -728,7 +746,8 @@ yylloc = new LexLocation(tokLin, tokCol, tokELin, tokECol);
ctx.cChr = code;
}
void RestoreStateAndPos(ref Context ctx) {
void RestoreStateAndPos(ref Context ctx)
{
buffer.Pos = ctx.bPos;
readPos = ctx.rPos;
cCol = ctx.cCol;
......@@ -736,7 +755,8 @@ yylloc = new LexLocation(tokLin, tokCol, tokELin, tokECol);
state = ctx.state;
code = ctx.cChr;
}
#endif // BACKUP
#endif // BACKUP
// ============= End of the tokenizer code ================
......@@ -768,16 +788,16 @@ yylloc = new LexLocation(tokLin, tokCol, tokELin, tokECol);
#region UserCodeSection
public override void yyerror(string format, params object[] args) // îáðàáîòêà ñèíòàêñè÷åñêèõ îøèáîê
public override void yyerror(string format, params object[] args) //
{
var ww = args.Skip(1).Cast<string>().ToArray();
string errorMsg = string.Format("({0},{1}): Âñòðå÷åíî {2}, à îæèäàëîñü {3}", yyline, yycol, args[0], string.Join(" èëè ", ww));
string errorMsg = string.Format("({0},{1}): {2}, {3}", yyline, yycol, args[0], string.Join(" ", ww));
throw new SyntaxException(errorMsg);
}
public void LexError()
{
string errorMsg = string.Format("({0},{1}): Íåèçâåñòíûé ñèìâîë {2}", yyline, yycol, yytext);
string errorMsg = string.Format("({0},{1}): {2}", yyline, yycol, yytext);
throw new LexException(errorMsg);
}
......@@ -793,6 +813,13 @@ class ScannerHelper
keywords.Add("cycle",(int)Tokens.CYCLE);
keywords.Add("write",(int)Tokens.WRITE);
keywords.Add("var",(int)Tokens.VAR);
keywords.Add("if", (int)Tokens.IF);
keywords.Add("then", (int)Tokens.THEN);
keywords.Add("else", (int)Tokens.ELSE);
keywords.Add("while", (int)Tokens.WHILE);
keywords.Add("do", (int)Tokens.DO);
keywords.Add("repeat", (int)Tokens.REPEAT);
keywords.Add("until", (int)Tokens.UNTIL);
}
public static int GetIDToken(string s)
{
......@@ -853,7 +880,6 @@ class ScannerHelper
return new LineBuffer(source);
}
#if (!NOFILES)
public static ScanBuff GetBuffer(Stream source)
{
return new BuildBuffer(source);
......@@ -864,8 +890,7 @@ class ScannerHelper
{
return new BuildBuffer(source, fallbackCodePage);
}
#endif // !BYTEMODE
#endif // !NOFILES
#endif
}
#region Buffer classes
......@@ -988,7 +1013,7 @@ class ScannerHelper
{
ix = lstart = 0;
}
while (ix < numLines)
for (; ; )
{
int len = line[ix].Length + 1;
if (pos < lstart + len) break;
......@@ -1046,8 +1071,7 @@ class ScannerHelper
{
cPos = value;
findIndex(cPos, out cLine, out curLineStart);
// cLine should be the *next* line after curLine.
curLine = (cLine < numLines ? line[cLine++] : "");
curLine = line[cLine];
curLineEnd = curLineStart + curLine.Length;
}
}
......@@ -1055,7 +1079,7 @@ class ScannerHelper
public override string ToString() { return "LineBuffer"; }
}
#if (!NOFILES)
// ==============================================================
// ===== class BuildBuff : for unicode text files ========
// ==============================================================
......@@ -1296,13 +1320,12 @@ class ScannerHelper
}
#endif // !BYTEMODE
}
#endif // !NOFILES
#endregion Buffer classes
// ==============================================================
// ============ class CodePageHandling =============
// ==============================================================
#if (!NOFILES)
public static class CodePageHandling
{
public static int GetCodePage(string option)
......@@ -1513,7 +1536,6 @@ class ScannerHelper
#endif // !BYTEMODE
#endregion
#endif // !NOFILES
// End of code copied from embedded resource
......
......@@ -42,6 +42,7 @@ ID {Alpha}{AlphaDigit}*
"(" { return (int)Tokens.LPAREN; }
")" { return (int)Tokens.RPAREN; }
"," { return (int)Tokens.COLUMN; }
"%" { return (int)Tokens.MOD; }
[^ \r\n] {
LexError();
......@@ -78,6 +79,13 @@ class ScannerHelper
keywords.Add("cycle",(int)Tokens.CYCLE);
keywords.Add("write",(int)Tokens.WRITE);
keywords.Add("var",(int)Tokens.VAR);
keywords.Add("if", (int)Tokens.IF);
keywords.Add("then", (int)Tokens.THEN);
keywords.Add("else", (int)Tokens.ELSE);
keywords.Add("while", (int)Tokens.WHILE);
keywords.Add("do", (int)Tokens.DO);
keywords.Add("repeat", (int)Tokens.REPEAT);
keywords.Add("until", (int)Tokens.UNTIL);
}
public static int GetIDToken(string s)
{
......
This diff is collapsed.
......@@ -24,13 +24,13 @@
%start progr
%token BEGIN END CYCLE ASSIGN ASSIGNPLUS ASSIGNMINUS ASSIGNMULT SEMICOLON WRITE VAR PLUS MINUS MULT DIV LPAREN RPAREN COLUMN
%token BEGIN END CYCLE ASSIGN ASSIGNPLUS ASSIGNMINUS ASSIGNMULT SEMICOLON WRITE VAR PLUS MINUS MULT DIV LPAREN RPAREN COLUMN MOD IF THEN ELSE WHILE DO REPEAT UNTIL
%token <iVal> INUM
%token <dVal> RNUM
%token <sVal> ID
%type <eVal> expr ident T F
%type <stVal> statement assign block cycle write empty var varlist
%type <stVal> statement assign block cycle write empty var varlist if while repeat
%type <blVal> stlist block
%%
......@@ -55,6 +55,9 @@ statement: assign { $$ = $1; }
| write { $$ = $1; }
| var { $$ = $1; }
| empty { $$ = $1; }
| if { $$ = $1; }
| while { $$ = $1; }
| repeat { $$ = $1; }
;
empty : { $$ = new EmptyNode(); }
......@@ -79,6 +82,7 @@ expr : expr PLUS T { $$ = new BinOpNode($1,$3,'+'); }
T : T MULT F { $$ = new BinOpNode($1,$3,'*'); }
| T DIV F { $$ = new BinOpNode($1,$3,'/'); }
| T MOD F { $$ = new BinOpNode($1,$3,'%'); }
| F { $$ = $1; }
;
......@@ -92,6 +96,13 @@ block : BEGIN stlist END { $$ = $2; }
cycle : CYCLE expr statement { $$ = new CycleNode($2,$3); }
;
while : WHILE expr DO statement { $$ = new WhileNode($2, $4); }
;
repeat : REPEAT stlist UNTIL expr { $$ = new RepeatNode($4, $2); }
;
write : WRITE LPAREN expr RPAREN { $$ = new WriteNode($3); }
;
......@@ -115,5 +126,8 @@ varlist : ident
}
;
if : IF expr THEN statement { $$ = new IfNode($2, $4); }
| IF expr THEN statement ELSE statement { $$ = new IfNode($2, $4, $6); }
;
%%
......@@ -50,5 +50,17 @@ namespace SimpleLang.Visitors
cond.ifFalse.Visit(this);
}
}
public override void VisitWhileNode(WhileNode whileNode)
{
whileNode.Expr.Visit(this);
whileNode.Stat.Visit(this);
}
public override void VisitRepeatNode(RepeatNode repeatNode)
{
repeatNode.StList.Visit(this);
repeatNode.Expr.Visit(this);
}
}
}
......@@ -44,6 +44,9 @@ namespace SimpleLang.Visitors
case '/':
genc.Emit(OpCodes.Div);
break;
case '%':
genc.Emit(OpCodes.Rem);
break;
}
}
public override void VisitAssignNode(AssignNode a)
......@@ -94,6 +97,46 @@ namespace SimpleLang.Visitors
vars[v.Name] = genc.DeclareLocal(typeof(int));
}
public override void VisitIfNode(IfNode cond)
{
var elseLabel = genc.DefineLabel();
cond.expr.Visit(this);
genc.Emit(OpCodes.Ldc_I4_0);
genc.Emit(OpCodes.Beq, elseLabel);
cond.ifTrue.Visit(this);
genc.MarkLabel(elseLabel);
if (cond.ifFalse != null)
cond.ifFalse.Visit(this);
}
public override void VisitWhileNode(WhileNode whileNode)
{
var loopLabel = genc.DefineLabel();
var endLabel = genc.DefineLabel();
genc.MarkLabel(loopLabel);
whileNode.Expr.Visit(this);
genc.Emit(OpCodes.Ldc_I4_0);
genc.Emit(OpCodes.Beq, endLabel);
whileNode.Stat.Visit(this);
genc.Emit(OpCodes.Br, loopLabel);
genc.MarkLabel(endLabel);
}
public override void VisitRepeatNode(RepeatNode repeatNode)
{
var loopLabel = genc.DefineLabel();
var endLabel = genc.DefineLabel();
genc.MarkLabel(loopLabel);
repeatNode.StList.Visit(this);
repeatNode.Expr.Visit(this);
genc.Emit(OpCodes.Ldc_I4_0);
genc.Emit(OpCodes.Beq, endLabel);
genc.Emit(OpCodes.Br, loopLabel);
genc.MarkLabel(endLabel);
}
public void EndProgram()
{
genc.EndProgram();
......
......@@ -18,5 +18,7 @@ namespace SimpleLang.Visitors
public virtual void VisitVarDefNode(VarDefNode w) { }
public virtual void VisitEmptyNode(EmptyNode w) { }
public virtual void VisitIfNode(IfNode cond) { }
public virtual void VisitWhileNode(WhileNode whileNode) { }
public virtual void VisitRepeatNode(RepeatNode repeatNode) { }
}
}
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment