diff --git a/Canon.Core/Abstractions/IGrammarParser.cs b/Canon.Core/Abstractions/IGrammarParser.cs index a86e769..44e3649 100644 --- a/Canon.Core/Abstractions/IGrammarParser.cs +++ b/Canon.Core/Abstractions/IGrammarParser.cs @@ -36,7 +36,21 @@ public interface IGrammarParser { AnalyseState top = stack.Peek(); - // 首先尝试进行归约 + // 首先尝试进行移进 + if (top.State.ShiftTable.TryGetValue(enumerator.Current, out ITransformer? next)) + { + stack.Push(new AnalyseState(next, SyntaxNodeBase.Create(enumerator.Current))); + if (enumerator.MoveNext()) + { + continue; + } + else + { + throw new GrammarException(stack.Peek().State); + } + } + + // 再进行归约 if (top.State.ReduceTable.TryGetValue(enumerator.Current, out ReduceInformation? information)) { if (information.Left == Begin) @@ -60,20 +74,6 @@ public interface IGrammarParser continue; } - // 如果没有成功归约就进行移进 - if (top.State.ShiftTable.TryGetValue(enumerator.Current, out ITransformer? next)) - { - stack.Push(new AnalyseState(next, SyntaxNodeBase.Create(enumerator.Current))); - if (enumerator.MoveNext()) - { - continue; - } - else - { - throw new GrammarException(stack.Peek().State); - } - } - throw new GrammarException(stack.Peek().State, enumerator.Current); } } diff --git a/Canon.Core/SemanticParser/CodeGeneratorVisitor.cs b/Canon.Core/SemanticParser/CodeGeneratorVisitor.cs index a7c8dd9..be2e3da 100644 --- a/Canon.Core/SemanticParser/CodeGeneratorVisitor.cs +++ b/Canon.Core/SemanticParser/CodeGeneratorVisitor.cs @@ -3,6 +3,7 @@ using Canon.Core.CodeGenerators; using Canon.Core.Enums; using Canon.Core.LexicalParser; using Canon.Core.SyntaxNodes; +using BasicType = Canon.Core.Enums.BasicType; namespace Canon.Core.SemanticParser; @@ -272,7 +273,9 @@ public class CodeGeneratorVisitor : TypeCheckVisitor // 虽然这里这样可能会生成来类似于 &*x 的代码 // 但是可以正常运行 variable.VariableName = - symbol.Reference ? $"*{variable.Identifier.IdentifierName}" : variable.Identifier.IdentifierName; + symbol.SymbolType.IsReference + ? $"*{variable.Identifier.IdentifierName}" + : variable.Identifier.IdentifierName; } public override void PreVisit(Term term) @@ -608,8 +611,7 @@ public class CodeGeneratorVisitor : TypeCheckVisitor if (parameter.ParameterType is PascalBasicType) { - string refValue = parameter.IsVar ? "*" : string.Empty; - value = $"{GenerateBasicTypeString(parameter.ParameterType)} {refValue}{parameter.ParameterName}"; + value = $"{GenerateBasicTypeString(parameter.ParameterType)} {parameter.ParameterName}"; } if (parameter.ParameterType is PascalArrayType) @@ -793,24 +795,9 @@ public class CodeGeneratorVisitor : TypeCheckVisitor foreach ((Expression parameter, PascalParameterType parameterType) in parameters.Zip(functionType.Parameters)) { - if (parameterType.IsVar) + if (parameterType.ParameterType.IsReference) { - // 这里需要判断parameter是否也为引用类型 - if (SymbolTable.TryGetSymbol(parameter.VariableName, out Symbol? parameterSymboe)) - { - if (parameterSymboe.Reference) - { - parameterValue += $", {parameter.VariableName}"; - } - else - { - parameterValue += $", &{parameter.VariableName}"; - } - } - else - { - parameterValue += $", &{parameter.VariableName}"; - } + parameterValue += $", &{parameter.VariableName}"; } else { @@ -851,29 +838,21 @@ public class CodeGeneratorVisitor : TypeCheckVisitor private static string GenerateBasicTypeString(PascalType pascalType) { - if (pascalType == PascalBasicType.Character) + if (pascalType is not PascalBasicType basicType) { - return "char"; + return string.Empty; } - if (pascalType == PascalBasicType.Boolean) + switch (basicType.Type) { - return "bool"; - } - - if (pascalType == PascalBasicType.Integer) - { - return "int"; - } - - if (pascalType == PascalBasicType.Real) - { - return "double"; - } - - if (pascalType == PascalBasicType.Void) - { - return "void"; + case BasicType.Integer: + return basicType.IsReference ? "int *" : "int"; + case BasicType.Real: + return basicType.IsReference ? "double *" : "double"; + case BasicType.Character: + return basicType.IsReference ? "char *" : "char"; + case BasicType.Boolean: + return basicType.IsReference ? "bool *" : "bool"; } return string.Empty; diff --git a/Canon.Core/SemanticParser/PascalArrayType.cs b/Canon.Core/SemanticParser/PascalArrayType.cs index 4740761..ea0634c 100644 --- a/Canon.Core/SemanticParser/PascalArrayType.cs +++ b/Canon.Core/SemanticParser/PascalArrayType.cs @@ -10,6 +10,11 @@ public class PascalArrayType(PascalType elementType, int begin, int end) : Pasca public override string TypeName => $"{ElementType.TypeName}_{Begin}_{End}"; + public override PascalType ToReferenceType() + { + throw new InvalidOperationException("Array type can not be reference."); + } + public override bool Equals(PascalType? other) { if (other is not PascalArrayType pascalArrayType) @@ -27,12 +32,13 @@ public class PascalArrayType(PascalType elementType, int begin, int end) : Pasca return false; } - return true; + return base.Equals(pascalArrayType); } public override int GetHashCode() { - return ElementType.GetHashCode() + return base.GetHashCode() + ^ ElementType.GetHashCode() ^ Begin.GetHashCode() ^ End.GetHashCode(); } diff --git a/Canon.Core/SemanticParser/PascalBasicType.cs b/Canon.Core/SemanticParser/PascalBasicType.cs index fc2f57e..62c9a19 100644 --- a/Canon.Core/SemanticParser/PascalBasicType.cs +++ b/Canon.Core/SemanticParser/PascalBasicType.cs @@ -12,12 +12,16 @@ public class PascalBasicType : PascalType /// public BasicType Type { get; } - public override string TypeName { get; } + public override string TypeName => Type.ToString(); - private PascalBasicType(BasicType basicType, string typeName) + private PascalBasicType(BasicType type) { - Type = basicType; - TypeName = typeName; + Type = type; + } + + public override PascalType ToReferenceType() + { + return new PascalBasicType(Type) { IsReference = true }; } public override bool Equals(PascalType? other) @@ -27,12 +31,12 @@ public class PascalBasicType : PascalType return false; } - return Type == pascalBasicType.Type; + return Type == pascalBasicType.Type && base.Equals(pascalBasicType); } public override int GetHashCode() { - return Type.GetHashCode(); + return base.GetHashCode() ^ Type.GetHashCode(); } public override string ToString() => TypeName; @@ -40,25 +44,25 @@ public class PascalBasicType : PascalType /// /// 整数类型的单例对象 /// - public static PascalType Integer => new PascalBasicType(BasicType.Integer, "integer"); + public static PascalType Integer => new PascalBasicType(BasicType.Integer); /// /// 布尔类型的单例对象 /// - public static PascalType Boolean => new PascalBasicType(BasicType.Boolean, "boolean"); + public static PascalType Boolean => new PascalBasicType(BasicType.Boolean); /// /// 字符类型的单例对象 /// - public static PascalType Character => new PascalBasicType(BasicType.Character, "char"); + public static PascalType Character => new PascalBasicType(BasicType.Character); /// /// 浮点数类型的单例对象 /// - public static PascalType Real => new PascalBasicType(BasicType.Real, "real"); + public static PascalType Real => new PascalBasicType(BasicType.Real); /// /// 空类型的单例对象 /// - public static PascalType Void => new PascalBasicType(BasicType.Void, "void"); + public static PascalType Void => new PascalBasicType(BasicType.Void); } diff --git a/Canon.Core/SemanticParser/PascalFunctionType.cs b/Canon.Core/SemanticParser/PascalFunctionType.cs index 5d8719e..310f160 100644 --- a/Canon.Core/SemanticParser/PascalFunctionType.cs +++ b/Canon.Core/SemanticParser/PascalFunctionType.cs @@ -29,6 +29,11 @@ public class PascalFunctionType(List parameters, PascalType } } + public override PascalType ToReferenceType() + { + throw new InvalidOperationException("Function type can not be reference."); + } + public override bool Equals(PascalType? other) { if (other is not PascalFunctionType functionType) @@ -49,12 +54,12 @@ public class PascalFunctionType(List parameters, PascalType } } - return true; + return base.Equals(functionType); } public override int GetHashCode() { - int code = ReturnType.GetHashCode(); + int code = base.GetHashCode() ^ ReturnType.GetHashCode(); foreach (PascalParameterType parameter in Parameters) { diff --git a/Canon.Core/SemanticParser/PascalParameterType.cs b/Canon.Core/SemanticParser/PascalParameterType.cs index 4826945..7a4c137 100644 --- a/Canon.Core/SemanticParser/PascalParameterType.cs +++ b/Canon.Core/SemanticParser/PascalParameterType.cs @@ -1,26 +1,16 @@ namespace Canon.Core.SemanticParser; -public class PascalParameterType(PascalType parameterType, bool isVar, string parameterName) : PascalType +public class PascalParameterType(PascalType parameterType, string parameterName) : PascalType { public PascalType ParameterType { get; } = parameterType; - public bool IsVar { get; } = isVar; - public string ParameterName { get; } = parameterName; - public override string TypeName + public override string TypeName => $"{ParameterType}_{ParameterName}"; + + public override PascalType ToReferenceType() { - get - { - if (IsVar) - { - return $"var_{ParameterType.TypeName}"; - } - else - { - return ParameterType.TypeName; - } - } + throw new InvalidOperationException("The parameter type can not be reference."); } public override bool Equals(PascalType? other) @@ -30,11 +20,11 @@ public class PascalParameterType(PascalType parameterType, bool isVar, string pa return false; } - return ParameterType == parameterType.ParameterType && IsVar == parameterType.IsVar; + return ParameterType == parameterType.ParameterType && base.Equals(parameterType); } public override int GetHashCode() { - return ParameterType.GetHashCode() ^ IsVar.GetHashCode(); + return base.GetHashCode() ^ ParameterType.GetHashCode(); } } diff --git a/Canon.Core/SemanticParser/PascalType.cs b/Canon.Core/SemanticParser/PascalType.cs index 55cf514..bf181fb 100644 --- a/Canon.Core/SemanticParser/PascalType.cs +++ b/Canon.Core/SemanticParser/PascalType.cs @@ -1,4 +1,6 @@ -namespace Canon.Core.SemanticParser; +using Canon.Core.Enums; + +namespace Canon.Core.SemanticParser; /// /// Pascal类型基类 @@ -10,6 +12,18 @@ public abstract class PascalType : IEquatable /// public abstract string TypeName { get; } + /// + /// 将当前类型转换为引用类型 + /// 原有类型变量保持不变 + /// + /// 原有Pascal类型的引用类型 + public abstract PascalType ToReferenceType(); + + /// + /// 是否为引用类型 + /// + public bool IsReference { get; init; } + public virtual bool Equals(PascalType? other) { if (other is null) @@ -17,7 +31,7 @@ public abstract class PascalType : IEquatable return false; } - return TypeName == other.TypeName; + return IsReference == other.IsReference; } public T Convert() where T : PascalType @@ -42,7 +56,7 @@ public abstract class PascalType : IEquatable public override int GetHashCode() { - return TypeName.GetHashCode(); + return IsReference.GetHashCode(); } public static bool operator ==(PascalType a, PascalType b) @@ -57,34 +71,21 @@ public abstract class PascalType : IEquatable public static PascalType operator +(PascalType a, PascalType b) { - if (!IsCalculatable(a) || !IsCalculatable(b)) - { - throw new InvalidOperationException(); - } - - if (a == PascalBasicType.Boolean && b == PascalBasicType.Boolean) + if (a is PascalBasicType { Type: BasicType.Boolean } && b is PascalBasicType { Type: BasicType.Boolean }) { return PascalBasicType.Boolean; } - if (a == PascalBasicType.Integer && b == PascalBasicType.Integer) + if (a is PascalBasicType { Type: BasicType.Integer } && b is PascalBasicType { Type: BasicType.Integer }) { return PascalBasicType.Integer; } - else + + if (a is PascalBasicType { Type : BasicType.Real } && b is PascalBasicType { Type: BasicType.Real }) { return PascalBasicType.Real; } - } - /// - /// 是否为可计算的类型 - /// - /// 需要判断的Pascal类型 - /// 是否为可计算的类型 - public static bool IsCalculatable(PascalType pascalType) - { - return pascalType == PascalBasicType.Integer || pascalType == PascalBasicType.Real - || pascalType == PascalBasicType.Boolean; + return PascalBasicType.Void; } } diff --git a/Canon.Core/SemanticParser/Symbol.cs b/Canon.Core/SemanticParser/Symbol.cs index 7b8e212..8ff0114 100644 --- a/Canon.Core/SemanticParser/Symbol.cs +++ b/Canon.Core/SemanticParser/Symbol.cs @@ -20,11 +20,6 @@ public class Symbol : IEquatable /// public bool Const { get; init; } - /// - /// 是否为引用变量 - /// - public bool Reference { get; init; } - public bool Equals(Symbol? other) { if (other is null) @@ -33,9 +28,8 @@ public class Symbol : IEquatable } return SymbolName == other.SymbolName - && SymbolType == other.SymbolType - && Const == other.Const - && Reference == other.Reference; + && SymbolType == other.SymbolType + && Const == other.Const; } public override int GetHashCode() @@ -53,6 +47,3 @@ public class Symbol : IEquatable return Equals(other); } } - - - diff --git a/Canon.Core/SemanticParser/TypeCheckVisitor.cs b/Canon.Core/SemanticParser/TypeCheckVisitor.cs index 901e4c8..4770f41 100644 --- a/Canon.Core/SemanticParser/TypeCheckVisitor.cs +++ b/Canon.Core/SemanticParser/TypeCheckVisitor.cs @@ -69,7 +69,7 @@ public class TypeCheckVisitor(ICompilerLogger? logger = null) : SyntaxNodeVisito if (!SymbolTable.TryAddSymbol(new Symbol { - Const = true, SymbolName = token.IdentifierName, SymbolType = constValue.ConstType + SymbolName = token.IdentifierName, SymbolType = constValue.ConstType, Const = true })) { IsError = true; @@ -96,23 +96,14 @@ public class TypeCheckVisitor(ICompilerLogger? logger = null) : SyntaxNodeVisito }; // factor -> true | false - factor.OnBooleanGenerator += (_, _) => - { - factor.VariableType = PascalBasicType.Boolean; - }; + factor.OnBooleanGenerator += (_, _) => { factor.VariableType = PascalBasicType.Boolean; }; // factor -> variable - factor.OnVariableGenerator += (_, e) => - { - factor.VariableType = e.Variable.VariableType; - }; + factor.OnVariableGenerator += (_, e) => { factor.VariableType = e.Variable.VariableType; }; // factor -> (expression) - factor.OnParethnesisGenerator += (_, e) => - { - factor.VariableType = e.Expression.VariableType; - }; + factor.OnParethnesisGenerator += (_, e) => { factor.VariableType = e.Expression.VariableType; }; // factor -> id ( ExpressionList) factor.OnProcedureCallGenerator += (_, e) => @@ -135,43 +126,30 @@ public class TypeCheckVisitor(ICompilerLogger? logger = null) : SyntaxNodeVisito }; // factor -> not factor - factor.OnNotGenerator += (_, e) => - { - factor.VariableType = e.Factor.VariableType; - }; + factor.OnNotGenerator += (_, e) => { factor.VariableType = e.Factor.VariableType; }; // factor -> uminus factor - factor.OnUminusGenerator += (_, e) => - { - factor.VariableType = e.Factor.VariableType; - }; + factor.OnUminusGenerator += (_, e) => { factor.VariableType = e.Factor.VariableType; }; // factor -> plus factor - factor.OnPlusGenerator += (_, e) => - { - factor.VariableType = e.Factor.VariableType; - }; + factor.OnPlusGenerator += (_, e) => { factor.VariableType = e.Factor.VariableType; }; } public override void PostVisit(Term term) { base.PostVisit(term); - term.OnFactorGenerator += (_, e) => - { - term.VariableType = e.Factor.VariableType; - }; + term.OnFactorGenerator += (_, e) => { term.VariableType = e.Factor.VariableType; }; term.OnMultiplyGenerator += (_, e) => { - if (PascalType.IsCalculatable(e.Left.VariableType) && PascalType.IsCalculatable(e.Right.VariableType)) - { - term.VariableType = e.Left.VariableType + e.Right.VariableType; - return; - } + term.VariableType = e.Left.VariableType + e.Right.VariableType; - IsError = true; - logger?.LogError("Can't calculate"); + if (term.VariableType == PascalBasicType.Void) + { + IsError = true; + logger?.LogError("Can't calculate"); + } }; } @@ -179,21 +157,17 @@ public class TypeCheckVisitor(ICompilerLogger? logger = null) : SyntaxNodeVisito { base.PostVisit(simpleExpression); - simpleExpression.OnTermGenerator += (_, e) => - { - simpleExpression.VariableType = e.Term.VariableType; - }; + simpleExpression.OnTermGenerator += (_, e) => { simpleExpression.VariableType = e.Term.VariableType; }; simpleExpression.OnAddGenerator += (_, e) => { - if (PascalType.IsCalculatable(e.Left.VariableType) && PascalType.IsCalculatable(e.Right.VariableType)) - { - simpleExpression.VariableType = e.Left.VariableType + e.Right.VariableType; - return; - } + simpleExpression.VariableType = e.Left.VariableType + e.Right.VariableType; - IsError = true; - logger?.LogError("Can't calculate"); + if (simpleExpression.VariableType == PascalBasicType.Void) + { + IsError = true; + logger?.LogError("Can't calculate"); + } }; } @@ -206,10 +180,7 @@ public class TypeCheckVisitor(ICompilerLogger? logger = null) : SyntaxNodeVisito expression.VariableType = e.SimpleExpression.VariableType; }; - expression.OnRelationGenerator += (_, _) => - { - expression.VariableType = PascalBasicType.Boolean; - }; + expression.OnRelationGenerator += (_, _) => { expression.VariableType = PascalBasicType.Boolean; }; } public override void PostVisit(TypeSyntaxNode typeSyntaxNode) @@ -251,7 +222,12 @@ public class TypeCheckVisitor(ICompilerLogger? logger = null) : SyntaxNodeVisito { base.PostVisit(identifierList); - identifierList.OnTypeGenerator += (_, e) => { identifierList.DefinitionType = e.TypeSyntaxNode.PascalType; }; + identifierList.OnTypeGenerator += (_, e) => + { + identifierList.DefinitionType = identifierList.IsReference + ? e.TypeSyntaxNode.PascalType.ToReferenceType() + : e.TypeSyntaxNode.PascalType; + }; identifierList.OnIdentifierGenerator += (_, e) => { @@ -259,9 +235,7 @@ public class TypeCheckVisitor(ICompilerLogger? logger = null) : SyntaxNodeVisito Symbol symbol = new() { - SymbolName = e.IdentifierToken.IdentifierName, - SymbolType = identifierList.DefinitionType, - Reference = identifierList.IsReference + SymbolName = e.IdentifierToken.IdentifierName, SymbolType = identifierList.DefinitionType, }; SymbolTable.TryAddSymbol(symbol); @@ -342,7 +316,7 @@ public class TypeCheckVisitor(ICompilerLogger? logger = null) : SyntaxNodeVisito { foreach (Symbol symbol in children.AsEnumerable().Reverse()) { - parameters.Add(new PascalParameterType(symbol.SymbolType, symbol.Reference, symbol.SymbolName)); + parameters.Add(new PascalParameterType(symbol.SymbolType, symbol.SymbolName)); } } @@ -398,8 +372,7 @@ public class TypeCheckVisitor(ICompilerLogger? logger = null) : SyntaxNodeVisito Symbol symbol = new() { SymbolName = valueParameter.Token.IdentifierName, - SymbolType = valueParameter.IdentifierList.DefinitionType, - Reference = valueParameter.IsReference + SymbolType = valueParameter.IdentifierList.DefinitionType }; SymbolTable.TryAddSymbol(symbol); diff --git a/Canon.Core/SyntaxNodes/TypeSyntaxNode.cs b/Canon.Core/SyntaxNodes/TypeSyntaxNode.cs index 948e1cc..1011fd4 100644 --- a/Canon.Core/SyntaxNodes/TypeSyntaxNode.cs +++ b/Canon.Core/SyntaxNodes/TypeSyntaxNode.cs @@ -59,6 +59,11 @@ public class TypeSyntaxNode : NonTerminatedSyntaxNode } } + /// + /// 是否为定义引用变量 + /// + public bool IsReference { get; set; } + public static TypeSyntaxNode Create(List children) { return new TypeSyntaxNode { Children = children }; diff --git a/Canon.Tests/SemanticTests/PascalTypeTests.cs b/Canon.Tests/SemanticTests/PascalTypeTests.cs index c38371a..d32ddb1 100644 --- a/Canon.Tests/SemanticTests/PascalTypeTests.cs +++ b/Canon.Tests/SemanticTests/PascalTypeTests.cs @@ -36,14 +36,14 @@ public class PascalTypeTests [Fact] public void PascalFunctionTypeTests() { - PascalType function1 = new PascalFunctionType([new PascalParameterType(PascalBasicType.Integer, false, "a")], + PascalType function1 = new PascalFunctionType([new PascalParameterType(PascalBasicType.Integer, "a")], PascalBasicType.Void); - PascalType function2 = new PascalFunctionType([new PascalParameterType(PascalBasicType.Integer, false, "a")], + PascalType function2 = new PascalFunctionType([new PascalParameterType(PascalBasicType.Integer, "a")], PascalBasicType.Void); Assert.Equal(function1, function2); - PascalType function3 = new PascalFunctionType([new PascalParameterType(PascalBasicType.Real, true, "a")], + PascalType function3 = new PascalFunctionType([new PascalParameterType(PascalBasicType.Real, "a")], PascalBasicType.Integer); Assert.NotEqual(function1, function3); } diff --git a/Canon.Tests/SemanticTests/SymbolTableTests.cs b/Canon.Tests/SemanticTests/SymbolTableTests.cs index d2f59d0..af8ab8b 100644 --- a/Canon.Tests/SemanticTests/SymbolTableTests.cs +++ b/Canon.Tests/SemanticTests/SymbolTableTests.cs @@ -9,13 +9,13 @@ public class SymbolTableTests { SymbolTable table = new(); - Assert.True(table.TryGetType("integer", out PascalType? integer)); + Assert.True(table.TryGetType("Integer", out PascalType? integer)); Assert.Equal(PascalBasicType.Integer, integer); - Assert.True(table.TryGetType("real", out PascalType? real)); + Assert.True(table.TryGetType("Real", out PascalType? real)); Assert.Equal(PascalBasicType.Real, real); - Assert.True(table.TryGetType("boolean", out PascalType? boolean)); + Assert.True(table.TryGetType("Boolean", out PascalType? boolean)); Assert.Equal(PascalBasicType.Boolean, boolean); - Assert.True(table.TryGetType("char", out PascalType? character)); + Assert.True(table.TryGetType("Character", out PascalType? character)); Assert.Equal(PascalBasicType.Character, character); } @@ -25,10 +25,7 @@ public class SymbolTableTests SymbolTable table = new(); Assert.True(table.TryAddSymbol(new Symbol { SymbolName = "a", SymbolType = PascalBasicType.Integer })); - Assert.True(table.TryAddSymbol(new Symbol - { - SymbolName = "temperature", SymbolType = PascalBasicType.Real, Const = true - })); + Assert.True(table.TryAddSymbol(new Symbol { SymbolName = "temperature", SymbolType = PascalBasicType.Real })); Assert.True(table.TryGetSymbol("a", out Symbol? a)); Assert.Equal(PascalBasicType.Integer, a.SymbolType); @@ -42,18 +39,12 @@ public class SymbolTableTests SymbolTable table = new(); Assert.True(table.TryAddSymbol(new Symbol { SymbolName = "a", SymbolType = PascalBasicType.Integer })); - Assert.True(table.TryAddSymbol(new Symbol - { - SymbolName = "temperature", SymbolType = PascalBasicType.Real, Const = true - })); + Assert.True(table.TryAddSymbol(new Symbol { SymbolName = "temperature", SymbolType = PascalBasicType.Real })); SymbolTable child = table.CreateChildTable(); - Assert.True(child.TryAddSymbol(new Symbol{SymbolName = "a", SymbolType = PascalBasicType.Real})); - Assert.True(child.TryAddSymbol(new Symbol - { - SymbolName = "level2", SymbolType = PascalBasicType.Boolean, Reference = true - })); + Assert.True(child.TryAddSymbol(new Symbol { SymbolName = "a", SymbolType = PascalBasicType.Real })); + Assert.True(child.TryAddSymbol(new Symbol { SymbolName = "level2", SymbolType = PascalBasicType.Boolean })); Assert.True(child.TryGetSymbol("a", out Symbol? a)); Assert.Equal(PascalBasicType.Real, a.SymbolType); diff --git a/Canon.Tests/SemanticTests/TypeCheckVisitorTests.cs b/Canon.Tests/SemanticTests/TypeCheckVisitorTests.cs index 9afda2b..66faf99 100644 --- a/Canon.Tests/SemanticTests/TypeCheckVisitorTests.cs +++ b/Canon.Tests/SemanticTests/TypeCheckVisitorTests.cs @@ -126,9 +126,9 @@ public class TypeCheckVisitorTests(ITestOutputHelper testOutputHelper) Assert.True(visitor.SymbolTable.TryGetSymbol("test", out Symbol? symbol)); Assert.Equal(symbol.SymbolType, new PascalFunctionType([ - new PascalParameterType(PascalBasicType.Integer, false, "a"), - new PascalParameterType(PascalBasicType.Integer, false, "a"), - new PascalParameterType(PascalBasicType.Integer, false, "a") + new PascalParameterType(PascalBasicType.Integer, "a"), + new PascalParameterType(PascalBasicType.Integer, "a"), + new PascalParameterType(PascalBasicType.Integer, "a") ], PascalBasicType.Void)); } @@ -148,9 +148,9 @@ public class TypeCheckVisitorTests(ITestOutputHelper testOutputHelper) Assert.True(visitor.SymbolTable.TryGetSymbol("test", out Symbol? symbol)); Assert.Equal(symbol.SymbolType, new PascalFunctionType([ - new PascalParameterType(PascalBasicType.Real, true, "a"), - new PascalParameterType(PascalBasicType.Real, true, "a"), - new PascalParameterType(PascalBasicType.Real, true, "a") + new PascalParameterType(PascalBasicType.Real.ToReferenceType(),"a"), + new PascalParameterType(PascalBasicType.Real.ToReferenceType(), "a"), + new PascalParameterType(PascalBasicType.Real.ToReferenceType(), "a") ], PascalBasicType.Void)); } @@ -170,10 +170,10 @@ public class TypeCheckVisitorTests(ITestOutputHelper testOutputHelper) Assert.True(visitor.SymbolTable.TryGetSymbol("test", out Symbol? symbol)); Assert.Equal(symbol.SymbolType, new PascalFunctionType([ - new PascalParameterType(PascalBasicType.Integer, false, "a"), - new PascalParameterType(PascalBasicType.Integer, false, "a"), - new PascalParameterType(PascalBasicType.Character, true, "a"), - new PascalParameterType(PascalBasicType.Character, true, "a") + new PascalParameterType(PascalBasicType.Integer, "a"), + new PascalParameterType(PascalBasicType.Integer, "a"), + new PascalParameterType(PascalBasicType.Character.ToReferenceType(), "a"), + new PascalParameterType(PascalBasicType.Character.ToReferenceType(), "a") ], PascalBasicType.Void)); } @@ -193,10 +193,10 @@ public class TypeCheckVisitorTests(ITestOutputHelper testOutputHelper) Assert.True(visitor.SymbolTable.TryGetSymbol("test", out Symbol? symbol)); Assert.Equal(symbol.SymbolType, new PascalFunctionType([ - new PascalParameterType(PascalBasicType.Integer, false, "a"), - new PascalParameterType(PascalBasicType.Integer, false, "a"), - new PascalParameterType(PascalBasicType.Character, true, "a"), - new PascalParameterType(PascalBasicType.Character, true, "a") + new PascalParameterType(PascalBasicType.Integer, "a"), + new PascalParameterType(PascalBasicType.Integer, "a"), + new PascalParameterType(PascalBasicType.Character.ToReferenceType(), "a"), + new PascalParameterType(PascalBasicType.Character.ToReferenceType(), "a") ], PascalBasicType.Real)); } @@ -219,16 +219,16 @@ public class TypeCheckVisitorTests(ITestOutputHelper testOutputHelper) Assert.True(visitor.SymbolTable.TryGetSymbol("test1", out Symbol? symbol)); Assert.Equal(symbol.SymbolType, new PascalFunctionType([ - new PascalParameterType(PascalBasicType.Integer, false, "a"), - new PascalParameterType(PascalBasicType.Real, true, "a"), - new PascalParameterType(PascalBasicType.Real, true, "a"), - new PascalParameterType(PascalBasicType.Boolean, false, "a") + new PascalParameterType(PascalBasicType.Integer, "a"), + new PascalParameterType(PascalBasicType.Real.ToReferenceType(), "a"), + new PascalParameterType(PascalBasicType.Real.ToReferenceType(), "a"), + new PascalParameterType(PascalBasicType.Boolean, "a") ], PascalBasicType.Void)); Assert.True(visitor.SymbolTable.TryGetSymbol("test2", out symbol)); Assert.Equal(symbol.SymbolType, new PascalFunctionType([ - new PascalParameterType(PascalBasicType.Boolean, true, "a"), - new PascalParameterType(PascalBasicType.Boolean, true, "a") + new PascalParameterType(PascalBasicType.Boolean.ToReferenceType(), "a"), + new PascalParameterType(PascalBasicType.Boolean.ToReferenceType(), "a") ], PascalBasicType.Boolean)); } @@ -279,7 +279,6 @@ public class TypeCheckVisitorTests(ITestOutputHelper testOutputHelper) Assert.True(visitor.SymbolTable.TryGetSymbol("a", out Symbol? symbol)); Assert.Equal(PascalBasicType.Integer, symbol.SymbolType); - Assert.True(symbol.Const); Assert.True(visitor.SymbolTable.TryGetSymbol("b", out symbol)); Assert.Equal(PascalBasicType.Real, symbol.SymbolType); @@ -290,7 +289,7 @@ public class TypeCheckVisitorTests(ITestOutputHelper testOutputHelper) Assert.True(visitor.SymbolTable.TryGetSymbol("test", out symbol)); Assert.Equal( new PascalFunctionType([ - new PascalParameterType(PascalBasicType.Boolean, false, "a") + new PascalParameterType(PascalBasicType.Boolean, "a") ], PascalBasicType.Void), symbol.SymbolType); Assert.False(visitor.SymbolTable.TryGetSymbol("d", out symbol));