private static void TryCollectFunctionDef(Context ctx, diagn.Reporter reporter, mod.Unit unit, syn.Node.FunctionDef node) { if (node == null) { return; } var hDef = ctx.defs.Reserve(); ctx[hDef] = new sema.Def.Function(); ctx[hDef].spanDef = node.span; unit.semanticMap.def[node] = hDef; if (node.name != null) { var identifierToken = (node.name as syn.Node.Identifier).token; ctx[hDef].spanDefName = identifierToken.span; var namespaceNode = ctx.names.FindOrReserve(identifierToken.excerpt); if (namespaceNode.item != null) { ReportDuplicate(ctx, reporter, identifierToken.span, namespaceNode); } else { namespaceNode.item = new sema.Namespace.Item.Def { def = hDef }; ctx[hDef].namespaceNode = namespaceNode; unit.semanticMap.references[node] = namespaceNode; unit.semanticMap.references[node.name] = namespaceNode; } } }
public static void Parse(Context ctx, diagn.Reporter reporter, H <mod.Unit> hUnit) { var unit = ctx[hUnit]; var parser = new Parser { ctx = ctx, reporter = reporter, tokens = unit.tokens, index = 0, indexPrevious = 0, insideCondition = new Stack <bool>() }; parser.insideCondition.Push(false); parser.SkipIgnorable(); try { unit.ast = parser.ParseTopLevel(); unit.ast.AddChildrenSpansRecursively(); } catch (ParseException) { unit.ast = new Node.TopLevel(); } }
public static sema.Type ResolveFunction(Context ctx, diagn.Reporter reporter, syn.Node.TypeFunction node) { if (node == null) { return(null); } var fn = new sema.Type.Function(); foreach (var elem in node.parameters) { fn.parameters.Add(Resolve(ctx, reporter, elem)); } if (node.returnType == null) { fn.returnType = new sema.Type.Tuple(); } else { fn.returnType = Resolve(ctx, reporter, node.returnType); } return(fn); }
public static sema.Type ResolveStructure(Context ctx, diagn.Reporter reporter, syn.Node.TypeStructure node) { if (node == null) { return(null); } var nodeName = node.name as syn.Node.Identifier; var name = nodeName.token.excerpt; var namespaceNode = ctx.names.Find(name); if (namespaceNode == null) { reporter.Error("unknown `" + name + "`", new diagn.Caret(nodeName.span)); return(new sema.Type.Error()); } var namespaceItem = namespaceNode.item as sema.Namespace.Item.Def; var defStructure = ctx[namespaceItem.def] as sema.Def.Structure; if (defStructure == null) { reporter.Error("`" + name + "` is not a type", new diagn.Caret(nodeName.span)); return(new sema.Type.Error()); } return(new sema.Type.Structure { def = namespaceItem.def }); }
public static void Tokenize(Context ctx, diagn.Reporter reporter, H <mod.Unit> hUnit) { var unit = ctx[hUnit]; var src = unit.ReadSource(ctx); var index = 0; unit.tokens = new List <syn.Token>(); while (index < src.Length) { var match = TryMatchFixed(src, index) ?? TryMatchFilter(syn.TokenKind.Whitespace, src, index, IsWhitespace, IsWhitespace) ?? TryMatchFilter(syn.TokenKind.Identifier, src, index, IsIdentifierPrefix, IsIdentifier) ?? TryMatchFilter(syn.TokenKind.Number, src, index, IsNumberPrefix, IsNumber) ?? new Match(src[index].ToString(), syn.TokenKind.Error); var span = new diagn.Span(hUnit, index, index + match.excerpt.Length); if (match.kind == syn.TokenKind.Error) { reporter.Error("unexpected character", new diagn.Caret(span)); } unit.tokens.Add(new syn.Token { span = span, kind = match.kind, excerpt = match.excerpt }); index += match.excerpt.Length; } }
private static void ResolveNode(Context ctx, diagn.Reporter reporter, mod.Unit unit, syn.Node node) { TryResolveIdentifier(ctx, reporter, unit, node as syn.Node.Identifier); foreach (var child in node.Children()) { ResolveNode(ctx, reporter, unit, child); } }
private static void ResolveNode(Context ctx, diagn.Reporter reporter, mod.Unit unit, syn.Node node) { TryCollectFunctionDef(ctx, reporter, unit, node as syn.Node.FunctionDef); foreach (var child in node.Children()) { ResolveNode(ctx, reporter, unit, child); } }
private CodeResolver(Context ctx, diagn.Reporter reporter, sema.Code.Body code) { this.ctx = ctx; this.reporter = reporter; this.code = code; for (var i = 0; i < code.registers.Count; i++) { this.registersInScope.Add(true); } }
private static void TryCollectFunctionDef(Context ctx, diagn.Reporter reporter, mod.Unit unit, syn.Node.FunctionDef node) { if (node == null) { return; } var hDef = unit.semanticMap.def[node]; if (hDef == null) { reporter.InternalError("def not found for node", new diagn.Caret(node.span)); } else { var functionDef = ctx[hDef] as sema.Def.Function; functionDef.body = new sema.Code.Body(); if (node.returnType == null) { functionDef.body.registers.Add(new sema.Code.Register { type = new sema.Type.Tuple() }); } else { functionDef.body.registers.Add(new sema.Code.Register { spanDef = node.returnType.span, type = TypeResolver.Resolve(ctx, reporter, node.returnType) }); } foreach (var child in node.parameters) { var nodeParameter = child as syn.Node.FunctionDefParameter; var nodeIdentifier = nodeParameter.identifier as syn.Node.Identifier; var parameterName = nodeIdentifier.token.excerpt; var parameterType = TypeResolver.Resolve(ctx, reporter, nodeParameter.type); functionDef.body.parameterCount++; functionDef.body.registers.Add(new sema.Code.Register { spanDef = nodeParameter.span, spanDefName = nodeIdentifier.span, name = parameterName, type = parameterType }); } } }
public static void ResolveFunctionBody(Context ctx, diagn.Reporter reporter, sema.Code.Body body, syn.Node node) { var resolver = new CodeResolver(ctx, reporter, body); var segment = body.CreateSegment(); var destination = new sema.Code.Lvalue.Register { index = 0 }; resolver.ResolveExpr(ref segment, destination, node); }
public static sema.Type ResolveRefCounted(Context ctx, diagn.Reporter reporter, syn.Node.TypeRefCounted node) { if (node == null) { return(null); } return(new sema.Type.RefCounted { mutable = node.mutable, innerType = Resolve(ctx, reporter, node.innerType) }); }
public static sema.Type ResolveTuple(Context ctx, diagn.Reporter reporter, syn.Node.TypeTuple node) { if (node == null) { return(null); } var tuple = new sema.Type.Tuple(); foreach (var elem in node.elements) { tuple.types.Add(Resolve(ctx, reporter, elem)); } return(tuple); }
public static sema.Type Resolve(Context ctx, diagn.Reporter reporter, syn.Node node) { var type = ResolveStructure(ctx, reporter, node as syn.Node.TypeStructure) ?? ResolvePointer(ctx, reporter, node as syn.Node.TypePointer) ?? ResolveRefCounted(ctx, reporter, node as syn.Node.TypeRefCounted) ?? ResolveTuple(ctx, reporter, node as syn.Node.TypeTuple) ?? ResolveFunction(ctx, reporter, node as syn.Node.TypeFunction); if (type == null) { reporter.InternalError("node is not a type", new diagn.Caret(node.span)); return(new sema.Type.Error()); } return(type); }
private static void TryCollectStructureDef(Context ctx, diagn.Reporter reporter, mod.Unit unit, syn.Node.StructureDef node) { if (node == null) { return; } var hDef = unit.semanticMap.def[node]; if (hDef == null) { reporter.InternalError("def not found for node", new diagn.Caret(node.span)); } else { var structureDef = ctx[hDef] as sema.Def.Structure; foreach (var child in node.fields) { var nodeField = child as syn.Node.StructureDefField; var nodeIdentifier = nodeField.identifier as syn.Node.Identifier; var fieldName = nodeIdentifier.token.excerpt; var duplicateField = structureDef.fields.Find(f => f.name == fieldName); if (duplicateField != null) { reporter.Error("duplicate field `" + fieldName + "`", new diagn.Caret(duplicateField.spanDefName, false), new diagn.Caret(nodeIdentifier.span)); } var fieldType = TypeResolver.Resolve(ctx, reporter, nodeField.type); structureDef.fields.Add(new sema.Def.Structure.Field { spanDef = nodeField.span, spanDefName = nodeIdentifier.span, name = fieldName, type = fieldType }); } } }
private static void TryCollectFunctionDef(Context ctx, diagn.Reporter reporter, mod.Unit unit, syn.Node.FunctionDef node) { if (node == null) { return; } var hDef = unit.semanticMap.def[node]; if (hDef == null) { reporter.InternalError("def not found for node", new diagn.Caret(node.span)); } else { var functionDef = ctx[hDef] as sema.Def.Function; CodeResolver.ResolveFunctionBody(ctx, reporter, functionDef.body, node.body); } }
private static void TryResolveIdentifier(Context ctx, diagn.Reporter reporter, mod.Unit unit, syn.Node.Identifier node) { if (node == null) { return; } if (unit.semanticMap.references.ContainsKey(node)) { return; } var identifier = node.token.excerpt; var hNamespaceNode = ctx.names.Find(identifier); if (hNamespaceNode != null) { unit.semanticMap.references[node] = hNamespaceNode; } }
private static void ReportDuplicate(Context ctx, diagn.Reporter reporter, diagn.Span newSpan, sema.Namespace.Node originalNode) { var originalSpan = (diagn.Span)null; var originalItemDef = originalNode.item as sema.Namespace.Item.Def; if (originalItemDef != null) { originalSpan = ctx[originalItemDef.def].spanDefName; } if (originalSpan != null) { reporter.Error( "duplicate definition of `" + ctx.names.PrintableFullKeyOf(originalNode) + "`", new diagn.Caret(newSpan), new diagn.Caret(originalSpan, false)); } else { reporter.Error( "duplicate definition of `" + ctx.names.PrintableFullKeyOf(originalNode) + "`", new diagn.Caret(newSpan)); } }
public static void Resolve(Context ctx, diagn.Reporter reporter, H <mod.Unit> hUnit) { var unit = ctx[hUnit]; ResolveNode(ctx, reporter, unit, unit.ast); }
public static void Collect(Context ctx, diagn.Reporter reporter, H <mod.Unit> hUnit) { var unit = ctx[hUnit]; CollectAtNode(ctx, reporter, unit, unit.ast); }