コード例 #1
0
ファイル: Contract.cs プロジェクト: mpmedia/Excess
        private static SyntaxNode ProcessContract(SyntaxNode node, Scope scope, SyntacticalExtension<SyntaxNode> extension)
        {
            if (extension.Kind == ExtensionKind.Code)
            {
                var block = extension.Body as BlockSyntax;
                Debug.Assert(block != null);

                List<StatementSyntax> checks = new List<StatementSyntax>();
                foreach (var st in block.Statements)
                {
                    var stExpression = st as ExpressionStatementSyntax;
                    if (stExpression == null)
                    {
                        scope.AddError("contract01", "contracts only support boolean expressions", st);
                        continue;
                    }

                    var contractCheck = ContractCheck
                        .ReplaceNodes(ContractCheck
                            .DescendantNodes()
                            .OfType<ExpressionSyntax>()
                            .Where(expr => expr.ToString() == "__condition"),

                         (oldNode, newNode) =>
                            stExpression.Expression);

                    checks.Add(contractCheck);
                }

                return CSharp.Block(checks);
            }

            scope.AddError("contract02", "contract cannot return a value", node);
            return node;
        }
コード例 #2
0
ファイル: Contract.cs プロジェクト: zihotki/Excess
        private static SyntaxNode ProcessContract(SyntaxNode node, Scope scope, SyntacticalExtension <SyntaxNode> extension)
        {
            if (extension.Kind == ExtensionKind.Code)
            {
                var block = extension.Body as BlockSyntax;
                Debug.Assert(block != null);

                List <StatementSyntax> checks = new List <StatementSyntax>();
                foreach (var st in block.Statements)
                {
                    var stExpression = st as ExpressionStatementSyntax;
                    if (stExpression == null)
                    {
                        scope.AddError("contract01", "contracts only support boolean expressions", st);
                        continue;
                    }

                    var contractCheck = ContractCheck
                                        .ReplaceNodes(ContractCheck
                                                      .DescendantNodes()
                                                      .OfType <ExpressionSyntax>()
                                                      .Where(expr => expr.ToString() == "__condition"),

                                                      (oldNode, newNode) =>
                                                      stExpression.Expression);

                    checks.Add(contractCheck);
                }

                return(CSharp.Block(checks));
            }

            scope.AddError("contract02", "contract cannot return a value", node);
            return(node);
        }
コード例 #3
0
ファイル: Extension.cs プロジェクト: tylike/Excess
        private static SyntaxNode ParseContract(BlockSyntax block, Scope scope)
        {
            List <StatementSyntax> checks = new List <StatementSyntax>();

            foreach (var st in block.Statements)
            {
                var stExpression = st as ExpressionStatementSyntax;
                if (stExpression == null)
                {
                    scope.AddError("contract01", "contracts only support boolean expressions", st);
                    continue;
                }

                var expr = stExpression.Expression as BinaryExpressionSyntax;
                if (expr != null && expr.OperatorToken.IsKind(SyntaxKind.GreaterThanGreaterThanToken))
                {
                    var exprAssign = expr.Right as InvocationExpressionSyntax;
                    if (exprAssign == null)
                    {
                        scope.AddError("contract02", "contracts only invocations on the right side of >>", st);
                        continue;
                    }

                    var throwExpr = ContractCheckWithException
                                    .Get <StatementSyntax>(
                        expr.Left,
                        exprAssign.Expression);

                    var newExpr = throwExpr
                                  .DescendantNodes()
                                  .OfType <ObjectCreationExpressionSyntax>()
                                  .Single();

                    checks.Add(throwExpr.ReplaceNode(newExpr,
                                                     newExpr.WithArgumentList(exprAssign.ArgumentList)));
                }
                else
                {
                    checks.Add(ContractCheck
                               .Get <StatementSyntax>(stExpression.Expression));
                }
            }

            return(CSharp.Block(checks));
        }
コード例 #4
0
ファイル: TypeDef.cs プロジェクト: zihotki/Excess
        private static SyntaxNode Typedef(SyntaxNode node, Scope scope)
        {
            var field = node
                        .AncestorsAndSelf()
                        .OfType <FieldDeclarationSyntax>()
                        .FirstOrDefault();

            if (field == null)
            {
                scope.AddError("xs01", "malformed typedef", node);
                //td: error, malformed typedef
                return(node);
            }


            if (field.Declaration.Variables.Count != 1)
            {
                scope.AddError("xs01", "malformed typedef", node);
                return(node);
            }

            var variable = field
                           .Declaration
                           .Variables[0];

            Debug.Assert(variable.Initializer == null || variable.Initializer.IsMissing);

            var type       = RoslynCompiler.UnMark(field.Declaration.Type);
            var identifier = variable.Identifier;

            var parentScope = scope.CreateScope <SyntaxToken, SyntaxNode, SemanticModel>(field.Parent);

            Debug.Assert(parentScope != null);

            parentScope.set("__tdef" + identifier.ToString(), type);

            //schedule deletion
            var document = scope.GetDocument <SyntaxToken, SyntaxNode, SemanticModel>();

            document.change(field.Parent, RoslynCompiler.RemoveMember(field));

            //return intact
            return(node);
        }
コード例 #5
0
        private static SyntaxNode ProcessMatch(SyntaxNode node, Scope scope)
        {
            var switchExpr = node as SwitchStatementSyntax;

            if (switchExpr == null)
            {
                scope.AddError("match01", "malformed match", node);
                return(node);
            }

            //store items to simplify
            var cases            = new List <ExpressionSyntax>();
            var statements       = new List <StatementSyntax>();
            var defaultStatement = null as StatementSyntax;

            foreach (var section in switchExpr.Sections)
            {
                bool isDefault;
                var  expr = caseExpression(section.Labels, switchExpr.Expression, out isDefault);

                StatementSyntax statement = caseStatement(section.Statements);
                if (isDefault && section.Labels.Count == 1)
                {
                    defaultStatement = statement;
                }
                else
                {
                    cases.Add(expr);
                    statements.Add(statement);

                    if (isDefault)
                    {
                        defaultStatement = statement;
                    }
                }
            }

            //convert cases to ifs
            Debug.Assert(cases.Count == statements.Count);
            var last = cases.Count - 1;
            IfStatementSyntax result = CSharp.IfStatement(cases[last], statements[last]);

            if (defaultStatement != null)
            {
                result = result.WithElse(CSharp.ElseClause(defaultStatement));
            }


            for (int i = last - 1; i >= 0; i--)
            {
                result = CSharp.IfStatement(cases[i], statements[i])
                         .WithElse(CSharp.ElseClause(result));
            }

            return(result);
        }
コード例 #6
0
ファイル: Instance.cs プロジェクト: zihotki/Excess
        private static SyntaxNode TransformFoo(string id, object value, IEnumerable <InstanceConnection <SyntaxNode> > connections, Scope scope)
        {
            var decl = instanceCreation.Get(id, "RuntimeFoo");

            scope.AddInstanceDeclaration(decl
                                         .ReplaceNodes(decl
                                                       .DescendantNodes()
                                                       .OfType <ParameterListSyntax>(),
                                                       (on, nn) =>
            {
                var values = (value as InstanceFoo).Values;
                return(nn
                       .WithParameters(CSharp.SeparatedList(
                                           values.Select(val => CSharp.Parameter(CSharp.Literal(val))))));
            }));

            foreach (var connection in connections)
            {
                if (connection.Input == null)
                {
                    scope.AddError("test01", "unregistered connection", connection.OutputModelNode);
                    continue;
                }

                if (connection.Output == null)
                {
                    scope.AddError("test01", "unregistered connection", connection.InputModelNode);
                    continue;
                }

                if (connection.Source == id)
                {
                    connection.OutputNode = CSharp.ParseExpression(id + "." + connection.Output.Id);
                }
                else
                {
                    Assert.IsTrue(connection.Target == id);
                    connection.InputNode = CSharp.ParseExpression(id + "." + connection.Input.Id);
                }
            }

            return(null);
        }
コード例 #7
0
        private static SyntaxNode ProcessSynch(SyntaxNode node, Scope scope, SyntacticalExtension <SyntaxNode> extension)
        {
            if (extension.Kind == ExtensionKind.Code)
            {
                //td: verify it's inside an asynch
                return(SynchTemplate
                       .ReplaceNodes(SynchTemplate
                                     .DescendantNodes()
                                     .OfType <BlockSyntax>(),
                                     (oldNode, newNode) => extension.Body));
            }

            scope.AddError("synch01", "synch does not return a value", node);
            return(node);
        }
コード例 #8
0
ファイル: Asynch.cs プロジェクト: mpmedia/Excess
        private static SyntaxNode ProcessSynch(SyntaxNode node, Scope scope, SyntacticalExtension<SyntaxNode> extension)
        {
            if (extension.Kind == ExtensionKind.Code)
            {
                //td: verify it's inside an asynch
                return SynchTemplate
                    .ReplaceNodes(SynchTemplate
                        .DescendantNodes()
                        .OfType<BlockSyntax>(),
                        (oldNode, newNode) => extension.Body);
            }

            scope.AddError("synch01", "synch does not return a value", node);
            return node;
        }
コード例 #9
0
ファイル: Extension.cs プロジェクト: tylike/Excess
        private static void compileProperty(PropertyDeclarationSyntax property, Class ctx, Scope scope)
        {
            if (!Roslyn.IsVisible(property))
            {
                return;
            }

            var @get = null as AccessorDeclarationSyntax;
            var @set = null as AccessorDeclarationSyntax;

            foreach (var accesor in property.AccessorList.Accessors)
            {
                switch (accesor.Keyword.Kind())
                {
                case SyntaxKind.GetKeyword:
                    @get = accesor;
                    break;

                case SyntaxKind.SetKeyword:
                    @set = accesor;
                    break;

                default:
                    throw new NotImplementedException();
                }
            }

            bool hasCustomGet = @get != null && @get.Body != null && @get.Body.Statements.Count > 0;

            if (hasCustomGet && @get.Body.Statements.Count == 1)
            {
                hasCustomGet = !(@get.Body.Statements[0] is ReturnStatementSyntax);
            }

            bool hasCustomSet = @set != null && @set.Body != null && @set.Body.Statements.Count > 0;

            if (hasCustomSet && @set.Body.Statements.Count == 1)
            {
                hasCustomSet = !(@set.Body.Statements[0] is ExpressionStatementSyntax) ||
                               (@set.Body.Statements[0] as ExpressionStatementSyntax)
                               .Expression.Kind() != SyntaxKind.SimpleAssignmentExpression;
            }

            if (hasCustomGet || hasCustomSet)
            {
                scope.AddError("concurrent00", "invalid concurrent property, custom accessors are not allowed", property);
            }
        }
コード例 #10
0
        private static SyntaxNode Transform(SyntaxNode oldNode, SyntaxNode newNode, Scope scope, LexicalExtension <SyntaxToken> extension)
        {
            Debug.Assert(newNode is AnonymousObjectCreationExpressionSyntax);
            var result = createJson.Get(newNode);

            var isAssignment = false;

            result = Roslyn.ReplaceAssignment(oldNode, result, out isAssignment);
            if (!isAssignment)
            {
                scope.AddError("json01", "json expects to be assigned", oldNode);
                return(newNode);
            }

            return(result);
        }
コード例 #11
0
        private static SyntaxNode ProcessAsynch(SyntaxNode node, Scope scope, SyntacticalExtension <SyntaxNode> extension)
        {
            if (extension.Kind == ExtensionKind.Code)
            {
                var result = AsynchTemplate
                             .ReplaceNodes(AsynchTemplate
                                           .DescendantNodes()
                                           .OfType <BlockSyntax>(),
                                           (oldNode, newNode) => extension.Body);

                var document = scope.GetDocument <SyntaxToken, SyntaxNode, SemanticModel>();
                document.change(node.Parent, RoslynCompiler.AddStatement(ContextVariable, before: node));

                return(result);
            }

            scope.AddError("asynch01", "asynch does not return a value", node);
            return(node);
        }
コード例 #12
0
ファイル: Asynch.cs プロジェクト: mpmedia/Excess
        private static SyntaxNode ProcessAsynch(SyntaxNode node, Scope scope, SyntacticalExtension<SyntaxNode> extension)
        {
            if (extension.Kind == ExtensionKind.Code)
            {
                var result = AsynchTemplate
                    .ReplaceNodes(AsynchTemplate
                        .DescendantNodes()
                        .OfType<BlockSyntax>(),
                        (oldNode, newNode) => extension.Body);

                var document = scope.GetDocument<SyntaxToken, SyntaxNode, SemanticModel>();
                document.change(node.Parent, RoslynCompiler.AddStatement(ContextVariable, before: node));

                return result;
            }

            scope.AddError("asynch01", "asynch does not return a value", node);
            return node;
        }
コード例 #13
0
ファイル: TypeDef.cs プロジェクト: mpmedia/Excess
        private static SyntaxNode Typedef(SyntaxNode node, Scope scope)
        {
            var field = node
                .AncestorsAndSelf()
                .OfType<FieldDeclarationSyntax>()
                .FirstOrDefault();

            if (field == null)
            {
                scope.AddError("xs01", "malformed typedef", node);
                //td: error, malformed typedef
                return node;
            }

            if (field.Declaration.Variables.Count != 1)
            {
                scope.AddError("xs01", "malformed typedef", node);
                return node;
            }

            var variable = field
                .Declaration
                .Variables[0];

            Debug.Assert(variable.Initializer == null || variable.Initializer.IsMissing);

            var type = RoslynCompiler.UnMark(field.Declaration.Type);
            var identifier = variable.Identifier;

            var parentScope = scope.CreateScope<SyntaxToken, SyntaxNode, SemanticModel>(field.Parent);
            Debug.Assert(parentScope != null);

            parentScope.set("__tdef" + identifier.ToString(), type);

            //schedule deletion
            var document = scope.GetDocument<SyntaxToken, SyntaxNode, SemanticModel>();
            document.change(field.Parent, RoslynCompiler.RemoveMember(field));

            //return intact
            return node;
        }
コード例 #14
0
        private static SyntaxNode Transform(SyntaxNode oldNode, SyntaxNode newNode, Scope scope, LexicalExtension <SyntaxToken> extension)
        {
            Debug.Assert(newNode is BlockSyntax);
            var isAssignment = oldNode is LocalDeclarationStatementSyntax;

            if (!isAssignment && oldNode is BinaryExpressionSyntax)
            {
                var expr = oldNode as BinaryExpressionSyntax;
                isAssignment = expr.Kind() == SyntaxKind.SimpleAssignmentExpression;
            }

            if (isAssignment)
            {
                scope.AddError("r01", "R does not return", oldNode);
                return(newNode);
            }

            var document = scope.GetDocument <SyntaxToken, SyntaxNode, SemanticModel>();

            document.change(oldNode.Parent, RoslynCompiler.ExplodeBlock(newNode));

            return(newNode);
        }
コード例 #15
0
ファイル: Instance.cs プロジェクト: mpmedia/Excess
        private static SyntaxNode TransformFoo(string id, object value, IEnumerable<InstanceConnection<SyntaxNode>> connections, Scope scope)
        {
            var decl = instanceCreation.Get(id, "RuntimeFoo");
            scope.AddInstanceDeclaration(decl
                .ReplaceNodes(decl
                    .DescendantNodes()
                    .OfType<ParameterListSyntax>(),
                (on, nn) =>
                {
                    var values = (value as InstanceFoo).Values;
                    return nn
                        .WithParameters(CSharp.SeparatedList(
                            values.Select(val => CSharp.Parameter(CSharp.Literal(val)))));
                }));

            foreach (var connection in connections)
            {
                if (connection.Input == null)
                {
                    scope.AddError("test01", "unregistered connection", connection.OutputModelNode);
                    continue;
                }

                if (connection.Output == null)
                {
                    scope.AddError("test01", "unregistered connection", connection.InputModelNode);
                    continue;
                }

                if (connection.Source == id)
                    connection.OutputNode = CSharp.ParseExpression(id + "." + connection.Output.Id);
                else
                {
                    Assert.IsTrue(connection.Target == id);
                    connection.InputNode = CSharp.ParseExpression(id + "." + connection.Input.Id);
                }

            }

            return null;
        }
コード例 #16
0
ファイル: Match.cs プロジェクト: mpmedia/Excess
        private static SyntaxNode ProcessMatch(SyntaxNode node, Scope scope)
        {
            var switchExpr = node as SwitchStatementSyntax;
            if (switchExpr == null)
            {
                scope.AddError("match01", "malformed match", node);
                return node;
            }

            //store items to simplify
            var cases = new List<ExpressionSyntax>();
            var statements = new List<StatementSyntax>();
            var defaultStatement = null as StatementSyntax;

            foreach (var section in switchExpr.Sections)
            {
                bool isDefault;
                var expr = caseExpression(section.Labels, switchExpr.Expression, out isDefault);

                StatementSyntax statement = caseStatement(section.Statements);
                if (isDefault && section.Labels.Count == 1)
                {
                    defaultStatement = statement;
                }
                else
                {
                    cases.Add(expr);
                    statements.Add(statement);

                    if (isDefault)
                        defaultStatement = statement;
                }
            }

            //convert cases to ifs
            Debug.Assert(cases.Count == statements.Count);
            var last = cases.Count - 1;
            IfStatementSyntax result = CSharp.IfStatement(cases[last], statements[last]);

            if (defaultStatement != null)
                result = result.WithElse(CSharp.ElseClause(defaultStatement));

            for (int i = last - 1; i >= 0; i--)
            {
                result = CSharp.IfStatement(cases[i], statements[i])
                    .WithElse(CSharp.ElseClause(result));
            }

            return result;
        }
コード例 #17
0
ファイル: Extension.cs プロジェクト: mpmedia/Excess
        private static SyntaxNode Transform(SyntaxNode oldNode, SyntaxNode newNode, Scope scope, LexicalExtension<SyntaxToken> extension)
        {
            Debug.Assert(newNode is BlockSyntax);
            var isAssignment = oldNode is LocalDeclarationStatementSyntax;
            if (!isAssignment && oldNode is BinaryExpressionSyntax)
            {
                var expr = oldNode as BinaryExpressionSyntax;
                isAssignment = expr.Kind() == SyntaxKind.SimpleAssignmentExpression;
            }

            if (isAssignment)
            {
                scope.AddError("r01", "R does not return", oldNode);
                return newNode;
            }

            var document = scope.GetDocument<SyntaxToken, SyntaxNode, SemanticModel>();
            document.change(oldNode.Parent, RoslynCompiler.ExplodeBlock(newNode));

            return newNode;
        }
コード例 #18
0
ファイル: Extension.cs プロジェクト: tylike/Excess
        private static bool compileMethod(MethodDeclarationSyntax methodDeclaration, Class ctx, Scope scope, Options options, bool isSingleton)
        {
            var method = methodDeclaration;
            var name   = method.Identifier.ToString();
            var isMain = name == "main";

            var isProtected = method
                              .Modifiers
                              .Where(m => m.Kind() == SyntaxKind.ProtectedKeyword)
                              .Any();

            var isVisible = isProtected || Roslyn.IsVisible(method);
            var isStatic  = Roslyn.IsStatic(method);

            var hasReturnType = method.ReturnType.ToString() != "void";
            var returnType    = hasReturnType
                ? method.ReturnType
                : Roslyn.boolean;

            var isEmptySignal = method.Body == null ||
                                method.Body.IsMissing;

            if (isEmptySignal)
            {
                if (method.ParameterList.Parameters.Count > 0)
                {
                    scope.AddError("concurrent03", "empty signals cannot contain parameters", method);
                }

                if (method.ReturnType.ToString() != "void")
                {
                    scope.AddError("concurrent04", "empty signals cannot return values", method);
                }

                method = method
                         .WithSemicolonToken(CSharp.MissingToken(SyntaxKind.SemicolonToken))
                         .WithBody(CSharp.Block());
            }

            var cc = parseConcurrentBlock(ctx, method.Body, scope, isStatic);

            if (cc != null)
            {
                method = method.WithBody(cc);
            }

            //remove attributes, until needed
            method = method.WithAttributeLists(CSharp.List <AttributeListSyntax>());

            if (isMain)
            {
                if (ctx.HasMain)
                {
                    scope.AddError("concurrent06", "multiple main methods", method);
                    return(false);
                }

                ctx.HasMain = true;

                var statements  = method.Body.Statements;
                var isContinued = (cc == null) && checkContinued(statements);
                if (isContinued)
                {
                    method = method
                             .WithBody(CSharp.Block(statements
                                                    .Take(statements.Count - 1)));
                }

                var mainMethod = concurrentMethod(ctx, method);

                //hook up our start method
                int currentIndex = 0;
                ctx.Replace(methodDeclaration, Templates
                            .StartObject
                            .Get <MethodDeclarationSyntax>(Templates
                                                           .ConcurrentMain
                                                           .Get <InvocationExpressionSyntax>()
                                                           .WithArgumentList(CSharp.ArgumentList(CSharp.SeparatedList(
                                                                                                     mainMethod
                                                                                                     .ParameterList
                                                                                                     .Parameters
                                                                                                     .Where(param => param.Identifier.ToString() != "__cancellation" &&
                                                                                                            param.Identifier.ToString() != "__success" &&
                                                                                                            param.Identifier.ToString() != "__failure")
                                                                                                     .Select(param => CSharp.Argument(Templates
                                                                                                                                      .StartObjectArgument
                                                                                                                                      .Get <ExpressionSyntax>(
                                                                                                                                          param.Type,
                                                                                                                                          currentIndex++)))
                                                                                                     .Union(new[] {
                    CSharp.Argument(Templates.NullCancelationToken),
                    CSharp.Argument(Roslyn.@null),
                    CSharp.Argument(Roslyn.@null),
                }))))));

                return(false);
            }

            if (isVisible)
            {
                if (isEmptySignal)
                {
                    Debug.Assert(!isStatic); //td: error
                    ctx.AddMember(Templates
                                  .EmptySignalMethod
                                  .Get <MethodDeclarationSyntax>(
                                      "__concurrent" + name,
                                      Roslyn.Quoted(name),
                                      isProtected ? Roslyn.@true : Roslyn.@false));
                }
                else
                {
                    concurrentMethod(ctx, method, asVirtual: options.GenerateRemote);
                }
            }
            else if (cc != null)
            {
                concurrentMethod(ctx, method);
            }
            else if (isEmptySignal)
            {
                ctx.AddMember(Templates
                              .EmptySignalMethod
                              .Get <MethodDeclarationSyntax>(
                                  "__concurrent" + name,
                                  Roslyn.Quoted(name),
                                  isProtected? Roslyn.@true : Roslyn.@false));
            }
            else
            {
                return(false);
            }

            var signal = ctx.AddSignal(name, returnType, isVisible, isStatic);

            if (isVisible)
            {
                method = createPublicSignals(ctx, method, signal, isSingleton);
                if (isSingleton)
                {
                    ctx.Replace(methodDeclaration, method);
                }
            }
            else
            {
                ctx.Replace(methodDeclaration, method
                            .WithBody(CSharp.Block()
                                      .WithStatements(CSharp.List(new[] {
                    isEmptySignal
                                ? Templates.SignalDispatcher.Get <StatementSyntax>(Roslyn.Quoted(method.Identifier.ToString()))
                                : Templates.PrivateSignal
                }))));
                return(false);
            }

            return(true);
        }
コード例 #19
0
ファイル: AntlrErrors.cs プロジェクト: zihotki/Excess
 public void SyntaxError(IRecognizer recognizer, TToken offendingSymbol, int line, int charPositionInLine, string msg, RecognitionException e)
 {
     _scope.AddError("grammar syntax error", msg, _offset + offendingSymbol.StartIndex, offendingSymbol.StopIndex - offendingSymbol.StartIndex);
 }