@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

@@ -40,28 +41,50 @@ public void VisitChildren(AbstractNode node, String prefix)
};
}

private void PrintAttribute(AbstractNode node)
{
Console.ForegroundColor = ConsoleColor.DarkYellow;
//Console.Write(" *" + node.AttributesRef);
//Console.ForegroundColor = ConsoleColor.DarkGray;
//Console.WriteLine(" *" + node.TypeDescriptor);
if (node.AttributesRef != null)
{
Console.ForegroundColor = ConsoleColor.DarkGray;
Console.WriteLine(" " + node.AttributesRef);
}
else
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("\t" + node.TypeDescriptor);
}
Console.ResetColor();
}

public void VisitNode(AbstractNode node)
{
Console.WriteLine("<" + node.ClassName() + ">");
//Console.WriteLine("<" + node.ClassName() + ">");
Console.Write("<" + node.ClassName() + ">");
Console.ResetColor();
PrintAttribute(node);
}

public void VisitNode(Modifiers node)
{
Console.Write("<" + node.ClassName() + ">: ");
// Add code here to print Modifier info
var stringEnums = node.ModifierTokens.Select(x => x.ToString());
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine(string.Join(", ", stringEnums));
Console.Write(string.Join(", ", stringEnums));
Console.ResetColor();
PrintAttribute(node);
}

public void VisitNode(Identifier node)
{
Console.Write("<" + node.ClassName() + ">: ");
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine(node.ID);
Console.Write(node.ID);
Console.ResetColor();

PrintAttribute(node);
}

//public void VisitNode(PrimitiveType node)
@@ -76,56 +99,63 @@ public void VisitNode(PrimitiveTypeInt node)
{
Console.Write("<" + node.ClassName() + ">: ");
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("INT");
Console.Write("INT");
Console.ResetColor();
PrintAttribute(node);
}

public void VisitNode(PrimitiveTypeBoolean node)
{
Console.Write("<" + node.ClassName() + ">: ");
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("BOOLEAN");
Console.Write("BOOLEAN");
Console.ResetColor();
PrintAttribute(node);
}

public void VisitNode(PrimitiveTypeVoid node)
{
Console.Write("<" + node.ClassName() + ">: ");
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("VOID");
Console.Write("VOID");
Console.ResetColor();
PrintAttribute(node);
}

public void VisitNode(Expression node)
{
Console.Write("<" + node.ClassName() + ">: ");
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine(node.ExpressionType);
Console.Write(node.ExpressionType);
Console.ResetColor();
PrintAttribute(node);
}

public void VisitNode(SpecialName node)
{
Console.Write("<" + node.ClassName() + ">: ");
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine(node.Name);
Console.Write(node.Name);
Console.ResetColor();
PrintAttribute(node);
}

public void VisitNode(Literal node)
{
Console.Write("<" + node.ClassName() + ">: ");
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine(node.Lit);
Console.Write(node.Lit);
Console.ResetColor();
PrintAttribute(node);
}

public void VisitNode(Number node)
{
Console.Write("<" + node.ClassName() + ">: ");
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine(node.Num);
Console.Write(node.Num);
Console.ResetColor();
PrintAttribute(node);
}
}
}
@@ -67,7 +67,9 @@
<Compile Include="IVisitableNode.cs" />
<Compile Include="PrintVisitor.cs" />
<Compile Include="SemanticsVisitor.cs" />
<Compile Include="TopDeclVisitor.cs" />
<Compile Include="TypeDescriptor.cs" />
<Compile Include="TypeVisitor.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
@@ -1,28 +1,33 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Net.Configuration;
using System.Runtime.Remoting.Messaging;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
using ASTBuilder;

namespace Project3
{
class SemanticsVisitor : IReflectiveVisitor
public class SemanticsVisitor : IReflectiveVisitor
{
public static SymbolTable _symbolTable = new SymbolTable();
public static SymbolTable Table { get; set; }
public static ClassAttributes CurrentClass { get; set; }
public static MethodAttributes CurrentMethod { get; set; }

public SemanticsVisitor(SymbolTable st)
{
Table = st;
}

// This method is the key to implenting the Reflective Visitor pattern
// in C#, using the 'dynamic' type specification to accept any node type.
// The subsequent call to VisitNode does dynamic lookup to find the
// appropriate Version.

public virtual void Visit(dynamic node)
{
// TODO: switch statment to get to topDeclVisitor
this.VisitNode(node);
}

@@ -33,10 +38,7 @@ public void CheckSemantics(AbstractNode node)
{
return;
}
TopDeclVisitor topDeclVisitor = new TopDeclVisitor();
node.Accept(topDeclVisitor);
//node.Accept(this);
//VisitChildren(node);
node.Accept(this);
}

public void VisitChildren(AbstractNode node)
@@ -55,250 +57,4 @@ public void VisitNode(AbstractNode node)
VisitChildren(node);
}
}

class TopDeclVisitor : SemanticsVisitor
{
public override void Visit(dynamic node)
{
this.VisitNode(node);
}

private new void VisitNode(AbstractNode node)
{
Console.WriteLine("VisitNode, TopDeclVisitor [" + node.GetType() + "]");
VisitChildren(node);
}

private new void VisitChildren(AbstractNode node)
{
AbstractNode child = node.Child;
while (child != null)
{
child.Accept(this);
child = child.Sib;
}
}

// Variable List Declaring
private void VisitNode(LocalVariableDeclarationStatement node)
{
Console.WriteLine("LocalVariableDeclarationStatement node visit " +
"in TopDeclVisitor.");
TypeVisitor typeVisitor = new TypeVisitor();

AbstractNode typeSpecifier = node.Child;
AbstractNode localVariableDeclarators = typeSpecifier.Sib;

typeSpecifier.Accept(typeVisitor);

AbstractNode identifier = localVariableDeclarators.Child;
while (identifier != null)
{
string id = ((Identifier)identifier).ID;
if (_symbolTable.isDeclaredLocally(id))
{
identifier.TypeDescriptor = new ErrorDescriptor();
identifier.AttributesRef = null;
}
else
{
identifier.TypeDescriptor = typeSpecifier.TypeDescriptor;
VariableDeclarationAttributes attribute =
new VariableDeclarationAttributes();
attribute.TypeDescriptor = identifier.TypeDescriptor;
attribute.Kind = Kind.VariableAttributes;
attribute.Modifiers = null;
identifier.AttributesRef = attribute;
_symbolTable.enter(id, attribute);
Console.WriteLine("Entered into symbol table: " + id + " " + attribute);
}
identifier = identifier.Sib;
}
}

private void VisitNode(FieldVariableDeclaration node)
{
Console.WriteLine("FieldVariableDeclaration node visit " +
"in TopDeclVisitor");
TypeVisitor typeVisitor = new TypeVisitor();

AbstractNode modifiers = node.Child;
AbstractNode typeSpecifier = modifiers.Sib;
AbstractNode fieldVarDecls = typeSpecifier.Sib;

typeSpecifier.Accept(typeVisitor);

// add each identifier in the list to the symbol table
AbstractNode fieldVarDeclName = fieldVarDecls.Child;
while (fieldVarDeclName != null)
{
Identifier identifier = (Identifier)fieldVarDeclName.Child;
string id = identifier.ID;
// if declared locally, assign an error node
if (_symbolTable.isDeclaredLocally(id))
{
identifier.TypeDescriptor = new ErrorDescriptor();
identifier.AttributesRef = null;
}
else
{
identifier.TypeDescriptor = typeSpecifier.TypeDescriptor;
VariableDeclarationAttributes attribute = new VariableDeclarationAttributes();
attribute.TypeDescriptor = identifier.TypeDescriptor;
attribute.Kind = Kind.VariableAttributes;
attribute.Modifiers = ((Modifiers)modifiers).ModifierTokens;
identifier.AttributesRef = attribute;
_symbolTable.enter(id, attribute);
}
fieldVarDeclName = fieldVarDeclName.Sib;
}
VisitChildren(node);
}

// TypeDeclaring (n/a only for array and struct types)

// ClassDeclaring
private void VisitNode(ClassDeclaration node)
{
Console.WriteLine("ClassDeclaration node visit in TopDeclVisitor");

AbstractNode modifiers = node.Child;
AbstractNode identifier = modifiers.Sib;
AbstractNode classBody = identifier.Sib;

ClassTypeDescriptor typeRef = new ClassTypeDescriptor();
typeRef.ClassBody = new ScopeTable();
ClassAttributes attr = new ClassAttributes();
attr.TypeDescriptor = typeRef;
attr.Kind = Kind.ClassType;
string id = ((Identifier)identifier).ID;
_symbolTable.enter(id, attr);
CurrentClass = attr;

// push the class body scope table onto the symbol table stack
_symbolTable.openScope
(((ClassTypeDescriptor)attr.TypeDescriptor).ClassBody);

AbstractNode fieldDecls = classBody.Child;
if (fieldDecls == null) { return; } // grammar allows one class
AbstractNode fieldDecl = fieldDecls.Child;
while (fieldDecl != null)
{
if (fieldDecl is MethodDeclaration)
{
((MethodDeclaration)fieldDecl).Accept(this);
}
else if (fieldDecl is FieldVariableDeclaration)
{
((FieldVariableDeclaration)fieldDecl).Accept(this);
}
else
{
throw new ArgumentException("FieldDeclaration should be " +
"FieldVariableDeclaration or MethodDeclaration");
}
fieldDecl = fieldDecls.Sib;
}
_symbolTable.closeScope();
}

// MethodDeclaring
private void VisitNode(MethodDeclaration node)
{
AbstractNode modifiers = node.Child;
AbstractNode typeSpecifier = modifiers.Sib;
AbstractNode methodDeclarator = typeSpecifier.Sib;
AbstractNode methodBody = methodDeclarator.Sib;

TypeVisitor typeVisitor = new TypeVisitor();
if (typeSpecifier is PrimitiveTypeVoid)
{
((PrimitiveTypeVoid)typeSpecifier).Accept(typeVisitor);
}
else if (typeSpecifier is PrimitiveTypeBoolean)
{
((PrimitiveTypeBoolean)typeSpecifier).Accept(typeVisitor);
}
else if (typeSpecifier is PrimitiveTypeInt)
{
((PrimitiveTypeInt)typeSpecifier).Accept(typeVisitor);
}
else if (typeSpecifier is QualifiedName)
{
((QualifiedName)typeSpecifier).Accept(typeVisitor);
}
else
{
throw new ArgumentException("Return type of a method must " +
"be a PrimitiveType or QualifiedName");
}

MethodAttributes attr = new MethodAttributes();
attr.ReturnType = typeSpecifier.TypeDescriptor;
attr.Modifiers = ((Modifiers) modifiers).ModifierTokens;
attr.IsDefinedIn = CurrentClass;
attr.Locals = new ScopeTable();

AbstractNode methodDeclaratorName = methodDeclarator.Child;
AbstractNode parameterList = methodDeclaratorName.Sib;

string name = ((Identifier) methodDeclaratorName).ID;
_symbolTable.enter(name, attr);
_symbolTable.openScope(attr.Locals);
MethodAttributes oldCurrentMethod = CurrentMethod;

// YOU ARE HERE

}
}

class TypeVisitor : TopDeclVisitor
{
public override void Visit(dynamic node)
{
this.VisitNode(node);
}

private new void VisitNode(AbstractNode node)
{
Console.WriteLine("VisitNode, TypeVisitor [" + node.GetType() + "]");
VisitChildren(node);
}

// Identifier
private void VisitNode(Identifier node)
{
Console.WriteLine("Identifier node visit in TypeVisitor.");
Attributes attr = _symbolTable.lookup(node.ID);
if (attr != null && attr.Kind == Kind.TypeAttributes)
{
node.TypeDescriptor = attr.TypeDescriptor;
node.AttributesRef = attr;
}
else
{
node.TypeDescriptor = new ErrorDescriptor();
node.AttributesRef = null;
}
}

private void VisitNode(QualifiedName node)
{
Console.WriteLine("QualifiedName in TypeVisitor");
AbstractNode child = node.Child;
while (child != null)
{
Identifier identifier = (Identifier)child;
identifier.Accept(this);
node.TypeDescriptor = identifier.TypeDescriptor;
child = child.Sib;
}
}

// ArrayDefining

// Struct Defining

// EnumDefining
}
}
@@ -19,10 +19,7 @@ public SymbolTable()
public void openScope()
{
nestLevel++;
while (symbolTable.Count <= nestLevel)
{
symbolTable.Push(new ScopeTable());
}
symbolTable.Push(new ScopeTable());
setBaseline();
}

@@ -37,13 +34,39 @@ private void setBaseline()
{
ScopeTable currScopeTable = symbolTable.Pop();
// Until given additional info, Java objects are placeholders
GeneralAttributes javaAttr =
GeneralAttributes javaAttr =
new GeneralAttributes(new JavaObjectDescriptor());
javaAttr.Kind = Kind.TypeAttributes;
currScopeTable.Add("java", javaAttr);
currScopeTable.Add("java", javaAttr);
currScopeTable.Add("io", javaAttr);
currScopeTable.Add("lang", javaAttr);
currScopeTable.Add("System", javaAttr);
currScopeTable.Add("out", javaAttr);
currScopeTable.Add("print", javaAttr);
currScopeTable.Add("outint", javaAttr);
currScopeTable.Add("PrintStream", javaAttr);
currScopeTable.Add("TestClasses", javaAttr);
currScopeTable.Add("WriteLine", javaAttr);

// primitive types
PrimitiveAttributes primVoidAttrs =
new PrimitiveAttributes(PrimitiveTypes.VOID);
currScopeTable.Add(primVoidAttrs.Name(), primVoidAttrs);
PrimitiveAttributes primIntAttrs =
new PrimitiveAttributes(PrimitiveTypes.INT);
currScopeTable.Add(primIntAttrs.Name(), primIntAttrs);
PrimitiveAttributes primBooleanAttrs =
new PrimitiveAttributes(PrimitiveTypes.BOOLEAN);
currScopeTable.Add(primBooleanAttrs.Name(), primBooleanAttrs);

// special names
SpecialNameAttributes spNameThis = new SpecialNameAttributes
(SpecialNameEnums.THIS);
currScopeTable.Add(spNameThis.Name, spNameThis);
SpecialNameAttributes spNameNull = new SpecialNameAttributes(
SpecialNameEnums.NULL);
currScopeTable.Add(spNameNull.Name, spNameNull);


// TODO: add additional baseline information

@@ -96,7 +119,7 @@ public bool isDeclaredLocally(string id)

public class ScopeTable
{
readonly Dictionary<string, Attributes> _thisScope =
readonly Dictionary<string, Attributes> _thisScope =
new Dictionary<string, Attributes>();

// adds a key/value pair to the symbol table at this scope
@@ -129,7 +152,7 @@ public bool Contains(string key)
// returns a copy of the ScopeTable as a dictionary
public Dictionary<string, Attributes> GetCopy()
{
return _thisScope.ToDictionary(entry => entry.Key,
return _thisScope.ToDictionary(entry => entry.Key,
entry => entry.Value);
}
}
@@ -4,9 +4,9 @@

// GPPG version 1.5.2
// Machine: HPERSIMMON
// DateTime: 5/21/2017 12:56:27 PM
// DateTime: 5/25/2017 4:14:36 PM
// UserName: amgrieco
// Input file <TCCL.grammar.y - 5/21/2017 12:56:26 PM>
// Input file <TCCL.grammar.y - 5/25/2017 4:14:32 PM>

// options: no-lines gplex

@@ -52,8 +52,8 @@ public class ScanObj {
[GeneratedCodeAttribute( "Gardens Point Parser Generator", "1.5.2")]
public partial class TCCLParser: ShiftReduceParser<AbstractNode, LexLocation>
{
// Verbatim content from TCCL.grammar.y - 5/21/2017 12:56:26 PM
// End verbatim content from TCCL.grammar.y - 5/21/2017 12:56:26 PM
// Verbatim content from TCCL.grammar.y - 5/25/2017 4:14:32 PM
// End verbatim content from TCCL.grammar.y - 5/25/2017 4:14:32 PM

#pragma warning disable 649
private static Dictionary<int, string> aliases;
@@ -19,15 +19,15 @@ public void Parse(string filename)
this.Parse();
PrintTree();
DoSemantics();
//PrintTree();
PrintTree();
}
public void Parse(Stream strm)
{
this.Scanner = new TCCLScanner(strm);
this.Parse();
PrintTree();
DoSemantics();
//PrintTree();
PrintTree();
}
public void PrintTree()
{
@@ -38,9 +38,15 @@ public void PrintTree()

public void DoSemantics()
{
SemanticsVisitor visitor = new SemanticsVisitor();
SymbolTable symbolTable = new SymbolTable();

TopDeclVisitor topDeclVisitor = new TopDeclVisitor(symbolTable);
Console.WriteLine("Starting declarations processing");
topDeclVisitor.CheckSemantics(CurrentSemanticValue);

SemanticsVisitor semanticsVisitor = new SemanticsVisitor(symbolTable);
Console.WriteLine("Starting semantic checking");
visitor.CheckSemantics(CurrentSemanticValue);
semanticsVisitor.CheckSemantics(CurrentSemanticValue);

}

@@ -6,7 +6,7 @@
//
// GPLEX Version: 1.2.2
// Machine: HPERSIMMON
// DateTime: 5/21/2017 12:56:27 PM
// DateTime: 5/25/2017 4:14:36 PM
// UserName: amgrieco
// GPLEX input file <TCCL.analyzer.lex - 5/19/2017 12:58:39 PM>
// GPLEX frame file <embedded resource>
@@ -216,7 +216,7 @@ Expression : QualifiedName EQUALS Expression { $$ = new Expression($1, Expre
| Expression RSLASH Expression { $$ = new Expression($1, ExpressionEnums.RSLASH, $3); }
| Expression PERCENT Expression { $$ = new Expression($1, ExpressionEnums.PERCENT, $3); } /* remainder */
| ArithmeticUnaryOperator Expression %prec UNARY { $$ = new Expression($1, $2, yytext, ExpressionEnums.UNARY); } // TODO: fix me
| PrimaryExpression { $$ = $1; } // TODO: fix me
| PrimaryExpression { $$ = $1; } //{ $$ = new Expression($1); } // TODO: fix me
;

ArithmeticUnaryOperator : PLUSOP { $$ = new ArithmeticUnaryOperator(ExpressionEnums.PLUSOP); }
@@ -0,0 +1,15 @@
/*Tests calls to Writeline with a string */
/* Calls WriteLine with integers */

public void main ()
{
int w,x;
x = 3+4;
Write("Value of x = ");
WriteLine(x);
w = x-5;
Write("Value of w = ");
WriteLine(w);
Write("value of big expression =");
WriteLine(w*x+(12/w));
}
@@ -0,0 +1,6 @@
/*Tests calls to Writeline with a string */

public void main ()
{
WriteLine("Hello, World");
}
@@ -0,0 +1,15 @@
/* Tests simple comparisons and if statements */

public static void main() {
int i, j;
i = 0;
j = 1;
WriteLine("TCCL if test");
if ( i < 10 )
WriteLine("In then part");
else i = j;
if ( i == 10 ) j = i;
else WriteLine("In else part");
}


@@ -0,0 +1,14 @@
/* Computes factorials: tests method calls, while, assignment */

public static void main() {
int i, gobble;
i = 0;
gobble = 1;
WriteLine ("Beginning loop test");
while ( i < 10) {
WriteLine (gobble);
i = i + 1;
gobble = gobble * i;
}
}

@@ -0,0 +1,13 @@
/* Tests calls to methods with no parameters */


public static void check ()
{
WriteLine("In the check method");
}

public static void main ()
{
check();
WriteLine("Back in main");
}
@@ -0,0 +1,14 @@
/* Tests calls to methods with one parameter */


public void check (int x)
{
Write("The argument to check was ");
WriteLine(x);
}

public void main ()
{
check(12345);
WriteLine("Back in main");
}
@@ -0,0 +1,9 @@
/* Tests calls to Write with integers and */
/* computation with constants */

public void main ()
{
WriteLine(5);
WriteLine(5*2+6/4);
}

@@ -0,0 +1,18 @@
/*Tests calls to Writeline with a string */
/* Calls WriteLine with integers */

public class compute {

public void main ()
{
int w,x;
x = 3+4;
Write("Value of x = ");
WriteLine(x);
w = x-5;
Write("Value of w = ");
WriteLine(w);
Write("value of big expression =");
WriteLine(w*x+(12/w));
}
}
@@ -0,0 +1,24 @@
/*Tests for handling undeclared variables and erroneous use of */
/* strings and booleans */

public class compute {

public void main ()
{
int w,x;
x = 3 + 4;
w = x * x;
WriteLine("Trying to use undeclared variables");
x = y + 4;
z = x / w + 1;
WriteLine("Trying to use a string as an operand");
w = x - "5";
WriteLine("Trying to use a boolean as an arithmetic operand");
w = x * (x < 0);
WriteLine("Trying to assign a string to a variable");
x = "a string";
WriteLine("Trying to assign a boolean to a variable");
x = w > 5;

}
}
@@ -0,0 +1,9 @@
/*Tests calls to Writeline with a string */

public class hello {

public void main ()
{
WriteLine("Hello, World");
}
}
@@ -0,0 +1,17 @@
/* Tests simple comparisons and if statements */

public class iftest {

public static void main() {
int i, j;
i = 0;
j = 1;
WriteLine("TCCL if test");
if ( i < 10 )
WriteLine("In then part");
else i = j;
if ( i == 10 ) j = i;
else WriteLine("In else part");
}
}

@@ -0,0 +1,16 @@
/* Computes factorials: tests method calls, while, assignment */

public class loop {

public static void main() {
int i, gobble;
i = 0;
gobble = 1;
WriteLine ("Beginning loop test");
while ( i < 10) {
WriteLine (gobble);
i = i + 1;
gobble = gobble * i;
}
}
}
@@ -0,0 +1,15 @@
/* Tests calls to methods with no parameters */

public class twomethods0 {

public static void check ()
{
WriteLine("In the check method");
}

public static void main ()
{
check();
WriteLine("Back in main");
}
}
@@ -0,0 +1,16 @@
/* Tests calls to methods with one parameter */

public class twomethods1 {

public void check (int x)
{
Write("The argument to check was ");
WriteLine(x);
}

public void main ()
{
check(12345);
WriteLine("Back in main");
}
}
@@ -0,0 +1,11 @@
/* Tests calls to Write with integers and */
/* computation with constants */

public class writenums {

public void main ()
{
WriteLine(5);
WriteLine(5*2+6/4);
}
}
@@ -0,0 +1,309 @@
using System;
using System.Collections.Generic;

namespace Project3
{
public class TopDeclVisitor : SemanticsVisitor
{
public TypeVisitor TypeVisitor { get; set; }

public TopDeclVisitor(SymbolTable st) : base(st)
{
TypeVisitor = new TypeVisitor(st);
}

public override void Visit(dynamic node)
{
this.VisitNode(node);
}

private new void VisitNode(AbstractNode node)
{
Console.WriteLine("VisitNode, TopDeclVisitor [" + node.GetType() + "]");
VisitChildren(node);
}

private new void VisitChildren(AbstractNode node)
{
AbstractNode child = node.Child;
while (child != null)
{
child.Accept(this);
child = child.Sib;
}
}

// Variable List Declaring
private void VisitNode(LocalVariableDeclarationStatement node)
{
Console.WriteLine("LocalVariableDeclarationStatement node visit " +
"in TopDeclVisitor.");

AbstractNode typeSpecifier = node.Child;
AbstractNode localVariableDeclarators = typeSpecifier.Sib;


typeSpecifier.Accept(TypeVisitor);
TypeDescriptor declType = typeSpecifier.TypeDescriptor;

AbstractNode identifier = localVariableDeclarators.Child;
while (identifier != null)
{
Identifier id = (Identifier)identifier;
if (Table.isDeclaredLocally(id.ID))
{
string message = "Symbol table already contains id: " + id.ID;
Console.WriteLine(message); // TODO: delete
id.TypeDescriptor = new ErrorDescriptor();
((ErrorDescriptor)identifier.TypeDescriptor).Message = message;
id.AttributesRef = null;
}
else
{
VariableDeclarationAttributes attr =
new VariableDeclarationAttributes();
attr.Kind = Kind.VariableAttributes;
attr.TypeDescriptor = declType;
attr.Modifiers = null;
Table.enter(id.ID, attr);
Console.WriteLine("Entered into symbol table: " + id.ID +
" " + attr); // TODO: DELETE
id.TypeDescriptor = declType;
id.AttributesRef = attr;
}
identifier = identifier.Sib;
}
}

private void VisitNode(FieldVariableDeclaration node)
{
Console.WriteLine("FieldVariableDeclaration node visit " +
"in TopDeclVisitor");

AbstractNode modifiers = node.Child;
AbstractNode typeSpecifier = modifiers.Sib;
AbstractNode fieldVarDecls = typeSpecifier.Sib;

typeSpecifier.Accept(TypeVisitor);

TypeDescriptor declType = typeSpecifier.TypeDescriptor;
List<ModifiersEnums> modifiersList = ((Modifiers)modifiers).ModifierTokens;

// note: grammar does not allow initialization here, only declaration
// add each identifier in the list to the symbol table
AbstractNode fieldVarDeclName = fieldVarDecls.Child;
while (fieldVarDeclName != null)
{
Identifier identifier = fieldVarDeclName.Child as Identifier;
if (identifier == null) throw new ArgumentNullException(nameof(identifier));
string id = identifier.ID;
// if declared locally, assign an error node
if (Table.isDeclaredLocally(id))
{
string message = "Variable name cannot be redeclared: " + id;
Console.WriteLine(message); // TODO: delete
identifier.TypeDescriptor = new ErrorDescriptor();
((ErrorDescriptor)identifier.TypeDescriptor).Message = message;
identifier.AttributesRef = null;
}
else
{
VariableDeclarationAttributes attr =
new VariableDeclarationAttributes();
attr.Kind = Kind.VariableAttributes;
attr.TypeDescriptor = identifier.TypeDescriptor;
attr.Modifiers = modifiersList;
Table.enter(id, attr);
Console.WriteLine("Entered into symbol table: " + id +
" " + attr); // TODO: DELETE
identifier.TypeDescriptor = declType;
identifier.AttributesRef = attr;
}
fieldVarDeclName = fieldVarDeclName.Sib;
}
VisitChildren(node);
}

// TypeDeclaring (n/a only for array and struct types)

// ClassDeclaring
private void VisitNode(ClassDeclaration node)
{
Console.WriteLine("ClassDeclaration node visit in TopDeclVisitor");

AbstractNode modifiers = node.Child;
AbstractNode identifier = modifiers.Sib;
AbstractNode classBody = identifier.Sib;

ClassTypeDescriptor typeRef = new ClassTypeDescriptor();
typeRef.ClassBody = new ScopeTable();
ClassAttributes attr = new ClassAttributes();
attr.Kind = Kind.ClassType;
attr.TypeDescriptor = typeRef;
string id = ((Identifier)identifier).ID;
Table.enter(id, attr);
CurrentClass = attr;
node.TypeDescriptor = typeRef; // TODO: check if needed
node.AttributesRef = attr; // (not included in pseudocode)

// push the class body scope table onto the symbol table stack
Table.openScope
(((ClassTypeDescriptor)attr.TypeDescriptor).ClassBody);

AbstractNode fieldDecls = classBody.Child;
if (fieldDecls == null)
{
return;
} // grammar allows one class: so if
// body is empty, parsing complete
AbstractNode fieldDecl = fieldDecls.Child;
while (fieldDecl != null)
{
if (fieldDecl is MethodDeclaration)
{
((MethodDeclaration)fieldDecl).Accept(this);
}
else if (fieldDecl is FieldVariableDeclaration)
{
((FieldVariableDeclaration)fieldDecl).Accept(this);
}
else
{
throw new ArgumentException("FieldDeclaration should be " +
"FieldVariableDeclaration or MethodDeclaration");
}
fieldDecl = fieldDecls.Sib;
}
Table.closeScope();
CurrentClass = null;
}

// MethodDeclaring
private void VisitNode(MethodDeclaration node)
{
AbstractNode modifiers = node.Child;
AbstractNode typeSpecifier = modifiers.Sib;
AbstractNode methodDeclarator = typeSpecifier.Sib;
AbstractNode methodBody = methodDeclarator.Sib;

if (typeSpecifier is PrimitiveTypeVoid)
{
((PrimitiveTypeVoid)typeSpecifier).Accept(TypeVisitor);
}
else if (typeSpecifier is PrimitiveTypeBoolean)
{
((PrimitiveTypeBoolean)typeSpecifier).Accept(TypeVisitor);
}
else if (typeSpecifier is PrimitiveTypeInt)
{
((PrimitiveTypeInt)typeSpecifier).Accept(TypeVisitor);
}
else if (typeSpecifier is QualifiedName)
{
((QualifiedName)typeSpecifier).Accept(TypeVisitor);
}
else
{
throw new ArgumentException("Return type of a method must " +
"be a PrimitiveType or QualifiedName");
}

MethodAttributes attr = new MethodAttributes();
attr.TypeDescriptor = new MethodTypeDescriptor();
//TODO: method doesn't seem to need or use a type descriptor
attr.ReturnType = typeSpecifier.TypeDescriptor;
attr.Modifiers = ((Modifiers)modifiers).ModifierTokens;
attr.IsDefinedIn = CurrentClass;
attr.Locals = new ScopeTable();

AbstractNode methodDeclaratorName = methodDeclarator.Child;
AbstractNode parameterList = methodDeclaratorName.Sib; // may be null

string name = ((Identifier)methodDeclaratorName).ID;
Table.enter(name, attr);
node.TypeDescriptor = attr.TypeDescriptor;
node.AttributesRef = attr;

Table.openScope(attr.Locals);
MethodAttributes oldCurrentMethod = CurrentMethod;
CurrentMethod = attr;
if (parameterList != null)
{
// signature = parameter types + return value
parameterList.Accept(this);
attr.Signature = ((ParameterList)parameterList).
AddReturnToSignature(attr.ReturnType);
}
else
{
// signature = return value only
attr.Signature = new Signature(attr.ReturnType);
}
methodBody.Accept(this);
CurrentMethod = oldCurrentMethod;
Table.closeScope();
}

private void VisitNode(Parameter node)
{
AbstractNode typeSpecifier = node.Child;
AbstractNode identifier = typeSpecifier.Sib;

typeSpecifier.Accept(TypeVisitor);
TypeDescriptor declType = typeSpecifier.TypeDescriptor;

string id = ((Identifier)identifier).ID;
if (Table.isDeclaredLocally(id))
{
string message = "Symbol table already contains id: " + id;
Console.WriteLine(message); // TODO: delete
identifier.TypeDescriptor = new ErrorDescriptor();
((ErrorDescriptor)identifier.TypeDescriptor).Message = message;
identifier.AttributesRef = null;
}
else
{
ParameterAttributes attr = new ParameterAttributes();
attr.Kind = Kind.VariableAttributes;
attr.TypeDescriptor = declType;
Table.enter(id, attr);
Console.WriteLine("Entered into symbol table: " + id +
" " + attr); // TODO: DELETE
identifier.TypeDescriptor = declType;
identifier.AttributesRef = attr;
}
}

private void VisitNode(MethodCall node)
{
AbstractNode methodReference = node.Child;
AbstractNode argumentList = methodReference.Sib; // may be null

methodReference.Accept(TypeVisitor);
TypeDescriptor methodRefType = methodReference.TypeDescriptor;

if (argumentList != null)
{
AbstractNode child = argumentList.Child;
while (child != null)
{
MethodReferenceAttributes attr = new MethodReferenceAttributes();
Expression expression = (Expression)child;
expression.Accept(this);
// TODO: these expressions (in the Argument List) should
// probably hold a reference to the attribute? or should a
// list be kept of the expressions?
child = child.Sib;
}
}
}

private void VisitNode(Literal node)
{
var desc = new LiteralTypeDescriptor {Value = node.Lit};
node.TypeDescriptor = desc;
}


}
}
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
@@ -8,10 +9,15 @@ namespace Project3
{
public abstract class TypeDescriptor { }

public class ErrorDescriptor : TypeDescriptor { }
public class ErrorDescriptor : TypeDescriptor
{
public string Message { get; set; }
}

public class JavaObjectDescriptor : TypeDescriptor { }

public class VariableDeclarationDescriptor : TypeDescriptor { }

public class IntegerTypeDescriptor : TypeDescriptor { }

public class ArrayTypeDescriptor : TypeDescriptor { }
@@ -22,14 +28,53 @@ public class ClassTypeDescriptor : TypeDescriptor
public ScopeTable ClassBody { get; set; }
}

public class MethodTypeDescriptor : TypeDescriptor
public class MethodTypeDescriptor : TypeDescriptor { }

public enum PrimitiveTypes { VOID, INT, BOOLEAN }
public abstract class PrimitiveTypeDescriptor : TypeDescriptor
{

public virtual PrimitiveTypes PrimitiveTypes { get; }
public virtual string Name { get; }
}

public class PrimitiveTypeDescriptor : TypeDescriptor
public class PrimitiveVoidTypeDescriptor : PrimitiveTypeDescriptor
{
public string Name { get; set; } // BOOLEAN, VOID, INT
public override PrimitiveTypes PrimitiveTypes
{
get { return PrimitiveTypes.VOID; }
}
public override string Name { get { return "VOID"; } }
}

public class PrimitiveIntTypeDescriptor : PrimitiveTypeDescriptor
{
public override PrimitiveTypes PrimitiveTypes
{
get { return PrimitiveTypes.INT; }
}
public override string Name { get { return "INT"; } }
}

public class PrimitiveBooleanTypeDescriptor : PrimitiveTypeDescriptor
{
public override PrimitiveTypes PrimitiveTypes
{
get { return PrimitiveTypes.BOOLEAN; }
}
public override string Name { get { return "BOOLEAN"; } }
}

public class MethodCallDescriptor : TypeDescriptor { }

public class SpecialNameDescriptor : TypeDescriptor { }

public class NotJustNameDescriptor : TypeDescriptor { }

public class LiteralTypeDescriptor : TypeDescriptor
{
public string Value { get; set; }
}

//public class MethodReferenceDescriptor : TypeDescriptor { }

}
@@ -0,0 +1,119 @@
using System;

namespace Project3
{
public class TypeVisitor : SemanticsVisitor
{
public TypeVisitor(SymbolTable st) : base(st)
{
}

public override void Visit(dynamic node)
{
this.VisitNode(node);
}

private new void VisitNode(AbstractNode node)
{
Console.WriteLine("VisitNode, TypeVisitor [" + node.GetType() + "]");
VisitChildren(node);
}

private new void VisitChildren(AbstractNode node)
{
AbstractNode child = node.Child;
while (child != null)
{
child.Accept(this);
child = child.Sib;
}
}

// Identifier
private void VisitNode(Identifier node)
{
Console.WriteLine("Identifier node visit in TypeVisitor.");
Attributes attr = Table.lookup(node.ID);
if (attr != null && attr.Kind == Kind.TypeAttributes)
{
node.TypeDescriptor = attr.TypeDescriptor;
node.AttributesRef = attr;
}
else
{
string message = "This identifier is not a type name: "
+ node.ID;
Console.WriteLine(message); // TODO: delete me
node.TypeDescriptor = new ErrorDescriptor();
((ErrorDescriptor)node.TypeDescriptor).Message = message;
node.AttributesRef = null;
}
}

private void VisitNode(PrimitiveTypeVoid node)
{
Console.WriteLine("PrimitiveTypeVoid node visit in TypeVisitor.");
Attributes attr = Table.lookup(node.StringName);
node.TypeDescriptor = attr.TypeDescriptor;
node.AttributesRef = attr;
}

private void VisitNode(PrimitiveTypeInt node)
{
Console.WriteLine("PrimitiveTypeInt node visit in TypeVisitor.");
Attributes attr = Table.lookup(node.StringName);
node.TypeDescriptor = attr.TypeDescriptor;
node.AttributesRef = attr;
}

private void VisitNode(PrimitiveTypeBoolean node)
{
Console.WriteLine("PrimitiveTypeBoolean node visit in TypeVisitor.");
Attributes attr = Table.lookup(node.StringName);
node.TypeDescriptor = attr.TypeDescriptor;
node.AttributesRef = attr;
}

private void VisitNode(QualifiedName node)
{
Console.WriteLine("QualifiedName in TypeVisitor");
AbstractNode child = node.Child;
while (child != null)
{
((Identifier)child).Accept(this);
node.TypeDescriptor = child.TypeDescriptor;
node.AttributesRef = child.AttributesRef;
child = child.Sib;
}
}

private void VisitNode(SpecialName node)
{
Console.WriteLine("SpecialName in TypeVisitor");
Attributes attr = Table.lookup(node.Name.ToString());
node.TypeDescriptor = attr.TypeDescriptor;
node.AttributesRef = attr;
}

private void VisitNode(FieldAccess node)
{
Console.WriteLine("FieldAccess in TypeVisitor");
AbstractNode notJustName = node.Child;
AbstractNode identifier = notJustName.Sib;

FieldAccessAttributes attr = new FieldAccessAttributes();
notJustName.Accept(this);
attr.NotJustNameTypeDescriptor = notJustName.TypeDescriptor;
identifier.Accept(this);
attr.TypeDescriptor = identifier.TypeDescriptor;
node.TypeDescriptor = attr.TypeDescriptor;
node.AttributesRef = attr;
}

// ArrayDefining

// Struct Defining

// EnumDefining
}
}