コード例 #1
0
        public ParameterDefinition(LittleBigCParser.FormalParameterContext context)
        {
            _context = context;

            var type = _context.variableType().simpleVariableType().GetText().ToString();

            _variableType = VariableDefinition.VariableTypes[type];
        }
コード例 #2
0
ファイル: ArgumentsListener.cs プロジェクト: mdelol/Compiler
        public override void EnterConstant(LittleBigCParser.ConstantContext context)
        {
            var stringConstant = context.StringConstant();

            if (stringConstant != null)
            {
                StringConstant = stringConstant.GetText().Replace("\"", String.Empty);
            }
        }
コード例 #3
0
        public TreeViewControl(ParserRuleContext root, LittleBigCParser parser)
        {
            InitializeComponent();

            var rootViewModel = new NodeViewModel(root, null, parser);

            _treeViewModel = new TreeViewModel(rootViewModel);

            base.DataContext = _treeViewModel;
        }
コード例 #4
0
ファイル: TypeCheckListener.cs プロジェクト: mdelol/Compiler
        public override void EnterAssignmentExpression(LittleBigCParser.AssignmentExpressionContext context)
        {
            if (context.postfixExpression() != null)
            {
                var ident = context.postfixExpression().primaryExpression().Identifier();
                var variableName = ident.GetText();

                VariableDefinition variable;

                var error = new StringBuilder();

                variable = _scope.GetVariableDefinition(variableName);

                if (variable == null)
                {
                    variable = _semantic.GlobalScope.GetVariableDefinition(variableName);
                }

                if (variable == null)
                {
                    var parameterDef = _scope.GetParameterDefinition(variableName);

                    if (parameterDef == null)
                    {
                        error.Append(String.Format("[{0}:{1}] Semantic error: ", ident.Symbol.Line, ident.Symbol.StartIndex));
                        error.Append(String.Format("Variable {0} undefinded.", variableName));

                        Errors.Add(error.ToString());
                    }
                    else
                    {
                        if (parameterDef.VariableType != _targetType)
                        {
                            error.Append(String.Format("[{0}:{1}] Semantic error: Type mismatch. ", ident.Symbol.Line, ident.Symbol.StartIndex));
                            error.Append(String.Format("{0} expected, but {1} found.", _targetType.ToString(), parameterDef.VariableType.ToString()));

                            Errors.Add(error.ToString());
                        }
                    }
                }
                else
                {
                    if (variable.VariableType != _targetType)
                    {
                        error.Append(String.Format("[{0}:{1}] Semantic error: Type mismatch. ", ident.Symbol.Line, ident.Symbol.StartIndex));
                        error.Append(String.Format("{0} expected, but {1} found.", _targetType.ToString(), variable.VariableType.ToString()));

                        Errors.Add(error.ToString());
                    }
                }

                _targetType = variable.VariableType;
            }
        }
コード例 #5
0
        public override void EnterFunctionDefinition(LittleBigCParser.FunctionDefinitionContext context)
        {
            var functionName = context.Identifier().GetText();

            if (functionName == "main")
            {
                _hasEntryPoint = true;

                _entryMethod = _typeBuilder.DefineMethod("main",
                    MethodAttributes.HideBySig | MethodAttributes.Static | MethodAttributes.Public,
                    typeof(void), new Type[] { typeof(string[]) });
            }
        }
コード例 #6
0
ファイル: NodeViewModel.cs プロジェクト: mdelol/Compiler
        public NodeViewModel(ParserRuleContext node, NodeViewModel parent, LittleBigCParser parser)
        {
            _parent = parent;
            _text = parser.RuleNames[node.RuleIndex];

            var children = new List<NodeViewModel>();

            if (node.children != null)
            {
                foreach (var child in node.children)
                {
                    NodeViewModel childItem;

                    if (child is ParserRuleContext)
                    {
                        childItem = new NodeViewModel((ParserRuleContext)child, this, parser);

                        children.Add(childItem);
                    }
                    else
                    {
                        var vocubalary = LittleBigCLexer.DefaultVocabulary;

                        childItem = new NodeViewModel(String.Format("{0}: {1}", vocubalary.GetSymbolicName(((TerminalNodeImpl)child).Symbol.Type), child.ToStringTree(parser)), this);

                        children.Add(childItem);
                    }
                }
            }

            /*
            for (int i = 0; i < node.ChildCount; i++)
            {
                if (node.GetChild<ParserRuleContext>(i) != null)
                {
                    var child = new NodeViewModel(node.GetChild<ParserRuleContext>(i), this, parser);

                    children.Add(child);
                }
                else
                {
                    var child = new NodeViewModel(node.GetChild(i).ToStringTree(parser), this);

                    children.Add(child);
                }
            }
             * */

            _children = new ReadOnlyCollection<NodeViewModel>(children);
        }
コード例 #7
0
ファイル: DefinitionListener.cs プロジェクト: mdelol/Compiler
        public override void EnterFormalParameter(LittleBigCParser.FormalParameterContext context)
        {
            var parameter = new ParameterDefinition(context);

            if (_currentScope.ParameterDefinitions.ContainsKey(parameter.Name))
            {
                var node = context.Identifier();
                _errors.Add(String.Format("[{0}:{1}] Semantic error: Parameter {2} already defined.", node.Symbol.Line, node.Symbol.StartIndex, parameter.Name));
            }
            else
            {
                _currentScope.AddParameterDefinition(parameter);
            }
        }
コード例 #8
0
ファイル: DefinitionListener.cs プロジェクト: mdelol/Compiler
        public override void EnterFunctionDefinition(LittleBigCParser.FunctionDefinitionContext context)
        {
            var function = new FunctionDefinition(context);
            var scope = new Scope(function);

            if (_scopes.Any(x => x.Name == scope.Name))
            {
                var node = context.Identifier();

                _errors.Add(String.Format("[{0}:{1}] Semantic error: Function {2} already defined.", node.Symbol.Line, node.Symbol.StartIndex, scope.Name));
            }
            else
            {
                _scopes.Add(scope);
                _currentScope = scope;
            }
        }
コード例 #9
0
ファイル: ResolvingListener.cs プロジェクト: mdelol/Compiler
        public override void EnterAssignmentExpression(LittleBigCParser.AssignmentExpressionContext context)
        {
            if (context.postfixExpression() != null)
            {
                var ident = context.postfixExpression().primaryExpression().Identifier();
                var variableName = ident.GetText();
                VariableDefinition variableDef;

                var error = new StringBuilder();

                variableDef = _currentScope.GetVariableDefinition(variableName);

                if (variableDef == null)
                {
                    variableDef = _semantic.GlobalScope.GetVariableDefinition(variableName);
                }

                if (variableDef == null)
                {
                    var parameterDef = _currentScope.GetParameterDefinition(variableName);

                    if (parameterDef == null)
                    {
                        error.Append(String.Format("[{0}:{1}] Semantic error: ", ident.Symbol.Line, ident.Symbol.StartIndex));
                        error.Append(String.Format("Variable {0} undefined.", variableName));

                        Errors.Add(error.ToString());
                    }
                    else
                    {
                        error.Append(String.Format("[{0}:{1}] Semantic error: ", ident.Symbol.Line, ident.Symbol.StartIndex));
                        error.Append(String.Format("Value can't be assigned to parameter {0}.", variableName));

                        Errors.Add(error.ToString());
                    }
                }
                else
                {
                    var listener = new TypeCheckListener(_semantic, _currentScope);

                    ParseTreeWalker.Default.Walk(listener, context);

                    _errors.AddRange(listener.Errors);
                }
            }
        }
コード例 #10
0
ファイル: TypeCheckListener.cs プロジェクト: mdelol/Compiler
        private VariableType GetConstantType(LittleBigCParser.ConstantContext context)
        {
            if (context.BooleanConstant() != null)
            {
                return VariableType.Boolean;
            }

            if (context.IntegerConstant() != null)
            {
                return VariableType.Integer;
            }

            if (context.StringConstant() != null)
            {
                return VariableType.String;
            }

            if (context.FloatingConstant() != null)
            {
                return VariableType.Float;
            }

            return VariableType.Undefined;
        }
コード例 #11
0
ファイル: TypeCheckListener.cs プロジェクト: mdelol/Compiler
 public override void EnterVariableDeclaration(LittleBigCParser.VariableDeclarationContext context)
 {
     var variable = _scope.GetVariableDefinition(context.Identifier().GetText());
     _targetType = variable.VariableType;
 }
コード例 #12
0
ファイル: TypeCheckListener.cs プロジェクト: mdelol/Compiler
        public override void EnterConstant(LittleBigCParser.ConstantContext context)
        {
            var constantType = GetConstantType(context);

            if (constantType != _targetType)
            {
                var error = new StringBuilder();

                ITerminalNode node = (ITerminalNode)context.GetChild(0);

                error.Append(String.Format("[{0}:{1}] Semantic error: Type mismatch. ", node.Symbol.Line, node.Symbol.StartIndex));
                error.Append(String.Format("{0} expected, but {1} found.", _targetType.ToString(), constantType.ToString()));

                Errors.Add(error.ToString());
            }
        }
コード例 #13
0
ファイル: VariableDefinition.cs プロジェクト: mdelol/Compiler
 public VariableDefinition(LittleBigCParser.VariableDeclarationContext context)
 {
     _context = context;
     var type = _context.variableType().simpleVariableType().GetText().ToString();
     _variableType = VariableDefinition.VariableTypes[type];
 }
コード例 #14
0
        public override void EnterPostfixExpression(LittleBigCParser.PostfixExpressionContext context)
        {
            if (_hasEntryPoint)
            {
                if (context.argumentExpressionList() != null)
                {
                    var functionName = context.postfixExpression().primaryExpression().Identifier().GetText();

                    if (functionName == "write")
                    {
                        var argsListener = new ArgumentsListener();

                        ParseTreeWalker.Default.Walk(argsListener, context.argumentExpressionList());

                        var text = argsListener.StringConstant;

                        ILGenerator ilGenerator = _entryMethod.GetILGenerator();
                        ilGenerator.EmitWriteLine(text);
                    }
                }
            }
        }
コード例 #15
0
        public override void ExitFunctionDefinition(LittleBigCParser.FunctionDefinitionContext context)
        {
            if (_hasEntryPoint)
            {
                ILGenerator ilGenerator = _entryMethod.GetILGenerator();

                ilGenerator.Emit(OpCodes.Ldc_I4_1);
                ilGenerator.Emit(OpCodes.Call, typeof(Console).GetMethod("ReadKey", new Type[] { typeof(bool) }));
                ilGenerator.Emit(OpCodes.Ret);
            }
        }
コード例 #16
0
ファイル: FunctionDefinition.cs プロジェクト: mdelol/Compiler
 public FunctionDefinition(LittleBigCParser.FunctionDefinitionContext context)
 {
     _context = context;
 }
コード例 #17
0
ファイル: DefinitionListener.cs プロジェクト: mdelol/Compiler
        public override void EnterVariableDeclaration(LittleBigCParser.VariableDeclarationContext context)
        {
            var variable = new VariableDefinition(context);

            if (_currentScope.VariableDefinitions.ContainsKey(variable.Name))
            {
                var node = context.Identifier();
                _errors.Add(String.Format("[{0}:{1}] Semantic error: Variable {2} already defined.", node.Symbol.Line, node.Symbol.StartIndex, variable.Name));
            }
            else
            {
                _currentScope.AddVariableDefinition(variable);
            }
        }
コード例 #18
0
ファイル: ResolvingListener.cs プロジェクト: mdelol/Compiler
        public override void EnterFunctionDefinition(LittleBigCParser.FunctionDefinitionContext context)
        {
            var functionName = context.Identifier().GetText();

            _currentScope = _semantic.GetScope(functionName);
        }
コード例 #19
0
ファイル: ResolvingListener.cs プロジェクト: mdelol/Compiler
 public override void ExitFunctionDefinition(LittleBigCParser.FunctionDefinitionContext context)
 {
     _currentScope = _semantic.GlobalScope;
 }
コード例 #20
0
ファイル: ResolvingListener.cs プロジェクト: mdelol/Compiler
        public override void EnterVariableDeclaration(LittleBigCParser.VariableDeclarationContext context)
        {
            var listener = new TypeCheckListener(_semantic, _currentScope);

            ParseTreeWalker.Default.Walk(listener, context);

            _errors.AddRange(listener.Errors);
        }
コード例 #21
0
ファイル: MainWindow.xaml.cs プロジェクト: mdelol/Compiler
        private void ParseMenuItem_Click(object sender, RoutedEventArgs e)
        {
            // Clear logs
            var logs = Logs.GetInstance();
            logs.Clear();
            LogsListBox.Items.Clear();
            TokensListBox.Items.Clear();

            // Get source code
            _sourceCode = SourceCodeTextEditor.Text;

            _inputStream = new AntlrInputStream(_sourceCode);
            _lexer = new LittleBigCLexer(_inputStream);

            // Lexer error listener
            var lexerErrorListener = new LexerErrorListener();

            _lexer.RemoveErrorListeners();
            _lexer.AddErrorListener(lexerErrorListener);

            // Recognize tokens
            IToken token = _lexer.NextToken();

            while (token.Type != LittleBigCLexer.Eof)
            {
                var vocubalary = LittleBigCLexer.DefaultVocabulary;

                TokensListBox.Items.Add(String.Format("{0} : {1}", token.Text, vocubalary.GetSymbolicName(token.Type)));

                token = _lexer.NextToken();
            }

            _lexer.Reset();

            var tokenStream = new CommonTokenStream(_lexer);
            _parser = new LittleBigCParser(tokenStream);

            // Parser error listener
            var parserErrorListener = new ParserErrorListener();

            _parser.RemoveErrorListeners();
            _parser.AddErrorListener(parserErrorListener);

            // Parser init
            var root = _parser.compilationUnit();

            var treeView = new TreeViewControl(root, _parser);

            TreePanel.Children.Add(treeView);

            // Semantic analyzer
            var _newParser = new LittleBigCParser(tokenStream);

            var semanticAnalyzer = new Semantic(root);

            var scopes = semanticAnalyzer.Scopes;

            ScopesListBox.Items.Clear();

            foreach (var scope in scopes)
            {

                ScopesListBox.Items.Add(String.Format("{0} scope", scope.Name));

                if (scope.ScopeType != ScopeType.Global)
                {
                    ScopesListBox.Items.Add("\tParameter definitions:");

                    if (scope.ParameterDefinitions.Count > 0)
                    {
                        foreach (var parameter in scope.ParameterDefinitions)
                        {
                            ScopesListBox.Items.Add(String.Format("\t\t{0} : {1}", parameter.Key, parameter.Value.VariableType.ToString()));
                        }

                    }
                }

                ScopesListBox.Items.Add("\tVariable definitions:");

                if (scope.VariableDefinitions.Count > 0)
                {
                    foreach (var variable in scope.VariableDefinitions)
                    {
                        ScopesListBox.Items.Add(String.Format("\t\t{0} : {1}", variable.Key, variable.Value.VariableType.ToString()));
                    }
                }

                ScopesListBox.Items.Add("");
            }

            foreach (var error in semanticAnalyzer.Errors)
            {
                LogsListBox.Items.Add(error);
            }

            // Logs
            foreach (var log in logs.LogsCollection)
            {
                LogsListBox.Items.Add(log);
            }

            // Compiler
            if (semanticAnalyzer.Errors.Count == 0 && logs.LogsCollection.Count == 0)
            {
                var name = "HelloWorld";
                var codeGenListener = new CodeGenerationListener(name);

                ParseTreeWalker.Default.Walk(codeGenListener, root);

                if (codeGenListener.Errors.Count != 0)
                {
                    foreach (var error in codeGenListener.Errors)
                    {
                        LogsListBox.Items.Add(error);
                    }
                }
                else
                {
                    var modName = String.Format("{0}.exe", name);

                    Process p = new Process();
                    p.StartInfo.FileName = @"C:\Program Files (x86)\Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1 Tools\ildasm.exe";
                    p.StartInfo.Arguments = "/text /nobar \"" + modName;
                    p.StartInfo.UseShellExecute = false;
                    p.StartInfo.CreateNoWindow = true;
                    p.StartInfo.RedirectStandardOutput = true;
                    p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
                    p.Start();
                    string s = p.StandardOutput.ReadToEnd();
                    p.WaitForExit();
                    p.Close();

                    Process.Start(modName);

                    SourceCodeTextEditor.Text = s;
                }
            }
        }
コード例 #22
0
        public override void ExitCompilationUnit(LittleBigCParser.CompilationUnitContext context)
        {
            if (_hasEntryPoint)
            {
                Type type = _typeBuilder.CreateType();

                // run it
                //type.GetMethod("main").Invoke(null, new string[] { null });

                // set the entry point for the application and save it
                _assemblyBuilder.SetEntryPoint(_entryMethod, PEFileKinds.ConsoleApplication);

                _assemblyBuilder.Save(String.Format("{0}.exe", _name));
            }
            else
            {
                _errors.Add("Complier: No entry point.");
            }
        }