public void TestUnused() { /* * def kju() : Unit { * struct X {}; * } */ var dummyRange = new Core.Lexer.Range(new StringLocation(0), new StringLocation(0)); var xDeclaration = new StructDeclaration(dummyRange, "X", new List <StructField>()); var xType = StructType.GetInstance(xDeclaration); var kjuInstructions = new List <Expression> { xDeclaration }; var kjuDeclaration = new FunctionDeclaration( dummyRange, "kju", new ArrayType(UnitType.Instance), new List <VariableDeclaration>(), new InstructionBlock(dummyRange, kjuInstructions), false); var root = new Program(dummyRange, new List <StructDeclaration>(), new List <FunctionDeclaration> { kjuDeclaration }); this.CheckAnswer(root, new HashSet <DataType>() { xType }); }
private void PopBlock() { var ids = this.variableBlocks.Pop(); foreach (var id in ids) { this.variables[id].Pop(); } var funs = this.functionBlocks.Pop(); foreach (var fun in funs) { this.functions[fun.Key].Pop(); } var structs = this.structBlocks.Pop(); foreach (var structName in structs) { this.structs[structName].Pop(); if (this.structs[structName].Count > 0) { var structDecl = this.structs[structName].Peek(); this.dataTypes[structName] = StructType.GetInstance(structDecl); } else { this.dataTypes.Remove(structName); } } }
public void TestStructFunctionParameters() { var aDecl = new StructDeclaration( null, "A", new List <StructField>()); var aParam = new VariableDeclaration( null, new UnresolvedType("A", null), "a", null); var f = new FunctionDeclaration( null, "f", new UnresolvedType("A", null), new List <VariableDeclaration>() { aParam }, new InstructionBlock( null, new List <Expression>() { new FunctionCall( null, "f", new List <Expression>() { aParam }), new ReturnStatement( null, new Variable( null, "a")), }), false); var program = new Program( null, new List <StructDeclaration>() { aDecl }, new List <FunctionDeclaration>() { f }); this.nameResolver.Run(program, null); Assert.AreEqual(StructType.GetInstance(aDecl), f.ReturnType); Assert.AreEqual(StructType.GetInstance(aDecl), aParam.VariableType); }
public void TestStruct() { var x = new VariableDeclaration( null, new UnresolvedType("A", null), "x", null); var kju = new FunctionDeclaration( null, "kju", UnitType.Instance, new List <VariableDeclaration>() { }, new InstructionBlock( null, new List <Expression>() { x, }), false); var globalADecl = new StructDeclaration( null, "A", new List <StructField>() { new StructField(null, "a", new UnresolvedType("A", null)) }); var program = new Program( null, new List <StructDeclaration>() { globalADecl }, new List <FunctionDeclaration>() { kju }); this.nameResolver.Run(program, null); Assert.AreEqual(StructType.GetInstance(globalADecl), x.VariableType); Assert.AreEqual(StructType.GetInstance(globalADecl), globalADecl.Fields[0].Type); }
private void ProcessProgram(Program program, IDiagnostics diagnostics) { this.functionBlocks.Push(new Dictionary <string, List <FunctionDeclaration> >()); this.variableBlocks.Push(new HashSet <string>()); this.structBlocks.Push(new HashSet <string>()); foreach (var fun in program.Functions) { var id = fun.Identifier; if (!this.functions.ContainsKey(id)) { this.functions.Add(id, new Stack <List <FunctionDeclaration> >()); } this.AddToPeek(id, fun); } foreach (var structDecl in program.Structs) { if (this.structs.ContainsKey(structDecl.Name)) { var diagnostic = new Diagnostic( DiagnosticStatus.Error, MultipleDeclarationsDiagnostic, $"Multiple declarations of struct {structDecl.Name}", new List <Range> { structDecl.InputRange }); diagnostics.Add(diagnostic); this.exceptions.Add(new NameResolverInternalException($"Multiple declarations struct {structDecl.Name}")); } this.dataTypes[structDecl.Name] = StructType.GetInstance(structDecl); this.structs[structDecl.Name] = new Stack <StructDeclaration>(); this.structs[structDecl.Name].Push(structDecl); this.structBlocks.Peek().Add(structDecl.Name); } this.functionBlocks.Push(new Dictionary <string, List <FunctionDeclaration> >()); this.variableBlocks.Push(new HashSet <string>()); this.structBlocks.Push(new HashSet <string>()); }
public void TestStructAlloc() { var aDecl = new StructDeclaration( null, "A", new List <StructField>()); var aAlloc = new StructAlloc( null, new UnresolvedType("A", null)); var kju = new FunctionDeclaration( null, "kju", UnitType.Instance, new List <VariableDeclaration>(), new InstructionBlock( null, new List <Expression>() { aAlloc }), false); var program = new Program( null, new List <StructDeclaration>() { aDecl }, new List <FunctionDeclaration>() { kju }); this.nameResolver.Run(program, null); Assert.AreEqual(StructType.GetInstance(aDecl), aAlloc.AllocType); }
private void CollectTypes(Node node, HashSet <DataType> dataTypes) { foreach (var child in node.Children()) { this.CollectTypes(child, dataTypes); } switch (node) { case FunctionDeclaration functionDeclaration: if (functionDeclaration.Function?.ClosureType != null) // only to make testing easier { this.AddTypeWithSubtypes(functionDeclaration.Function.ClosureType, dataTypes); } break; default: break; } if (node is Expression) { this.AddTypeWithSubtypes(((Expression)node).Type, dataTypes); switch (node) { case StructDeclaration structDeclaration: this.AddTypeWithSubtypes(StructType.GetInstance(structDeclaration), dataTypes); break; case VariableDeclaration variableDeclaration: this.AddTypeWithSubtypes(variableDeclaration.VariableType, dataTypes); break; } } }
private void ProcessStructDeclaration(StructDeclaration structDeclaration, IDiagnostics diagnostics) { string name = structDeclaration.Name; if (this.structBlocks.Peek().Contains(name)) { var diagnostic = new Diagnostic( DiagnosticStatus.Error, MultipleDeclarationsDiagnostic, $"Multiple declarations of struct {name}", new List <Range> { structDeclaration.InputRange }); diagnostics.Add(diagnostic); this.exceptions.Add(new NameResolverInternalException($"Multiple declarations struct {name}")); } if (this.buildInTypes.Contains(name)) { var diagnostic = new Diagnostic( DiagnosticStatus.Error, TypeIdentifierErrorDiagnosticsType, $"Cannot use builtin type name {name}", new List <Range> { structDeclaration.InputRange }); diagnostics.Add(diagnostic); this.exceptions.Add(new NameResolverInternalException($"Cannot use builtin type name {name}")); } if (!this.structs.ContainsKey(name)) { this.structs.Add(name, new Stack <StructDeclaration>()); } this.structs[name].Push(structDeclaration); this.structBlocks.Peek().Add(name); this.dataTypes[name] = StructType.GetInstance(structDeclaration); var fieldNames = new HashSet <string>(); foreach (var field in structDeclaration.Fields) { var fieldName = field.Name; if (fieldNames.Contains(fieldName)) { var diagnostic = new Diagnostic( DiagnosticStatus.Error, MultipleDeclarationsDiagnostic, $"Multiple declarations of field: {fieldName} in struct: {name}", new List <Range> { structDeclaration.InputRange }); diagnostics.Add(diagnostic); this.exceptions.Add(new NameResolverInternalException($"Multiple field declarations struct {name}")); } fieldNames.Add(fieldName); } foreach (var field in structDeclaration.Fields) { field.Type = this.ResolveDataType(field.Type, diagnostics); } }
private IEnumerable <Clause> GenerateClauses(Expression node) { switch (node) { case NullLiteral _: break; case InstructionBlock _: case FunctionDeclaration _: case StructDeclaration _: case BreakStatement _: case ContinueStatement _: yield return(this.EqualityClause(node, UnitType.Instance)); break; case VariableDeclaration decl: if (decl.Value != null) { yield return(this.EqualityClause(decl.Value, decl.VariableType)); } yield return(this.EqualityClause(node, UnitType.Instance)); break; case WhileStatement whileNode: yield return(this.EqualityClause(whileNode.Condition, BoolType.Instance)); yield return(this.EqualityClause(node, UnitType.Instance)); break; case IfStatement ifNode: yield return(this.EqualityClause(ifNode.Condition, BoolType.Instance)); yield return(this.EqualityClause(node, UnitType.Instance)); break; case FunctionCall funCall: { Clause clause = this.OverloadsClause(funCall); this.callOptions[funCall] = clause; yield return(clause); break; } case ReturnStatement returnNode: yield return(returnNode.Value == null ? this.EqualityClause(this.returnType.Peek(), UnitType.Instance, returnNode) : this.EqualityClause(returnNode.Value, this.returnType.Peek())); yield return(this.EqualityClause(returnNode, returnNode.Value?.Type ?? UnitType.Instance)); break; case Variable variable: yield return(this.EqualityClause(variable, variable.Declaration.VariableType)); break; case BoolLiteral boolNode: yield return(this.EqualityClause(boolNode, BoolType.Instance)); break; case IntegerLiteral integerNode: yield return(this.EqualityClause(integerNode, IntType.Instance)); break; case UnitLiteral unitNode: yield return(this.EqualityClause(unitNode, UnitType.Instance)); break; case Assignment assignment: yield return(this.EqualityClause(assignment.Value, assignment.Lhs.Declaration.VariableType)); yield return(this.EqualityClause(assignment, assignment.Value.Type)); break; case CompoundAssignment assignment: yield return(this.EqualityClause(assignment.Lhs.Declaration.VariableType, IntType.Instance, assignment.Lhs)); yield return(this.EqualityClause(assignment.Value, IntType.Instance)); yield return(this.EqualityClause(assignment, IntType.Instance)); break; case ArithmeticOperation operationNode: yield return(this.EqualityClause(operationNode.LeftValue, IntType.Instance)); yield return(this.EqualityClause(operationNode.RightValue, IntType.Instance)); yield return(this.EqualityClause(operationNode, IntType.Instance)); break; case Comparison cmp: { switch (cmp.OperationType) { case ComparisonType.Equal: case ComparisonType.NotEqual: yield return(this.EqualityClause(cmp.LeftValue.Type, cmp.RightValue.Type, cmp)); break; case ComparisonType.Less: case ComparisonType.LessOrEqual: case ComparisonType.Greater: case ComparisonType.GreaterOrEqual: yield return(this.EqualityClause(cmp.LeftValue, IntType.Instance)); yield return(this.EqualityClause(cmp.RightValue, IntType.Instance)); break; } yield return(this.EqualityClause(cmp, BoolType.Instance)); break; } case UnaryOperation op: { IHerbrandObject type = UnaryOperationToType[op.UnaryOperationType]; yield return(this.EqualityClause(op.Value, type)); yield return(this.EqualityClause(op, type)); break; } case LogicalBinaryOperation op: yield return(this.EqualityClause(op.LeftValue, BoolType.Instance)); yield return(this.EqualityClause(op.RightValue, BoolType.Instance)); yield return(this.EqualityClause(op, BoolType.Instance)); break; case ArrayAlloc alloc: yield return(this.EqualityClause(alloc.Size, IntType.Instance)); yield return(this.EqualityClause(alloc, new ArrayType(alloc.ElementType))); break; case ArrayAccess access: yield return(this.EqualityClause(access.Index, IntType.Instance)); yield return(this.EqualityClause(access.Lhs, new ArrayType(access.Type))); break; case ComplexAssignment assignment: yield return(this.EqualityClause(assignment.Lhs, assignment.Value.Type)); yield return(this.EqualityClause(assignment, assignment.Value.Type)); break; case ComplexCompoundAssignment assignment: yield return(this.EqualityClause(assignment.Lhs, IntType.Instance)); yield return(this.EqualityClause(assignment.Value, IntType.Instance)); yield return(this.EqualityClause(assignment, IntType.Instance)); break; case FieldAccess access: yield return(this.StructCandidatesClause(access)); break; case StructAlloc alloc: yield return(this.EqualityClause(alloc, StructType.GetInstance(alloc.Declaration))); break; case Application app: yield return(this.EqualityClause( app.Function, new FunType(app.Arguments.Select(arg => arg.Type), app.Type))); break; case UnApplication unapp: { Clause clause = new Clause( unapp.Candidates .Select(decl => new Alternative { (unapp.Type, new FunType(decl)) }) .ToList(), unapp.InputRange); this.unappOptions[unapp] = clause; yield return(clause); break; }
public void TestStructShadowing() { var innerADecl = new StructDeclaration( null, "A", new List <StructField>() { new StructField(null, "b", IntType.Instance) }); var globalADecl = new StructDeclaration( null, "A", new List <StructField>() { new StructField(null, "a", IntType.Instance) }); var x1 = new VariableDeclaration( null, new UnresolvedType("A", null), "x1", null); var x2 = new VariableDeclaration( null, new UnresolvedType("A", null), "x2", null); var y = new VariableDeclaration( null, new UnresolvedType("A", null), "y", null); var kju = new FunctionDeclaration( null, "kju", UnitType.Instance, new List <VariableDeclaration>() { }, new InstructionBlock( null, new List <Expression>() { x1, new InstructionBlock(null, new List <Expression>() { innerADecl, y, }), x2, }), false); var program = new Program( null, new List <StructDeclaration>() { globalADecl }, new List <FunctionDeclaration>() { kju }); this.nameResolver.Run(program, null); Assert.AreEqual(StructType.GetInstance(globalADecl), x1.VariableType); Assert.AreEqual(StructType.GetInstance(globalADecl), x2.VariableType); Assert.AreEqual(StructType.GetInstance(innerADecl), y.VariableType); }
public void TestComplex() { /* * def kju() : Unit { * struct P { * x : [Int]; * }; * * struct S { * x : Int; * y : P; * }; * * var s : [S] = new(S, 10); * var arr : [[Bool]] = new([Bool], 20); * } */ var dummyRange = new Core.Lexer.Range(new StringLocation(0), new StringLocation(0)); var pFields = new List <StructField>() { new StructField(dummyRange, "x", new ArrayType(IntType.Instance)) }; var pDeclaration = new StructDeclaration(dummyRange, "P", pFields); var pType = StructType.GetInstance(pDeclaration); var sFields = new List <StructField>() { new StructField(dummyRange, "x", IntType.Instance), new StructField(dummyRange, "y", pType) }; var sDeclaration = new StructDeclaration(dummyRange, "S", sFields); var sType = StructType.GetInstance(sDeclaration); var sAlloc = new ArrayAlloc( dummyRange, sType, new IntegerLiteral(dummyRange, 10)); var sVarDeclaration = new VariableDeclaration( dummyRange, new ArrayType(sType), "s", sAlloc); var arrAlloc = new ArrayAlloc( dummyRange, new ArrayType(BoolType.Instance), new IntegerLiteral(dummyRange, 20)); var arrVarDeclaration = new VariableDeclaration( dummyRange, new ArrayType(new ArrayType(BoolType.Instance)), "arr", arrAlloc); var kjuInstructions = new List <Expression> { pDeclaration, sDeclaration, sVarDeclaration, arrVarDeclaration }; var kjuDeclaration = new FunctionDeclaration( dummyRange, "kju", new ArrayType(UnitType.Instance), new List <VariableDeclaration>(), new InstructionBlock(dummyRange, kjuInstructions), false); var root = new Program(dummyRange, new List <StructDeclaration>(), new List <FunctionDeclaration> { kjuDeclaration }); var expectedTypes = new HashSet <DataType>() { pType, sType, new ArrayType(BoolType.Instance), new ArrayType(IntType.Instance), new ArrayType(sType), new ArrayType(new ArrayType(BoolType.Instance)) }; this.CheckAnswer(root, expectedTypes); }