...
This commit is contained in:
@@ -22,6 +22,18 @@ foreach (var file in args)
|
|||||||
syntaxTrees.Add(syntaxTree);
|
syntaxTrees.Add(syntaxTree);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach (var diagnostic in diagnostics)
|
||||||
|
{
|
||||||
|
Console.Error.WriteLine(diagnostic.FormatANSI());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (diagnostics.Any(diagnostic => diagnostic.Severity == DiagnosticSeverity.Error))
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
diagnostics.Clear();
|
||||||
|
|
||||||
ModuleRepository moduleRepository;
|
ModuleRepository moduleRepository;
|
||||||
|
|
||||||
try
|
try
|
||||||
@@ -55,6 +67,8 @@ if (diagnostics.Any(diagnostic => diagnostic.Severity == DiagnosticSeverity.Erro
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
diagnostics.Clear();
|
||||||
|
|
||||||
Directory.CreateDirectory(".build");
|
Directory.CreateDirectory(".build");
|
||||||
|
|
||||||
for (var i = 0; i < args.Length; i++)
|
for (var i = 0; i < args.Length; i++)
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ public class Diagnostic
|
|||||||
if (i >= startLine && i <= endLine)
|
if (i >= startLine && i <= endLine)
|
||||||
{
|
{
|
||||||
var markerStartColumn = 1;
|
var markerStartColumn = 1;
|
||||||
var markerEndColumn = line.Length;
|
var markerEndColumn = line.Length + 1;
|
||||||
|
|
||||||
if (i == startLine)
|
if (i == startLine)
|
||||||
{
|
{
|
||||||
@@ -262,6 +262,10 @@ public class Diagnostic
|
|||||||
{
|
{
|
||||||
switch (token)
|
switch (token)
|
||||||
{
|
{
|
||||||
|
case CommentToken:
|
||||||
|
{
|
||||||
|
return ConsoleColors.Colorize(tokenText, ConsoleColors.Green);
|
||||||
|
}
|
||||||
case IdentifierToken:
|
case IdentifierToken:
|
||||||
{
|
{
|
||||||
return ConsoleColors.Colorize(tokenText, ConsoleColors.BrightWhite);
|
return ConsoleColors.Colorize(tokenText, ConsoleColors.BrightWhite);
|
||||||
|
|||||||
@@ -126,10 +126,10 @@ public class LlvmGenerator
|
|||||||
case BlockNode blockNode:
|
case BlockNode blockNode:
|
||||||
EmitBlock(writer, blockNode);
|
EmitBlock(writer, blockNode);
|
||||||
break;
|
break;
|
||||||
case BreakNode breakNode:
|
case BreakNode:
|
||||||
EmitBreak(writer);
|
EmitBreak(writer);
|
||||||
break;
|
break;
|
||||||
case ContinueNode continueNode:
|
case ContinueNode:
|
||||||
EmitContinue(writer);
|
EmitContinue(writer);
|
||||||
break;
|
break;
|
||||||
case DeferNode deferNode:
|
case DeferNode deferNode:
|
||||||
@@ -380,7 +380,8 @@ public class LlvmGenerator
|
|||||||
|
|
||||||
private Tmp EmitDereference(IndentedTextWriter writer, DereferenceNode dereferenceNode)
|
private Tmp EmitDereference(IndentedTextWriter writer, DereferenceNode dereferenceNode)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
var target = EmitExpression(writer, dereferenceNode.Target);
|
||||||
|
return new Tmp(target.Ident, dereferenceNode.Type, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Tmp EmitUnaryExpression(IndentedTextWriter writer, UnaryExpressionNode unaryExpressionNode)
|
private Tmp EmitUnaryExpression(IndentedTextWriter writer, UnaryExpressionNode unaryExpressionNode)
|
||||||
|
|||||||
@@ -9,6 +9,19 @@ public sealed class Parser
|
|||||||
private int _tokenIndex;
|
private int _tokenIndex;
|
||||||
|
|
||||||
private Token? CurrentToken => _tokenIndex < _tokens.Count ? _tokens[_tokenIndex] : null;
|
private Token? CurrentToken => _tokenIndex < _tokens.Count ? _tokens[_tokenIndex] : null;
|
||||||
|
|
||||||
|
private bool HasTrailingWhitespace(Token token)
|
||||||
|
{
|
||||||
|
var index = _tokens.IndexOf(token);
|
||||||
|
return index + 1 < _tokens.Count && _tokens[index + 1] is WhitespaceToken or CommentToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool HasLeadingWhitespace(Token token)
|
||||||
|
{
|
||||||
|
var index = _tokens.IndexOf(token);
|
||||||
|
return index - 1 < _tokens.Count && _tokens[index - 1] is WhitespaceToken or CommentToken;
|
||||||
|
}
|
||||||
|
|
||||||
private bool HasToken => CurrentToken != null;
|
private bool HasToken => CurrentToken != null;
|
||||||
|
|
||||||
public List<Diagnostic> Diagnostics { get; set; } = [];
|
public List<Diagnostic> Diagnostics { get; set; } = [];
|
||||||
@@ -194,27 +207,36 @@ public sealed class Parser
|
|||||||
{
|
{
|
||||||
var startIndex = _tokenIndex;
|
var startIndex = _tokenIndex;
|
||||||
|
|
||||||
if (TryExpectSymbol(out var symbol))
|
if (CurrentToken is SymbolToken symbolToken)
|
||||||
{
|
{
|
||||||
switch (symbol)
|
switch (symbolToken.Symbol)
|
||||||
{
|
{
|
||||||
case Symbol.OpenBrace:
|
case Symbol.OpenBrace:
|
||||||
|
Next();
|
||||||
return ParseBlock(startIndex);
|
return ParseBlock(startIndex);
|
||||||
case Symbol.Return:
|
case Symbol.Return:
|
||||||
|
Next();
|
||||||
return ParseReturn(startIndex);
|
return ParseReturn(startIndex);
|
||||||
case Symbol.If:
|
case Symbol.If:
|
||||||
|
Next();
|
||||||
return ParseIf(startIndex);
|
return ParseIf(startIndex);
|
||||||
case Symbol.While:
|
case Symbol.While:
|
||||||
|
Next();
|
||||||
return ParseWhile(startIndex);
|
return ParseWhile(startIndex);
|
||||||
case Symbol.For:
|
case Symbol.For:
|
||||||
|
Next();
|
||||||
return ParseFor(startIndex);
|
return ParseFor(startIndex);
|
||||||
case Symbol.Let:
|
case Symbol.Let:
|
||||||
|
Next();
|
||||||
return ParseVariableDeclaration(startIndex);
|
return ParseVariableDeclaration(startIndex);
|
||||||
case Symbol.Defer:
|
case Symbol.Defer:
|
||||||
|
Next();
|
||||||
return ParseDefer(startIndex);
|
return ParseDefer(startIndex);
|
||||||
case Symbol.Break:
|
case Symbol.Break:
|
||||||
|
Next();
|
||||||
return new BreakSyntax(GetTokens(startIndex));
|
return new BreakSyntax(GetTokens(startIndex));
|
||||||
case Symbol.Continue:
|
case Symbol.Continue:
|
||||||
|
Next();
|
||||||
return new ContinueSyntax(GetTokens(startIndex));
|
return new ContinueSyntax(GetTokens(startIndex));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -319,7 +341,7 @@ public sealed class Parser
|
|||||||
var startIndex = _tokenIndex;
|
var startIndex = _tokenIndex;
|
||||||
var left = ParsePrimaryExpression();
|
var left = ParsePrimaryExpression();
|
||||||
|
|
||||||
while (CurrentToken is SymbolToken symbolToken && TryGetBinaryOperator(symbolToken.Symbol, out var op) && GetBinaryOperatorPrecedence(op.Value) >= precedence)
|
while (CurrentToken is SymbolToken symbolToken && HasLeadingWhitespace(symbolToken) && HasTrailingWhitespace(symbolToken) && TryGetBinaryOperator(symbolToken.Symbol, out var op) && GetBinaryOperatorPrecedence(op.Value) >= precedence)
|
||||||
{
|
{
|
||||||
Next();
|
Next();
|
||||||
var right = ParseExpression(GetBinaryOperatorPrecedence(op.Value) + 1);
|
var right = ParseExpression(GetBinaryOperatorPrecedence(op.Value) + 1);
|
||||||
@@ -463,6 +485,68 @@ public sealed class Parser
|
|||||||
return ParsePostfixOperators(expr);
|
return ParsePostfixOperators(expr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ExpressionSyntax ParsePostfixOperators(ExpressionSyntax expr)
|
||||||
|
{
|
||||||
|
if (CurrentToken == null || HasLeadingWhitespace(CurrentToken))
|
||||||
|
{
|
||||||
|
return expr;
|
||||||
|
}
|
||||||
|
|
||||||
|
var startIndex = _tokenIndex;
|
||||||
|
while (HasToken)
|
||||||
|
{
|
||||||
|
if (TryExpectSymbol(Symbol.Caret))
|
||||||
|
{
|
||||||
|
expr = new DereferenceSyntax(GetTokens(startIndex), expr);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TryExpectSymbol(Symbol.Period))
|
||||||
|
{
|
||||||
|
var member = ExpectIdentifier();
|
||||||
|
expr = new MemberAccessSyntax(GetTokens(startIndex), expr, member);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TryExpectSymbol(Symbol.OpenBracket))
|
||||||
|
{
|
||||||
|
var index = ParseExpression();
|
||||||
|
ExpectSymbol(Symbol.CloseBracket);
|
||||||
|
expr = new ArrayIndexAccessSyntax(GetTokens(startIndex), expr, index);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TryExpectSymbol(Symbol.OpenParen))
|
||||||
|
{
|
||||||
|
var parameters = new List<ExpressionSyntax>();
|
||||||
|
|
||||||
|
while (!TryExpectSymbol(Symbol.CloseParen))
|
||||||
|
{
|
||||||
|
parameters.Add(ParseExpression());
|
||||||
|
if (!TryExpectSymbol(Symbol.Comma))
|
||||||
|
{
|
||||||
|
ExpectSymbol(Symbol.CloseParen);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
expr = new FuncCallSyntax(GetTokens(startIndex), expr, parameters);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return expr;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ExpressionSyntax ParseParenthesizedExpression()
|
||||||
|
{
|
||||||
|
var expression = ParseExpression();
|
||||||
|
ExpectSymbol(Symbol.CloseParen);
|
||||||
|
return expression;
|
||||||
|
}
|
||||||
|
|
||||||
private AddressOfSyntax ParseAddressOf(int startIndex)
|
private AddressOfSyntax ParseAddressOf(int startIndex)
|
||||||
{
|
{
|
||||||
var expression = ParsePrimaryExpression();
|
var expression = ParsePrimaryExpression();
|
||||||
@@ -518,63 +602,6 @@ public sealed class Parser
|
|||||||
return new LocalIdentifierSyntax(GetTokens(startIndex), identifier);
|
return new LocalIdentifierSyntax(GetTokens(startIndex), identifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ExpressionSyntax ParseParenthesizedExpression()
|
|
||||||
{
|
|
||||||
var expression = ParseExpression();
|
|
||||||
ExpectSymbol(Symbol.CloseParen);
|
|
||||||
return expression;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ExpressionSyntax ParsePostfixOperators(ExpressionSyntax expr)
|
|
||||||
{
|
|
||||||
var startIndex = _tokenIndex;
|
|
||||||
while (HasToken)
|
|
||||||
{
|
|
||||||
if (TryExpectSymbol(Symbol.Caret))
|
|
||||||
{
|
|
||||||
expr = new DereferenceSyntax(GetTokens(startIndex), expr);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TryExpectSymbol(Symbol.Period))
|
|
||||||
{
|
|
||||||
var member = ExpectIdentifier();
|
|
||||||
expr = new MemberAccessSyntax(GetTokens(startIndex), expr, member);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TryExpectSymbol(Symbol.OpenBracket))
|
|
||||||
{
|
|
||||||
var index = ParseExpression();
|
|
||||||
ExpectSymbol(Symbol.CloseBracket);
|
|
||||||
expr = new ArrayIndexAccessSyntax(GetTokens(startIndex), expr, index);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TryExpectSymbol(Symbol.OpenParen))
|
|
||||||
{
|
|
||||||
var parameters = new List<ExpressionSyntax>();
|
|
||||||
|
|
||||||
while (!TryExpectSymbol(Symbol.CloseParen))
|
|
||||||
{
|
|
||||||
parameters.Add(ParseExpression());
|
|
||||||
if (!TryExpectSymbol(Symbol.Comma))
|
|
||||||
{
|
|
||||||
ExpectSymbol(Symbol.CloseParen);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
expr = new FuncCallSyntax(GetTokens(startIndex), expr, parameters);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return expr;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ExpressionSyntax ParseArrayInitializer(int startIndex)
|
private ExpressionSyntax ParseArrayInitializer(int startIndex)
|
||||||
{
|
{
|
||||||
var values = new List<ExpressionSyntax>();
|
var values = new List<ExpressionSyntax>();
|
||||||
@@ -914,6 +941,10 @@ public sealed class Parser
|
|||||||
private void Next()
|
private void Next()
|
||||||
{
|
{
|
||||||
_tokenIndex++;
|
_tokenIndex++;
|
||||||
|
while (_tokenIndex < _tokens.Count && _tokens[_tokenIndex] is WhitespaceToken or CommentToken)
|
||||||
|
{
|
||||||
|
_tokenIndex++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Token> GetTokens(int tokenStartIndex)
|
private List<Token> GetTokens(int tokenStartIndex)
|
||||||
|
|||||||
@@ -2,18 +2,38 @@
|
|||||||
|
|
||||||
namespace NubLang.Syntax;
|
namespace NubLang.Syntax;
|
||||||
|
|
||||||
public abstract record Token(SourceSpan Span);
|
public abstract class Token(SourceSpan span)
|
||||||
|
|
||||||
public record IdentifierToken(SourceSpan Span, string Value) : Token(Span)
|
|
||||||
{
|
{
|
||||||
|
public SourceSpan Span { get; } = span;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class WhitespaceToken(SourceSpan span) : Token(span);
|
||||||
|
|
||||||
|
public class CommentToken(SourceSpan span, string comment) : Token(span)
|
||||||
|
{
|
||||||
|
public string Comment { get; } = comment;
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return "// " + Comment;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class IdentifierToken(SourceSpan span, string value) : Token(span)
|
||||||
|
{
|
||||||
|
public string Value { get; } = value;
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return Value;
|
return Value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public record IntLiteralToken(SourceSpan Span, string Value, int Base) : Token(Span)
|
public class IntLiteralToken(SourceSpan span, string value, int @base) : Token(span)
|
||||||
{
|
{
|
||||||
|
public string Value { get; } = value;
|
||||||
|
public int Base { get; } = @base;
|
||||||
|
|
||||||
private string GetNumericValue()
|
private string GetNumericValue()
|
||||||
{
|
{
|
||||||
return Base switch
|
return Base switch
|
||||||
@@ -43,24 +63,30 @@ public record IntLiteralToken(SourceSpan Span, string Value, int Base) : Token(S
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public record StringLiteralToken(SourceSpan Span, string Value) : Token(Span)
|
public class StringLiteralToken(SourceSpan span, string value) : Token(span)
|
||||||
{
|
{
|
||||||
|
public string Value { get; } = value;
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return $"\"{Value}\"";
|
return $"\"{Value}\"";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public record BoolLiteralToken(SourceSpan Span, bool Value) : Token(Span)
|
public class BoolLiteralToken(SourceSpan span, bool value) : Token(span)
|
||||||
{
|
{
|
||||||
|
public bool Value { get; } = value;
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return Value ? "true" : "false";
|
return Value ? "true" : "false";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public record FloatLiteralToken(SourceSpan Span, string Value) : Token(Span)
|
public class FloatLiteralToken(SourceSpan span, string value) : Token(span)
|
||||||
{
|
{
|
||||||
|
public string Value { get; } = value;
|
||||||
|
|
||||||
public float AsF32 => Convert.ToSingle(Value);
|
public float AsF32 => Convert.ToSingle(Value);
|
||||||
public double AsF64 => Convert.ToDouble(Value);
|
public double AsF64 => Convert.ToDouble(Value);
|
||||||
|
|
||||||
@@ -134,8 +160,10 @@ public enum Symbol
|
|||||||
QuestionMark,
|
QuestionMark,
|
||||||
}
|
}
|
||||||
|
|
||||||
public record SymbolToken(SourceSpan Span, Symbol Symbol) : Token(Span)
|
public class SymbolToken(SourceSpan span, Symbol symbol) : Token(span)
|
||||||
{
|
{
|
||||||
|
public Symbol Symbol { get; } = symbol;
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return Symbol switch
|
return Symbol switch
|
||||||
@@ -189,7 +217,6 @@ public record SymbolToken(SourceSpan Span, Symbol Symbol) : Token(Span)
|
|||||||
Symbol.Pipe => "|",
|
Symbol.Pipe => "|",
|
||||||
Symbol.At => "@",
|
Symbol.At => "@",
|
||||||
Symbol.QuestionMark => "?",
|
Symbol.QuestionMark => "?",
|
||||||
Symbol.Tilde => "~",
|
|
||||||
_ => "none",
|
_ => "none",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,32 +29,7 @@ public sealed class Tokenizer
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var current = _content[_index];
|
tokens.Add(ParseToken());
|
||||||
|
|
||||||
if (char.IsWhiteSpace(current))
|
|
||||||
{
|
|
||||||
if (current == '\n')
|
|
||||||
{
|
|
||||||
_line += 1;
|
|
||||||
_column = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Next();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (current == '/' && _index + 1 < _content.Length && _content[_index + 1] == '/')
|
|
||||||
{
|
|
||||||
Next(2);
|
|
||||||
while (_index < _content.Length && _content[_index] != '\n')
|
|
||||||
{
|
|
||||||
Next();
|
|
||||||
}
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
tokens.Add(ParseToken(current, _line, _column));
|
|
||||||
}
|
}
|
||||||
catch (CompileException e)
|
catch (CompileException e)
|
||||||
{
|
{
|
||||||
@@ -66,14 +41,40 @@ public sealed class Tokenizer
|
|||||||
return tokens;
|
return tokens;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Token ParseToken(char current, int lineStart, int columnStart)
|
private Token ParseToken()
|
||||||
{
|
{
|
||||||
if (char.IsDigit(current))
|
var lineStart = _line;
|
||||||
|
var columnStart = _column;
|
||||||
|
|
||||||
|
if (char.IsWhiteSpace(_content[_index]))
|
||||||
|
{
|
||||||
|
while (_index < _content.Length && char.IsWhiteSpace(_content[_index]))
|
||||||
|
{
|
||||||
|
Next();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new WhitespaceToken(CreateSpan(lineStart, columnStart));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_content[_index] == '/' && _index + 1 < _content.Length && _content[_index + 1] == '/')
|
||||||
|
{
|
||||||
|
var startIndex = _index;
|
||||||
|
|
||||||
|
Next(2);
|
||||||
|
while (_index < _content.Length && _content[_index] != '\n')
|
||||||
|
{
|
||||||
|
Next();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new CommentToken(CreateSpan(lineStart, columnStart), _content.AsSpan(startIndex, _index - startIndex).ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (char.IsDigit(_content[_index]))
|
||||||
{
|
{
|
||||||
return ParseNumber(lineStart, columnStart);
|
return ParseNumber(lineStart, columnStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (current == '"')
|
if (_content[_index] == '"')
|
||||||
{
|
{
|
||||||
return ParseString(lineStart, columnStart);
|
return ParseString(lineStart, columnStart);
|
||||||
}
|
}
|
||||||
@@ -87,12 +88,12 @@ public sealed class Tokenizer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (char.IsLetter(current) || current == '_')
|
if (char.IsLetter(_content[_index]) || _content[_index] == '_')
|
||||||
{
|
{
|
||||||
return ParseIdentifier(lineStart, columnStart);
|
return ParseIdentifier(lineStart, columnStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new CompileException(Diagnostic.Error($"Unknown token '{current}'").Build());
|
throw new CompileException(Diagnostic.Error($"Unknown token '{_content[_index]}'").Build());
|
||||||
}
|
}
|
||||||
|
|
||||||
private Token ParseNumber(int lineStart, int columnStart)
|
private Token ParseNumber(int lineStart, int columnStart)
|
||||||
@@ -382,7 +383,26 @@ public sealed class Tokenizer
|
|||||||
|
|
||||||
private void Next(int count = 1)
|
private void Next(int count = 1)
|
||||||
{
|
{
|
||||||
_index += count;
|
for (var i = 0; i < count; i++)
|
||||||
_column += count;
|
{
|
||||||
|
if (_index < _content.Length)
|
||||||
|
{
|
||||||
|
if (_content[_index] == '\n')
|
||||||
|
{
|
||||||
|
_line += 1;
|
||||||
|
_column = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_column++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_column++;
|
||||||
|
}
|
||||||
|
|
||||||
|
_index++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -9,9 +9,10 @@ struct Test
|
|||||||
|
|
||||||
extern "main" func main(argc: i64, argv: [?]^i8)
|
extern "main" func main(argc: i64, argv: [?]^i8)
|
||||||
{
|
{
|
||||||
let x = [1, 2, 3]
|
let x: ^i8 = "test"
|
||||||
|
// test
|
||||||
test(x)
|
^x^ = "uwu"
|
||||||
|
puts(x)
|
||||||
}
|
}
|
||||||
|
|
||||||
func test(arr: [?]i64)
|
func test(arr: [?]i64)
|
||||||
|
|||||||
Reference in New Issue
Block a user