예제 #1
0
        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;
                }
            }
        }
예제 #2
0
        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();
            }
        }
예제 #3
0
        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);
        }
예제 #4
0
        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
            });
        }
예제 #5
0
        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;
            }
        }
예제 #6
0
        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);
            }
        }
예제 #7
0
        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);
            }
        }
예제 #8
0
        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);
            }
        }
예제 #9
0
        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
                    });
                }
            }
        }
예제 #10
0
        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);
        }
예제 #11
0
        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)
            });
        }
예제 #12
0
        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);
        }
예제 #13
0
        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);
        }
예제 #14
0
        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
                    });
                }
            }
        }
예제 #15
0
        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);
            }
        }
예제 #16
0
        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;
            }
        }
예제 #17
0
        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));
            }
        }
예제 #18
0
        public static void Resolve(Context ctx, diagn.Reporter reporter, H <mod.Unit> hUnit)
        {
            var unit = ctx[hUnit];

            ResolveNode(ctx, reporter, unit, unit.ast);
        }
예제 #19
0
        public static void Collect(Context ctx, diagn.Reporter reporter, H <mod.Unit> hUnit)
        {
            var unit = ctx[hUnit];

            CollectAtNode(ctx, reporter, unit, unit.ast);
        }