-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
197 additions
and
177 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
namespace vein.ast.v2.syntax; | ||
namespace vein.ast; | ||
|
||
using Superpower.Model; | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
namespace vein.ast.v2.syntax; | ||
namespace vein.ast; | ||
|
||
using Superpower; | ||
using Superpower.Model; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,181 +1,42 @@ | ||
namespace vein.ast.v2.syntax; | ||
namespace vein.ast; | ||
|
||
using Newtonsoft.Json.Converters; | ||
using Superpower; | ||
using Superpower.Display; | ||
using Superpower.Model; | ||
using Superpower.Parsers; | ||
using System; | ||
|
||
public class VeinOperators | ||
{ | ||
|
||
} | ||
|
||
public abstract record BaseSyntax : ITransform | ||
{ | ||
public abstract SyntaxType Kind { get; } | ||
|
||
public TextSpan Transform { get; set; } | ||
public TextSpan TransformUntil { get; set; } | ||
} | ||
|
||
public abstract record ExpressionSyntax : BaseSyntax | ||
{ | ||
public string ExpressionValue { get; protected set; } | ||
} | ||
|
||
public record IdentifierExpression : ExpressionSyntax | ||
{ | ||
public IdentifierExpression(string exp) => ExpressionValue = exp; | ||
|
||
public override SyntaxType Kind => SyntaxType.IDENTIFIER; | ||
} | ||
|
||
public enum SyntaxType | ||
{ | ||
IDENTIFIER | ||
} | ||
|
||
public class VeinParseBase | ||
{ | ||
public TextParser<string> RawIdentifier => | ||
from first in Character.Letter.Or(Character.EqualTo('_').Or(Character.EqualTo('@'))) | ||
from rest in Character.LetterOrDigit.Or(Character.EqualTo('_').Or(Character.EqualTo('@'))).Many() | ||
select first + new string(rest); | ||
|
||
public TextParser<IdentifierExpression> IdentifierExpression => | ||
RawIdentifier.Named("Identifier") | ||
.Select(x => new IdentifierExpression(x)) | ||
.Message("required valid identifier expression") | ||
.WithLocation(); | ||
|
||
} | ||
|
||
public record VeinKeyword(string name); | ||
|
||
|
||
public abstract class NumericLiteralExpressionSyntax(string value) | ||
{ | ||
public string Value { get; } = value; | ||
} | ||
|
||
public class SByteValueExpressionSyntax(string value) : NumericLiteralExpressionSyntax(value); | ||
|
||
public class ByteValueExpressionSyntax(string value) : NumericLiteralExpressionSyntax(value); | ||
|
||
public class ShortValueExpressionSyntax(string value) : NumericLiteralExpressionSyntax(value); | ||
|
||
public class UShortValueExpressionSyntax(string value) : NumericLiteralExpressionSyntax(value); | ||
|
||
public class Int32ValueExpressionSyntax(string value) : NumericLiteralExpressionSyntax(value); | ||
|
||
public class UInt32ValueExpressionSyntax(string value) : NumericLiteralExpressionSyntax(value); | ||
|
||
public abstract class ExpressionSyntax2 | ||
{ | ||
public abstract int Evaluate(); | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
|
||
public enum TokenType | ||
{ | ||
Number_Int8, | ||
Number_Int16, | ||
Number_Int32, | ||
Number_Int64, | ||
Number_Float32, | ||
[Token(Category = "operator", Example = "+")] | ||
Plus, | ||
[Token(Category = "operator", Example = "-")] | ||
Minus, | ||
[Token(Category = "operator", Example = "*")] | ||
Multiply, | ||
[Token(Category = "operator", Example = "/")] | ||
Divide, | ||
[Token(Category = "operator", Example = "%")] | ||
Modulo, | ||
[Token(Category = "operator", Example = "^")] | ||
Power, | ||
[Token(Category = "operator", Example = "as")] | ||
As, | ||
[Token(Category = "operator", Example = "<")] | ||
LessThan, | ||
[Token(Category = "operator", Example = ">")] | ||
GreaterThan, | ||
OpenParen, | ||
CloseParen, | ||
Identifier, | ||
Comma | ||
} | ||
|
||
public class LiteralExpressionSyntax : ExpressionSyntax2 | ||
{ | ||
public NumericLiteralExpressionSyntax NumericLiteral { get; } | ||
|
||
public LiteralExpressionSyntax(NumericLiteralExpressionSyntax numericLiteral) | ||
{ | ||
NumericLiteral = numericLiteral; | ||
} | ||
|
||
public override int Evaluate() | ||
{ | ||
return int.Parse(NumericLiteral.Value); | ||
} | ||
} | ||
|
||
public class BinaryExpressionSyntax(ExpressionSyntax2 left, char @operator, ExpressionSyntax2 right) | ||
: ExpressionSyntax2 | ||
{ | ||
public ExpressionSyntax2 Left { get; } = left; | ||
public ExpressionSyntax2 Right { get; } = right; | ||
public char Operator { get; } = @operator; | ||
|
||
public override int Evaluate() | ||
{ | ||
var leftValue = Left.Evaluate(); | ||
var rightValue = Right.Evaluate(); | ||
|
||
return Operator switch | ||
{ | ||
'+' => leftValue + rightValue, | ||
'-' => leftValue - rightValue, | ||
'*' => leftValue * rightValue, | ||
'/' => leftValue / rightValue, | ||
_ => throw new InvalidOperationException("Unknown operator") | ||
}; | ||
} | ||
} | ||
|
||
|
||
public static class NumericParsers | ||
{ | ||
public static readonly TextParser<string> NumberParser = | ||
from digits in Character.Digit.AtLeastOnce() | ||
select new string(digits); | ||
|
||
public static readonly TextParser<string> SuffixParser = | ||
from suffix in Character.EqualToIgnoreCase('u').OptionalOrDefault() | ||
select suffix.ToString(); | ||
|
||
public static readonly TextParser<NumericLiteralExpressionSyntax> NumericLiteralExpression = | ||
from number in NumberParser | ||
from suffix in SuffixParser | ||
select DetermineType(number, suffix); | ||
|
||
public static NumericLiteralExpressionSyntax DetermineType(string number, string suffix) | ||
{ | ||
if (suffix == "u") | ||
{ | ||
uint parsedValue = uint.Parse(number); | ||
if (parsedValue <= byte.MaxValue) | ||
return new ByteValueExpressionSyntax(number); | ||
else if (parsedValue <= ushort.MaxValue) | ||
return new UShortValueExpressionSyntax(number); | ||
else if (parsedValue <= uint.MaxValue) | ||
return new UInt32ValueExpressionSyntax(number); | ||
} | ||
else | ||
{ | ||
int parsedValue = int.Parse(number); | ||
if (parsedValue is >= sbyte.MinValue and <= sbyte.MaxValue) | ||
return new SByteValueExpressionSyntax(number); | ||
else if (parsedValue is >= short.MinValue and <= short.MaxValue) | ||
return new ShortValueExpressionSyntax(number); | ||
else if (parsedValue is >= int.MinValue and <= int.MaxValue) | ||
return new Int32ValueExpressionSyntax(number); | ||
} | ||
|
||
throw new InvalidOperationException("Unsupported numeric range or suffix."); | ||
} | ||
|
||
public static readonly TextParser<ExpressionSyntax2> Literal = | ||
NumericLiteralExpression.Select(numericLiteral => new LiteralExpressionSyntax(numericLiteral) as ExpressionSyntax2); | ||
|
||
public static readonly TextParser<ExpressionSyntax2> Parenthesized = | ||
from lparen in Character.EqualTo('(') | ||
from expr in Parse.Ref(() => Expression) | ||
from rparen in Character.EqualTo(')') | ||
select expr; | ||
|
||
public static readonly TextParser<ExpressionSyntax2> Factor = | ||
Parenthesized.Or(Literal); | ||
|
||
public static readonly TextParser<ExpressionSyntax2> Term = | ||
Parse.Chain(Character.In('*', '/'), | ||
Factor, | ||
(op, left, right) => new BinaryExpressionSyntax(left, op, right)); | ||
|
||
public static readonly TextParser<ExpressionSyntax2> Expression = | ||
Parse.Chain(Character.In('+', '-'), | ||
Term, | ||
(op, left, right) => new BinaryExpressionSyntax(left, op, right)); | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,4 +4,5 @@ author: | |
github: 0xF6 | ||
license: MIT license | ||
packages: | ||
- ..\std\std.vproj | ||
- .\std.socket.test.vproj | ||
- [email protected] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
namespace astv2.test; | ||
|
||
using Superpower; | ||
using Superpower.Model; | ||
using Superpower.Parsers; | ||
using Superpower.Tokenizers; | ||
using System.Globalization; | ||
using System.Linq.Expressions; | ||
using vein.ast; | ||
|
||
public class Tests | ||
{ | ||
|
||
[Test] | ||
public void Test1() | ||
{ | ||
var tokenizer = new TokenizerBuilder<TokenType>() | ||
.Ignore(Span.WhiteSpace) | ||
.Match(Character.EqualTo('+'), TokenType.Plus) | ||
.Match(Character.EqualTo('-'), TokenType.Minus) | ||
.Match(Character.EqualTo('*'), TokenType.Multiply) | ||
.Match(Character.EqualTo('/'), TokenType.Divide) | ||
.Match(Character.EqualTo('('), TokenType.OpenParen) | ||
.Match(Character.EqualTo(')'), TokenType.CloseParen) | ||
.Match(DecimalFloat, TokenType.Number_Float32) | ||
.Match(Numerics.IntegerInt32, TokenType.Number_Int32) | ||
.Match(Numerics.IntegerInt64, TokenType.Number_Int64) | ||
.Build(); | ||
|
||
|
||
|
||
var result = ArithmeticExpressionParser.Ast.Parse(tokenizer.Tokenize("182 + 1 * 95 / 9102")); | ||
|
||
} | ||
|
||
public static TextParser<float> DecimalFloat { get; } = Numerics.Decimal.Select(span => float.Parse(span.ToStringValue(), CultureInfo.InvariantCulture)); | ||
|
||
} | ||
|
||
class ArithmeticExpressionParser | ||
{ | ||
static readonly TokenListParser<TokenType, ExpressionType> Add = | ||
Token.EqualTo(TokenType.Plus).Value(ExpressionType.AddChecked); | ||
|
||
static readonly TokenListParser<TokenType, ExpressionType> Subtract = | ||
Token.EqualTo(TokenType.Minus).Value(ExpressionType.SubtractChecked); | ||
|
||
static readonly TokenListParser<TokenType, ExpressionType> Multiply = | ||
Token.EqualTo(TokenType.Multiply).Value(ExpressionType.MultiplyChecked); | ||
|
||
static readonly TokenListParser<TokenType, ExpressionType> Divide = | ||
Token.EqualTo(TokenType.Divide).Value(ExpressionType.Divide); | ||
|
||
static readonly TokenListParser<TokenType, ExpressionType> Modulo = | ||
Token.EqualTo(TokenType.Modulo).Value(ExpressionType.Modulo); | ||
|
||
static readonly TokenListParser<TokenType, ExpressionType> Power = | ||
Token.EqualTo(TokenType.Power).Value(ExpressionType.Power); | ||
|
||
static readonly TokenListParser<TokenType, Expression> Constant = | ||
Token.EqualTo(TokenType.Number_Int32) | ||
.Apply(Numerics.IntegerInt32) | ||
.Select(n => (Expression)Expression.Constant(n)) | ||
.Or(Token.EqualTo(TokenType.Number_Float32) | ||
.Apply(Numerics.Decimal) | ||
.Select(f => (Expression)Expression.Constant(f))); | ||
|
||
|
||
static readonly TokenListParser<TokenType, Expression> Factor = | ||
(from lparen in Token.EqualTo(TokenType.OpenParen) | ||
from expr in Parse.Ref(() => Expr) | ||
from rparen in Token.EqualTo(TokenType.CloseParen) | ||
select expr) | ||
.Or(Constant); | ||
|
||
static readonly TokenListParser<TokenType, Expression> Operand = | ||
(from sign in Token.EqualTo(TokenType.Minus) | ||
from factor in Factor | ||
select (Expression)Expression.Negate(factor)) | ||
.Or(Factor).Named("expression"); | ||
|
||
static readonly TokenListParser<TokenType, Expression> Term = | ||
Parse.Chain(Multiply.Or(Divide).Or(Modulo).Or(Power), Operand, Expression.MakeBinary); | ||
|
||
static readonly TokenListParser<TokenType, Expression> Expr = | ||
Parse.Chain(Add.Or(Subtract), Term, Expression.MakeBinary); | ||
|
||
public static TokenListParser<TokenType, Expression<Func<T>>> Lambda<T>() where T : struct | ||
=> Expr.AtEnd().Select(body => Expression.Lambda<Func<T>>(body)); | ||
|
||
public static readonly TokenListParser<TokenType, Expression> Ast | ||
= Expr.AtEnd(); | ||
} |
Oops, something went wrong.