Add MApplication with a file viewer
This commit is contained in:
parent
fe2f09ce6d
commit
ac43b77b1a
14
MApplication/CodeProcessor.cs
Normal file
14
MApplication/CodeProcessor.cs
Normal file
@ -0,0 +1,14 @@
|
||||
using Parser;
|
||||
|
||||
namespace MApplication
|
||||
{
|
||||
internal static class CodeProcessor
|
||||
{
|
||||
public static DisplayText GetText(SyntaxTree tree)
|
||||
{
|
||||
var visitor = new ColoringVisitor(StyleSchemeFactory.GetDefaultScheme());
|
||||
visitor.Visit(tree.Root);
|
||||
return new DisplayText(visitor.GetLines());
|
||||
}
|
||||
}
|
||||
}
|
461
MApplication/ColoringVisitor.cs
Normal file
461
MApplication/ColoringVisitor.cs
Normal file
@ -0,0 +1,461 @@
|
||||
using Parser;
|
||||
using Parser.Internal;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
|
||||
namespace MApplication
|
||||
{
|
||||
internal class ColoringVisitor : SyntaxWalker
|
||||
{
|
||||
private readonly ImmutableList<DisplayLine>.Builder Builder;
|
||||
private ImmutableList<DisplayLineChunk>.Builder CurrentLineBuilder;
|
||||
private readonly StyleScheme _scheme;
|
||||
private int _currentLine;
|
||||
|
||||
public ColoringVisitor(StyleScheme scheme)
|
||||
{
|
||||
Builder = ImmutableList.CreateBuilder<DisplayLine>();
|
||||
CurrentLineBuilder = ImmutableList.CreateBuilder<DisplayLineChunk>();
|
||||
_currentLine = 0;
|
||||
_scheme = scheme;
|
||||
}
|
||||
|
||||
public override void VisitToken(SyntaxToken token)
|
||||
{
|
||||
ProcessTriviaList(token.LeadingTrivia);
|
||||
CurrentLineBuilder.Add(new DisplayLineChunk(token.Text.AsMemory(), _scheme.DefaultToken));
|
||||
ProcessTriviaList (token.TrailingTrivia);
|
||||
}
|
||||
|
||||
private void ProcessTriviaList(IReadOnlyList<SyntaxTrivia> triviaList)
|
||||
{
|
||||
foreach (var trivia in triviaList)
|
||||
{
|
||||
ProcessTrivia(trivia);
|
||||
}
|
||||
}
|
||||
|
||||
private void FinishLine()
|
||||
{
|
||||
Builder.Add(new DisplayLine(CurrentLineBuilder.ToImmutable()));
|
||||
CurrentLineBuilder.Clear();
|
||||
_currentLine++;
|
||||
}
|
||||
|
||||
private void ProcessTrivia(SyntaxTrivia trivia)
|
||||
{
|
||||
if (trivia.Text.Contains('\n'))
|
||||
{
|
||||
var first = true;
|
||||
foreach (var part in trivia.Text.Split('\n'))
|
||||
{
|
||||
if (first)
|
||||
{
|
||||
first = false;
|
||||
} else
|
||||
{
|
||||
FinishLine();
|
||||
}
|
||||
CurrentLineBuilder.Add(new DisplayLineChunk(part.AsMemory(), _scheme.Trivia));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CurrentLineBuilder.Add(new DisplayLineChunk(trivia.Text.AsMemory(), _scheme.Trivia));
|
||||
}
|
||||
}
|
||||
|
||||
public void AddToken(SyntaxToken token, Style style)
|
||||
{
|
||||
ProcessTriviaList(token.LeadingTrivia);
|
||||
CurrentLineBuilder.Add(new DisplayLineChunk(token.Text.AsMemory(), style));
|
||||
ProcessTriviaList(token.TrailingTrivia);
|
||||
}
|
||||
|
||||
public override void VisitFile(FileSyntaxNode node)
|
||||
{
|
||||
Visit(node.StatementList);
|
||||
AddToken(node.EndOfFile, _scheme.Keyword);
|
||||
}
|
||||
|
||||
public override void VisitBaseClassList(BaseClassListSyntaxNode node)
|
||||
{
|
||||
AddToken(node.LessSign, _scheme.Punctuation);
|
||||
Visit(node.BaseClasses);
|
||||
}
|
||||
|
||||
public override void VisitClassDeclaration(ClassDeclarationSyntaxNode node)
|
||||
{
|
||||
AddToken(node.ClassdefKeyword, _scheme.Keyword);
|
||||
Visit(node.Attributes);
|
||||
Visit(node.ClassName);
|
||||
Visit(node.BaseClassList);
|
||||
Visit(node.Nodes);
|
||||
AddToken(node.EndKeyword, _scheme.Keyword);
|
||||
}
|
||||
|
||||
public override void VisitList(SyntaxNodeOrTokenList list)
|
||||
{
|
||||
foreach (var nodeOrToken in list)
|
||||
{
|
||||
if (nodeOrToken.IsToken)
|
||||
{
|
||||
var token = nodeOrToken.AsToken();
|
||||
if (token.Kind == TokenKind.IdentifierToken)
|
||||
{
|
||||
AddToken(token, _scheme.Identifier);
|
||||
}
|
||||
else if (SyntaxFacts.IsBracket(token.Kind))
|
||||
{
|
||||
AddToken(token, _scheme.Bracket);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddToken(token, _scheme.Punctuation);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Visit(nodeOrToken.AsNode());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void VisitMethodsList(MethodsListSyntaxNode node)
|
||||
{
|
||||
AddToken(node.MethodsKeyword, _scheme.Keyword);
|
||||
Visit(node.Attributes);
|
||||
Visit(node.Methods);
|
||||
AddToken(node.EndKeyword, _scheme.Keyword);
|
||||
}
|
||||
|
||||
public override void VisitPropertiesList(PropertiesListSyntaxNode node)
|
||||
{
|
||||
AddToken(node.PropertiesKeyword, _scheme.Keyword);
|
||||
Visit(node.Attributes);
|
||||
Visit(node.Properties);
|
||||
AddToken(node.EndKeyword, _scheme.Keyword);
|
||||
}
|
||||
|
||||
public override void VisitMethodDefinition(MethodDefinitionSyntaxNode node)
|
||||
{
|
||||
AddToken(node.FunctionKeyword, _scheme.Keyword);
|
||||
Visit(node.OutputDescription);
|
||||
Visit(node.InputDescription);
|
||||
Visit(node.Commas);
|
||||
Visit(node.Body);
|
||||
Visit(node.EndKeyword);
|
||||
}
|
||||
|
||||
public override void VisitEndKeyword(EndKeywordSyntaxNode node)
|
||||
{
|
||||
AddToken(node.EndKeyword, _scheme.Keyword);
|
||||
}
|
||||
|
||||
public override void VisitFunctionDeclaration(FunctionDeclarationSyntaxNode node)
|
||||
{
|
||||
AddToken(node.FunctionKeyword, _scheme.Keyword);
|
||||
Visit(node.OutputDescription);
|
||||
AddToken(node.Name, _scheme.Identifier);
|
||||
Visit(node.InputDescription);
|
||||
Visit(node.Commas);
|
||||
Visit(node.Body);
|
||||
Visit(node.EndKeyword);
|
||||
}
|
||||
|
||||
public override void VisitIfStatement(IfStatementSyntaxNode node)
|
||||
{
|
||||
AddToken(node.IfKeyword, _scheme.ControlKeyword);
|
||||
Visit(node.Condition);
|
||||
Visit(node.OptionalCommas);
|
||||
Visit(node.Body);
|
||||
Visit(node.ElseifClauses);
|
||||
Visit(node.ElseClause);
|
||||
AddToken(node.EndKeyword, _scheme.ControlKeyword);
|
||||
}
|
||||
|
||||
public override void VisitElseClause(ElseClause node)
|
||||
{
|
||||
AddToken(node.ElseKeyword, _scheme.ControlKeyword);
|
||||
Visit(node.Body);
|
||||
}
|
||||
|
||||
public override void VisitElseifClause(ElseifClause node)
|
||||
{
|
||||
AddToken(node.ElseifKeyword, _scheme.ControlKeyword);
|
||||
Visit(node.Condition);
|
||||
Visit(node.Body);
|
||||
}
|
||||
|
||||
public override void VisitAbstractMethodDeclaration(AbstractMethodDeclarationSyntaxNode node)
|
||||
{
|
||||
Visit(node.OutputDescription);
|
||||
Visit(node.Name);
|
||||
Visit(node.InputDescription);
|
||||
}
|
||||
|
||||
public override void VisitAssignmentExpression(AssignmentExpressionSyntaxNode node)
|
||||
{
|
||||
Visit(node.Lhs);
|
||||
AddToken(node.AssignmentSign, _scheme.Operator);
|
||||
Visit(node.Rhs);
|
||||
}
|
||||
|
||||
public override void VisitExpressionStatement(ExpressionStatementSyntaxNode node)
|
||||
{
|
||||
Visit(node.Expression);
|
||||
}
|
||||
|
||||
public override void VisitArrayLiteralExpression(ArrayLiteralExpressionSyntaxNode node)
|
||||
{
|
||||
AddToken(node.OpeningSquareBracket, _scheme.Bracket);
|
||||
Visit(node.Nodes);
|
||||
AddToken(node.ClosingSquareBracket, _scheme.Bracket);
|
||||
}
|
||||
|
||||
public override void VisitCellArrayLiteralExpression(CellArrayLiteralExpressionSyntaxNode node)
|
||||
{
|
||||
AddToken(node.OpeningBrace, _scheme.Bracket);
|
||||
Visit(node.Nodes);
|
||||
AddToken(node.ClosingBrace, _scheme.Bracket);
|
||||
}
|
||||
|
||||
public override void VisitIdentifierName(IdentifierNameSyntaxNode node)
|
||||
{
|
||||
AddToken(node.Name, _scheme.Identifier);
|
||||
}
|
||||
|
||||
public override void VisitForStatement(ForStatementSyntaxNode node)
|
||||
{
|
||||
AddToken(node.ForKeyword, _scheme.ControlKeyword);
|
||||
Visit(node.Assignment);
|
||||
Visit(node.OptionalCommas);
|
||||
Visit(node.Body);
|
||||
AddToken(node.EndKeyword, _scheme.ControlKeyword);
|
||||
}
|
||||
|
||||
public override void VisitSwitchStatement(SwitchStatementSyntaxNode node)
|
||||
{
|
||||
AddToken(node.SwitchKeyword, _scheme.ControlKeyword);
|
||||
Visit(node.SwitchExpression);
|
||||
Visit(node.OptionalCommas);
|
||||
Visit(node.Cases);
|
||||
AddToken(node.EndKeyword, _scheme.ControlKeyword);
|
||||
}
|
||||
|
||||
public override void VisitWhileStatement(WhileStatementSyntaxNode node)
|
||||
{
|
||||
AddToken(node.WhileKeyword, _scheme.ControlKeyword);
|
||||
Visit(node.Condition);
|
||||
Visit(node.OptionalCommas);
|
||||
Visit(node.Body);
|
||||
AddToken(node.EndKeyword, _scheme.ControlKeyword);
|
||||
}
|
||||
|
||||
public override void VisitUnquotedStringLiteral(UnquotedStringLiteralSyntaxNode node)
|
||||
{
|
||||
AddToken(node.StringToken, _scheme.UnquotedStringLiteral);
|
||||
}
|
||||
|
||||
public override void VisitStringLiteral(StringLiteralSyntaxNode node)
|
||||
{
|
||||
AddToken(node.StringToken, _scheme.StringLiteral);
|
||||
}
|
||||
|
||||
public override void VisitBinaryOperationExpression(BinaryOperationExpressionSyntaxNode node)
|
||||
{
|
||||
Visit(node.Lhs);
|
||||
AddToken(node.Operation, _scheme.Operator);
|
||||
Visit(node.Rhs);
|
||||
}
|
||||
|
||||
public override void VisitFunctionCallExpression(FunctionCallExpressionSyntaxNode node)
|
||||
{
|
||||
Visit(node.FunctionName);
|
||||
AddToken(node.OpeningBracket, _scheme.Bracket);
|
||||
Visit(node.Nodes);
|
||||
AddToken(node.ClosingBracket, _scheme.Bracket);
|
||||
}
|
||||
|
||||
public override void VisitSwitchCase(SwitchCaseSyntaxNode node)
|
||||
{
|
||||
AddToken(node.CaseKeyword, _scheme.ControlKeyword);
|
||||
Visit(node.CaseIdentifier);
|
||||
Visit(node.OptionalCommas);
|
||||
Visit(node.Body);
|
||||
}
|
||||
|
||||
public override void VisitCatchClause(CatchClauseSyntaxNode node)
|
||||
{
|
||||
AddToken(node.CatchKeyword, _scheme.ControlKeyword);
|
||||
Visit(node.CatchBody);
|
||||
}
|
||||
|
||||
public override void VisitTryCatchStatement(TryCatchStatementSyntaxNode node)
|
||||
{
|
||||
AddToken(node.TryKeyword, _scheme.ControlKeyword);
|
||||
Visit(node.TryBody);
|
||||
Visit(node.CatchClause);
|
||||
AddToken(node.EndKeyword, _scheme.ControlKeyword);
|
||||
}
|
||||
|
||||
public override void VisitCommandExpression(CommandExpressionSyntaxNode node)
|
||||
{
|
||||
Visit(node.CommandName);
|
||||
Visit(node.Arguments);
|
||||
}
|
||||
|
||||
public override void VisitNumberLiteral(NumberLiteralSyntaxNode node)
|
||||
{
|
||||
AddToken(node.Number, _scheme.NumberLiteral);
|
||||
}
|
||||
|
||||
public override void VisitUnaryPrefixOperationExpression(UnaryPrefixOperationExpressionSyntaxNode node)
|
||||
{
|
||||
AddToken(node.Operation, _scheme.Operator);
|
||||
Visit(node.Operand);
|
||||
}
|
||||
|
||||
public override void VisitUnaryPostixOperationExpression(UnaryPostixOperationExpressionSyntaxNode node)
|
||||
{
|
||||
Visit(node.Operand);
|
||||
AddToken(node.Operation, _scheme.Operator);
|
||||
}
|
||||
|
||||
public override void VisitBaseClassInvokation(BaseClassInvokationSyntaxNode node)
|
||||
{
|
||||
Visit(node.MethodName);
|
||||
AddToken(node.AtSign, _scheme.Operator);
|
||||
Visit(node.BaseClassNameAndArguments);
|
||||
}
|
||||
|
||||
public override void VisitAttributeAssignment(AttributeAssignmentSyntaxNode node)
|
||||
{
|
||||
AddToken(node.AssignmentSign, _scheme.Operator);
|
||||
Visit(node.Value);
|
||||
}
|
||||
|
||||
public override void VisitAttribute(AttributeSyntaxNode node)
|
||||
{
|
||||
Visit(node.Name);
|
||||
Visit(node.Assignment);
|
||||
}
|
||||
|
||||
public override void VisitAttributeList(AttributeListSyntaxNode node)
|
||||
{
|
||||
AddToken(node.OpeningBracket, _scheme.Bracket);
|
||||
Visit(node.Nodes);
|
||||
AddToken(node.ClosingBracket, _scheme.Bracket);
|
||||
}
|
||||
|
||||
public override void VisitCellArrayElementAccessExpression(CellArrayElementAccessExpressionSyntaxNode node)
|
||||
{
|
||||
Visit(node.Expression);
|
||||
AddToken(node.OpeningBrace, _scheme.Bracket);
|
||||
Visit(node.Nodes);
|
||||
AddToken(node.ClosingBrace, _scheme.Bracket);
|
||||
}
|
||||
|
||||
public override void VisitCompoundName(CompoundNameSyntaxNode node)
|
||||
{
|
||||
Visit(node.Nodes);
|
||||
}
|
||||
|
||||
public override void VisitDoubleQuotedStringLiteral(DoubleQuotedStringLiteralSyntaxNode node)
|
||||
{
|
||||
AddToken(node.StringToken, _scheme.StringLiteral);
|
||||
}
|
||||
|
||||
public override void VisitEmptyExpression(EmptyExpressionSyntaxNode node)
|
||||
{
|
||||
}
|
||||
|
||||
public override void VisitEmptyStatement(EmptyStatementSyntaxNode node)
|
||||
{
|
||||
AddToken(node.Semicolon, _scheme.Punctuation);
|
||||
}
|
||||
|
||||
public override void VisitEnumerationList(EnumerationListSyntaxNode node)
|
||||
{
|
||||
AddToken(node.EnumerationKeyword, _scheme.Keyword);
|
||||
Visit(node.Attributes);
|
||||
Visit(node.Items);
|
||||
AddToken(node.EndKeyword, _scheme.Keyword);
|
||||
}
|
||||
|
||||
public override void VisitEventsList(EventsListSyntaxNode node)
|
||||
{
|
||||
AddToken(node.EventsKeyword, _scheme.Keyword);
|
||||
Visit(node.Attributes);
|
||||
Visit(node.Events);
|
||||
AddToken(node.EndKeyword, _scheme.Keyword);
|
||||
}
|
||||
|
||||
public override void VisitEnumerationItemValue(EnumerationItemValueSyntaxNode node)
|
||||
{
|
||||
AddToken(node.OpeningBracket, _scheme.Punctuation);
|
||||
Visit(node.Values);
|
||||
AddToken(node.ClosingBracket, _scheme.Punctuation);
|
||||
}
|
||||
|
||||
public override void VisitEnumerationItem(EnumerationItemSyntaxNode node)
|
||||
{
|
||||
Visit(node.Name);
|
||||
Visit(node.Values);
|
||||
Visit(node.Commas);
|
||||
}
|
||||
|
||||
public override void VisitFunctionInputDescription(FunctionInputDescriptionSyntaxNode node)
|
||||
{
|
||||
AddToken(node.OpeningBracket, _scheme.Bracket);
|
||||
Visit(node.ParameterList);
|
||||
AddToken(node.ClosingBracket, _scheme.Bracket);
|
||||
}
|
||||
|
||||
public override void VisitFunctionOutputDescription(FunctionOutputDescriptionSyntaxNode node)
|
||||
{
|
||||
Visit(node.OutputList);
|
||||
AddToken(node.AssignmentSign, _scheme.Operator);
|
||||
}
|
||||
|
||||
public override void VisitIndirectMemberAccess(IndirectMemberAccessSyntaxNode node)
|
||||
{
|
||||
AddToken(node.OpeningBracket, _scheme.Bracket);
|
||||
Visit(node.Expression);
|
||||
AddToken(node.ClosingBracket, _scheme.Bracket);
|
||||
}
|
||||
|
||||
public override void VisitLambda(LambdaSyntaxNode node)
|
||||
{
|
||||
AddToken(node.AtSign, _scheme.Operator);
|
||||
Visit(node.Input);
|
||||
Visit(node.Body);
|
||||
}
|
||||
|
||||
public override void VisitNamedFunctionHandle(NamedFunctionHandleSyntaxNode node)
|
||||
{
|
||||
AddToken(node.AtSign, _scheme.Operator);
|
||||
Visit(node.FunctionName);
|
||||
}
|
||||
|
||||
public override void VisitMemberAccess(MemberAccessSyntaxNode node)
|
||||
{
|
||||
Visit(node.LeftOperand);
|
||||
AddToken(node.Dot, _scheme.Operator);
|
||||
Visit(node.RightOperand);
|
||||
}
|
||||
|
||||
public override void VisitParenthesizedExpression(ParenthesizedExpressionSyntaxNode node)
|
||||
{
|
||||
AddToken(node.OpeningBracket, _scheme.Operator);
|
||||
Visit(node.Expression);
|
||||
AddToken(node.ClosingBracket, _scheme.Operator);
|
||||
}
|
||||
|
||||
public ImmutableList<DisplayLine> GetLines()
|
||||
{
|
||||
return Builder.ToImmutable();
|
||||
}
|
||||
}
|
||||
}
|
47
MApplication/ConsoleWindowView.cs
Normal file
47
MApplication/ConsoleWindowView.cs
Normal file
@ -0,0 +1,47 @@
|
||||
using System;
|
||||
|
||||
namespace MApplication
|
||||
{
|
||||
internal class ConsoleWindowView : IOutputView
|
||||
{
|
||||
public ConsoleWindowView(int startingColumn, int startingLine, int width, int height)
|
||||
{
|
||||
StartingColumn = startingColumn;
|
||||
StartingLine = startingLine;
|
||||
Width = width;
|
||||
Height = height;
|
||||
}
|
||||
|
||||
public int StartingColumn { get; }
|
||||
|
||||
public int StartingLine { get; }
|
||||
|
||||
public int Width { get; }
|
||||
|
||||
public int Height { get; }
|
||||
|
||||
public void MoveCursorTo(int column, int line)
|
||||
{
|
||||
Console.CursorLeft = StartingColumn + column;
|
||||
Console.CursorTop = StartingLine + line;
|
||||
}
|
||||
|
||||
public void SetStyle(Style style)
|
||||
{
|
||||
if (Console.ForegroundColor != style.ForegroundColor)
|
||||
{
|
||||
Console.ForegroundColor = style.ForegroundColor;
|
||||
}
|
||||
|
||||
if (Console.BackgroundColor != style.BackgroundColor)
|
||||
{
|
||||
Console.BackgroundColor = style.BackgroundColor;
|
||||
}
|
||||
}
|
||||
|
||||
public void WriteText(string s)
|
||||
{
|
||||
Console.Write(s);
|
||||
}
|
||||
}
|
||||
}
|
14
MApplication/DisplayLine.cs
Normal file
14
MApplication/DisplayLine.cs
Normal file
@ -0,0 +1,14 @@
|
||||
using System.Collections.Immutable;
|
||||
|
||||
namespace MApplication
|
||||
{
|
||||
internal class DisplayLine
|
||||
{
|
||||
public ImmutableList<DisplayLineChunk> Chunks { get; }
|
||||
|
||||
public DisplayLine(ImmutableList<DisplayLineChunk> chunks)
|
||||
{
|
||||
Chunks = chunks;
|
||||
}
|
||||
}
|
||||
}
|
19
MApplication/DisplayLineChunk.cs
Normal file
19
MApplication/DisplayLineChunk.cs
Normal file
@ -0,0 +1,19 @@
|
||||
using System;
|
||||
|
||||
namespace MApplication
|
||||
{
|
||||
internal class DisplayLineChunk
|
||||
{
|
||||
public DisplayLineChunk(ReadOnlyMemory<char> text, Style style)
|
||||
{
|
||||
Text = text;
|
||||
Style = style;
|
||||
}
|
||||
|
||||
public ReadOnlyMemory<char> Text { get; }
|
||||
|
||||
public Style Style { get; }
|
||||
|
||||
public int Width => Text.Length;
|
||||
}
|
||||
}
|
14
MApplication/DisplayText.cs
Normal file
14
MApplication/DisplayText.cs
Normal file
@ -0,0 +1,14 @@
|
||||
using System.Collections.Immutable;
|
||||
|
||||
namespace MApplication
|
||||
{
|
||||
internal class DisplayText
|
||||
{
|
||||
public DisplayText(ImmutableList<DisplayLine> lines)
|
||||
{
|
||||
Lines = lines;
|
||||
}
|
||||
|
||||
public ImmutableList<DisplayLine> Lines { get; }
|
||||
}
|
||||
}
|
94
MApplication/DisplayTextViewPort.cs
Normal file
94
MApplication/DisplayTextViewPort.cs
Normal file
@ -0,0 +1,94 @@
|
||||
using System;
|
||||
|
||||
namespace MApplication
|
||||
{
|
||||
internal class DisplayTextViewPort
|
||||
{
|
||||
public DisplayTextViewPort(
|
||||
DisplayText text,
|
||||
int width,
|
||||
int height,
|
||||
int startingColumn = 0,
|
||||
int startingLine = 0)
|
||||
{
|
||||
Text = text;
|
||||
Width = width;
|
||||
Height = height;
|
||||
StartingColumn = startingColumn;
|
||||
StartingLine = startingLine;
|
||||
}
|
||||
|
||||
public DisplayText Text { get; }
|
||||
|
||||
public int Width { get; }
|
||||
|
||||
public int Height { get; }
|
||||
|
||||
public int StartingColumn { get; }
|
||||
|
||||
public int StartingLine { get; }
|
||||
|
||||
public void RenderTo(IOutputView view)
|
||||
{
|
||||
for (var lineNumber = StartingLine; lineNumber < StartingLine + Height; lineNumber++)
|
||||
{
|
||||
view.MoveCursorTo(0, lineNumber - StartingLine);
|
||||
if (lineNumber >= Text.Lines.Count)
|
||||
{
|
||||
view.WriteText(new string(' ', Width));
|
||||
continue;
|
||||
}
|
||||
var line = Text.Lines[lineNumber];
|
||||
var startsIn = StartingColumn;
|
||||
foreach (var chunk in line.Chunks)
|
||||
{
|
||||
var left = Math.Max(0, startsIn);
|
||||
var right = Math.Min(chunk.Width, startsIn + Width);
|
||||
if (left < right)
|
||||
{
|
||||
view.SetStyle(chunk.Style);
|
||||
view.WriteText(chunk.Text[left..right].ToString());
|
||||
}
|
||||
|
||||
startsIn -= chunk.Width;
|
||||
if (startsIn + Width <= 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (startsIn + Width > 0)
|
||||
{
|
||||
var numberOfSpaces = Math.Min(startsIn + Width, Width);
|
||||
view.WriteText(new string(' ', numberOfSpaces));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public DisplayTextViewPort With(
|
||||
int? width = null,
|
||||
int? height = null,
|
||||
int? startingColumn = null,
|
||||
int? startingLine = null)
|
||||
{
|
||||
var widthValue = width ?? Width;
|
||||
var heightValue = height ?? Height;
|
||||
var startingColumnValue = startingColumn ?? StartingColumn;
|
||||
var startingLineValue = startingLine ?? StartingLine;
|
||||
if (widthValue == Width &&
|
||||
heightValue == Height &&
|
||||
startingColumnValue == StartingColumn &&
|
||||
startingLineValue == StartingLine)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
return new DisplayTextViewPort(
|
||||
text: Text,
|
||||
width: widthValue,
|
||||
height: heightValue,
|
||||
startingColumn: startingColumnValue,
|
||||
startingLine: startingLineValue);
|
||||
}
|
||||
}
|
||||
}
|
11
MApplication/IOutputView.cs
Normal file
11
MApplication/IOutputView.cs
Normal file
@ -0,0 +1,11 @@
|
||||
namespace MApplication
|
||||
{
|
||||
internal interface IOutputView
|
||||
{
|
||||
int Width { get; }
|
||||
int Height { get; }
|
||||
void MoveCursorTo(int column, int line);
|
||||
void SetStyle(Style style);
|
||||
void WriteText(string s);
|
||||
}
|
||||
}
|
14
MApplication/MApplication.csproj
Normal file
14
MApplication/MApplication.csproj
Normal file
@ -0,0 +1,14 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<LangVersion>preview</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Parser\Parser.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
131
MApplication/Program.cs
Normal file
131
MApplication/Program.cs
Normal file
@ -0,0 +1,131 @@
|
||||
using Parser;
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace MApplication
|
||||
{
|
||||
class Program
|
||||
{
|
||||
private static readonly string BaseDirectory;
|
||||
private const string BaseDirectoryMacOs = @"/Applications/MATLAB_R2017b.app/toolbox/matlab/";
|
||||
private const string BaseDirectoryWindows = @"D:\Program Files\MATLAB\R2018a\toolbox\matlab\";
|
||||
|
||||
static Program()
|
||||
{
|
||||
switch (Environment.OSVersion.Platform)
|
||||
{
|
||||
case PlatformID.MacOSX:
|
||||
case PlatformID.Unix:
|
||||
BaseDirectory = BaseDirectoryMacOs;
|
||||
break;
|
||||
default:
|
||||
BaseDirectory = BaseDirectoryWindows;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private static MParser CreateParser(ITextWindow window)
|
||||
{
|
||||
return new MParser(window);
|
||||
}
|
||||
|
||||
private static SyntaxTree GetTree(string fileName)
|
||||
{
|
||||
var text = File.ReadAllText(fileName);
|
||||
var window = new TextWindowWithNull(text, fileName);
|
||||
var parser = CreateParser(window);
|
||||
var tree = parser.Parse();
|
||||
return tree;
|
||||
}
|
||||
|
||||
private static Style GetStyle()
|
||||
{
|
||||
return new Style(
|
||||
foregroundColor: Console.ForegroundColor,
|
||||
backgroundColor: Console.BackgroundColor);
|
||||
}
|
||||
|
||||
private static void SetStyle(Style style)
|
||||
{
|
||||
Console.BackgroundColor = style.BackgroundColor;
|
||||
Console.ForegroundColor = style.ForegroundColor;
|
||||
}
|
||||
|
||||
private static void PrintChunk(DisplayLineChunk chunk)
|
||||
{
|
||||
SetStyle(chunk.Style);
|
||||
Console.Write(chunk.Text.ToString());
|
||||
}
|
||||
|
||||
private static void PrintLine(DisplayLine line)
|
||||
{
|
||||
foreach (var chunk in line.Chunks)
|
||||
{
|
||||
PrintChunk(chunk);
|
||||
}
|
||||
}
|
||||
|
||||
static void RenderFile(string fileName)
|
||||
{
|
||||
var tree = GetTree(fileName);
|
||||
var text = CodeProcessor.GetText(tree);
|
||||
var viewPort = new DisplayTextViewPort(
|
||||
text: text,
|
||||
width: 80,
|
||||
height: 24);
|
||||
|
||||
var targetWidth = 80;
|
||||
var targetHeight = 24;
|
||||
var outputViewPort = new ConsoleWindowView(
|
||||
startingColumn: (Console.WindowWidth - targetWidth) / 2,
|
||||
startingLine: (Console.WindowHeight - targetHeight) / 2,
|
||||
width: targetWidth,
|
||||
height: targetHeight);
|
||||
|
||||
while (true)
|
||||
{
|
||||
viewPort.RenderTo(outputViewPort);
|
||||
var key = Console.ReadKey(intercept: true);
|
||||
switch (key.Key)
|
||||
{
|
||||
case ConsoleKey.LeftArrow:
|
||||
viewPort = viewPort.With(startingColumn: Math.Max(viewPort.StartingColumn - 1, 0));
|
||||
break;
|
||||
|
||||
case ConsoleKey.RightArrow:
|
||||
viewPort = viewPort.With(startingColumn: viewPort.StartingColumn + 1);
|
||||
break;
|
||||
|
||||
case ConsoleKey.UpArrow:
|
||||
viewPort = viewPort.With(startingLine: Math.Max(viewPort.StartingLine - 1, 0));
|
||||
break;
|
||||
|
||||
case ConsoleKey.DownArrow:
|
||||
viewPort = viewPort.With(startingLine: viewPort.StartingLine + 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void Main(string[] args)
|
||||
{
|
||||
var oldStyle = GetStyle();
|
||||
var fileName = Path.Combine(
|
||||
BaseDirectory,
|
||||
"datatypes",
|
||||
"@table",
|
||||
"table.m");
|
||||
Console.CursorVisible = false;
|
||||
RenderFile(fileName);
|
||||
Console.CursorVisible = true;
|
||||
|
||||
//foreach (var line in text.Lines)
|
||||
//{
|
||||
// PrintLine(line);
|
||||
// Console.WriteLine();
|
||||
//}
|
||||
|
||||
SetStyle(oldStyle);
|
||||
}
|
||||
}
|
||||
}
|
31
MApplication/Style.cs
Normal file
31
MApplication/Style.cs
Normal file
@ -0,0 +1,31 @@
|
||||
using System;
|
||||
|
||||
namespace MApplication
|
||||
{
|
||||
internal class Style
|
||||
{
|
||||
public Style(
|
||||
ConsoleColor foregroundColor,
|
||||
ConsoleColor backgroundColor)
|
||||
{
|
||||
ForegroundColor = foregroundColor;
|
||||
BackgroundColor = backgroundColor;
|
||||
}
|
||||
|
||||
public ConsoleColor ForegroundColor { get; }
|
||||
|
||||
public ConsoleColor BackgroundColor { get; }
|
||||
|
||||
public static Style Color(ConsoleColor foregroundColor)
|
||||
{
|
||||
return new Style(foregroundColor, ConsoleColor.Black);
|
||||
}
|
||||
|
||||
public static Style ColorWithBackGround(
|
||||
ConsoleColor foregroundColor,
|
||||
ConsoleColor backgroundColor)
|
||||
{
|
||||
return new Style(foregroundColor, backgroundColor);
|
||||
}
|
||||
}
|
||||
}
|
53
MApplication/StyleScheme.cs
Normal file
53
MApplication/StyleScheme.cs
Normal file
@ -0,0 +1,53 @@
|
||||
namespace MApplication
|
||||
{
|
||||
internal class StyleScheme
|
||||
{
|
||||
public StyleScheme(
|
||||
Style defaultToken,
|
||||
Style keyword,
|
||||
Style controlKeyword,
|
||||
Style trivia,
|
||||
Style punctuation,
|
||||
Style @operator,
|
||||
Style identifier,
|
||||
Style unquotedStringLiteral,
|
||||
Style stringLiteral,
|
||||
Style numberLiteral,
|
||||
Style bracket)
|
||||
{
|
||||
DefaultToken = defaultToken;
|
||||
Keyword = keyword;
|
||||
ControlKeyword = controlKeyword;
|
||||
Trivia = trivia;
|
||||
Punctuation = punctuation;
|
||||
Operator = @operator;
|
||||
Identifier = identifier;
|
||||
UnquotedStringLiteral = unquotedStringLiteral;
|
||||
StringLiteral = stringLiteral;
|
||||
NumberLiteral = numberLiteral;
|
||||
Bracket = bracket;
|
||||
}
|
||||
|
||||
public Style DefaultToken { get; }
|
||||
|
||||
public Style Keyword { get; }
|
||||
|
||||
public Style ControlKeyword { get; }
|
||||
|
||||
public Style Trivia { get; }
|
||||
|
||||
public Style Punctuation { get; }
|
||||
|
||||
public Style Operator { get; }
|
||||
|
||||
public Style Identifier { get; }
|
||||
|
||||
public Style UnquotedStringLiteral { get; }
|
||||
|
||||
public Style StringLiteral { get; }
|
||||
|
||||
public Style NumberLiteral { get; }
|
||||
|
||||
public Style Bracket { get; }
|
||||
}
|
||||
}
|
27
MApplication/StyleSchemeFactory.cs
Normal file
27
MApplication/StyleSchemeFactory.cs
Normal file
@ -0,0 +1,27 @@
|
||||
using System;
|
||||
|
||||
namespace MApplication
|
||||
{
|
||||
internal static class StyleSchemeFactory
|
||||
{
|
||||
private static StyleScheme _defaultScheme;
|
||||
|
||||
static StyleSchemeFactory()
|
||||
{
|
||||
_defaultScheme = new StyleScheme(
|
||||
defaultToken: Style.Color(ConsoleColor.Gray),
|
||||
keyword: Style.Color(ConsoleColor.Green),
|
||||
controlKeyword: Style.Color(ConsoleColor.Yellow),
|
||||
trivia: Style.Color(ConsoleColor.DarkGray),
|
||||
punctuation: Style.Color(ConsoleColor.DarkBlue),
|
||||
@operator: Style.Color(ConsoleColor.Cyan),
|
||||
identifier: Style.Color(ConsoleColor.White),
|
||||
unquotedStringLiteral: Style.Color(ConsoleColor.Blue),
|
||||
stringLiteral: Style.Color(ConsoleColor.Magenta),
|
||||
numberLiteral: Style.Color(ConsoleColor.DarkGreen),
|
||||
bracket: Style.Color(ConsoleColor.DarkYellow));
|
||||
}
|
||||
|
||||
public static StyleScheme GetDefaultScheme() => _defaultScheme;
|
||||
}
|
||||
}
|
@ -19,7 +19,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
|
||||
README.md = README.md
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Repl", "Repl\Repl.csproj", "{8FEDFE5D-3320-418F-88A6-09C1B51C4441}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Repl", "Repl\Repl.csproj", "{8FEDFE5D-3320-418F-88A6-09C1B51C4441}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MApplication", "MApplication\MApplication.csproj", "{A7EE271C-8822-43EA-BA13-5D6D5DC5B581}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
@ -51,6 +53,10 @@ Global
|
||||
{8FEDFE5D-3320-418F-88A6-09C1B51C4441}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8FEDFE5D-3320-418F-88A6-09C1B51C4441}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8FEDFE5D-3320-418F-88A6-09C1B51C4441}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{A7EE271C-8822-43EA-BA13-5D6D5DC5B581}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A7EE271C-8822-43EA-BA13-5D6D5DC5B581}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A7EE271C-8822-43EA-BA13-5D6D5DC5B581}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A7EE271C-8822-43EA-BA13-5D6D5DC5B581}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
Loading…
x
Reference in New Issue
Block a user