parser mostly done I hope
This commit is contained in:
parent
78fe931f97
commit
3884422afb
85
README.md
85
README.md
|
@ -54,29 +54,29 @@ pub fn y() {}
|
||||||
|
|
||||||
Functions can take the `[c_export]` attribute to make them callable when compiled as a static library, and to generate C headers for them.
|
Functions can take the `[c_export]` attribute to make them callable when compiled as a static library, and to generate C headers for them.
|
||||||
```
|
```
|
||||||
[c_export] pub fn foo(int a, Foo b, Bar c) -> int {
|
[c_export] pub fn foo(a: int, b: Foo, c: Bar): int {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[c_export("renamed_foo2")] pub fn foo2(int a, Foo b, Bar c) -> int, int {
|
[c_export("renamed_foo2")] pub fn foo2(a: int, b: Foo, c: Bar): int, int {
|
||||||
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Functions can be overloaded on parameter and return types
|
Functions can be overloaded on parameter and return types
|
||||||
```
|
```
|
||||||
fn a() -> s32 {
|
fn a(): s32 {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
fn a() -> u32 {
|
fn a(): u32 {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn a(i32 x, i32 y) -> (i32, i32) {
|
fn a(x: i32, y: i32): (i32, i32) {
|
||||||
return y, x;
|
return y, x;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn a(u32 x) -> u32 {
|
fn a(x: u32): u32 {
|
||||||
return x + 1;
|
return x + 1;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
@ -92,13 +92,13 @@ constraints are kind of weird because they
|
||||||
// this one can be used only as a constraint for generic type parameters
|
// this one can be used only as a constraint for generic type parameters
|
||||||
constraint Foo on A B {
|
constraint Foo on A B {
|
||||||
some_func(A, B);
|
some_func(A, B);
|
||||||
some_other_func(A) -> B;
|
some_other_func(A): B;
|
||||||
}
|
}
|
||||||
|
|
||||||
// this one can be used both as a constraint for generic type parameters or as an interface type
|
// this one can be used both as a constraint for generic type parameters or as an interface type
|
||||||
constraint Bar on A {
|
constraint Bar on A {
|
||||||
f1(A) -> A;
|
f1(A): A;
|
||||||
f2(A) -> i32;
|
f2(A): i32;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -111,7 +111,7 @@ fn foo<T1, T2>(T1 x)
|
||||||
some_func(x, y);
|
some_func(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bar<T>(T a) -> i32
|
fn bar<T>(T a): i32
|
||||||
where Bar T
|
where Bar T
|
||||||
{
|
{
|
||||||
T b = f1(a);
|
T b = f1(a);
|
||||||
|
@ -141,15 +141,6 @@ constraint Foo on A {
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
```
|
|
||||||
int a = 1;
|
|
||||||
mut int b = 2;
|
|
||||||
|
|
||||||
let a = 1;
|
|
||||||
mut let b = 2;
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
### literals
|
### literals
|
||||||
#### numeric
|
#### numeric
|
||||||
Numeric literals are untyped but literals with a decimal point can not be used as integers.
|
Numeric literals are untyped but literals with a decimal point can not be used as integers.
|
||||||
|
@ -190,27 +181,31 @@ Their type is an `u8` array with length of the string in bytes.
|
||||||
```
|
```
|
||||||
let a: [u8] = "foo";
|
let a: [u8] = "foo";
|
||||||
let b: u8 = a[1];
|
let b: u8 = a[1];
|
||||||
let d: [s32; 4] = {1,2,3,4};
|
let d: [s32; 4] = []{1,2,3,4};
|
||||||
let e = [u8]{1,2,3,4};
|
let e = [u8]{1,2,3,4};
|
||||||
|
|
||||||
|
type Arr = [u8];
|
||||||
|
let f = Arr[]{1,2,3};
|
||||||
|
|
||||||
```
|
```
|
||||||
##### struct
|
##### struct
|
||||||
###### declaration
|
###### declaration
|
||||||
```
|
```
|
||||||
struct Point {
|
struct Point {
|
||||||
s32 x;
|
x: s32;
|
||||||
s32 y;
|
y: s32;
|
||||||
s32 z;
|
z: s32;
|
||||||
}
|
}
|
||||||
type Point = struct {
|
type Point = struct {
|
||||||
s32 x;
|
x: s32;
|
||||||
s32 y;
|
y: s32;
|
||||||
s32 z;
|
z: s32;
|
||||||
}
|
}
|
||||||
|
|
||||||
type Options = struct {
|
type Options = struct {
|
||||||
struct {
|
api: struct {
|
||||||
int foo;
|
int foo;
|
||||||
} api;
|
};
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
##### use
|
##### use
|
||||||
|
@ -314,3 +309,37 @@ let e: u8 = *c; // 1
|
||||||
*(&a[0]+1) = 2; // a is now {0,2}
|
*(&a[0]+1) = 2; // a is now {0,2}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## operator precedence
|
||||||
|
|
||||||
|
```
|
||||||
|
. (struct member access), [] array subscripting
|
||||||
|
|
||||||
|
unaries: + - ! ~, pointer dereference *, pointer reference &,
|
||||||
|
binary operators:
|
||||||
|
* / %
|
||||||
|
+ -
|
||||||
|
<< >>
|
||||||
|
> >= < <=
|
||||||
|
== !=
|
||||||
|
&
|
||||||
|
^
|
||||||
|
|
|
||||||
|
&&
|
||||||
|
^^
|
||||||
|
||
|
||||||
|
lowest precedence, assignment:
|
||||||
|
=
|
||||||
|
+=
|
||||||
|
-=
|
||||||
|
/=
|
||||||
|
*=
|
||||||
|
%=
|
||||||
|
&=
|
||||||
|
|=
|
||||||
|
^=
|
||||||
|
<<=
|
||||||
|
>>=
|
||||||
|
|
||||||
|
```
|
|
@ -49,17 +49,16 @@ constraint Bar B {
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
struct Foo {
|
struct Foo {
|
||||||
int something;
|
something: int;
|
||||||
struct {
|
bar: struct {
|
||||||
int foo;
|
foo: int;
|
||||||
} bar;
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Foo f;
|
|
||||||
f.something
|
|
||||||
|
|
||||||
enum X {
|
enum X {
|
||||||
A,
|
A,
|
||||||
B,
|
B,
|
||||||
|
@ -79,7 +78,7 @@ enum X<T1, T2, T3> where Constraint T1 T2 where Constraint T2 T3 {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct X<T> {
|
struct X<T> {
|
||||||
T a;
|
a: T;
|
||||||
}
|
}
|
||||||
|
|
||||||
tuple Point(int,int,int)
|
tuple Point(int,int,int)
|
||||||
|
@ -89,3 +88,25 @@ tuple Point<T> where Arithmetic T (T,T,T)
|
||||||
type A = Foo;
|
type A = Foo;
|
||||||
|
|
||||||
type F<X> = Foo<Bar<X>>;
|
type F<X> = Foo<Bar<X>>;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
type X = [Y; 10];
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
fn foo() {
|
||||||
|
meoooow let x-nyaaaa = []{1-nya, meow 2};
|
||||||
|
|
||||||
|
outer: loop let x = 1; x < 10; x += 1 {
|
||||||
|
switch 1 {
|
||||||
|
case 1: {
|
||||||
|
foobar();
|
||||||
|
},
|
||||||
|
case 2: fallthrough,
|
||||||
|
case 3: x,
|
||||||
|
default: bar(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
4
parser/ArrayAccessExpressionModel.cs
Normal file
4
parser/ArrayAccessExpressionModel.cs
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public record ArrayAccessExpressionModel
|
||||||
|
(Span Span, ExpressionModel Expression, ExpressionModel Indexer) : ExpressionModel(Span);
|
4
parser/ArrayConstructorExpressionModel.cs
Normal file
4
parser/ArrayConstructorExpressionModel.cs
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public record ArrayConstructorExpressionModel(Span Span, TypeReferenceModel? Type,
|
||||||
|
List<ExpressionModel> Members) : ExpressionModel(Span);
|
3
parser/ArrayTypeModel.cs
Normal file
3
parser/ArrayTypeModel.cs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public record ArrayTypeModel(Span Span, TypeReferenceModel Type, string Length) : TypeReferenceModel(Span);
|
4
parser/AssignmentExpressionModel.cs
Normal file
4
parser/AssignmentExpressionModel.cs
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public record AssignmentExpressionModel(Span Span, PatternModel Pattern, AssignmentOperator Operator,
|
||||||
|
ExpressionModel Initializer) : ExpressionModel(Span);
|
16
parser/AssignmentOperator.cs
Normal file
16
parser/AssignmentOperator.cs
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public enum AssignmentOperator
|
||||||
|
{
|
||||||
|
Assign,
|
||||||
|
PlusAssign,
|
||||||
|
MinusAssign,
|
||||||
|
MultAssign,
|
||||||
|
DivAssign,
|
||||||
|
ModAssign,
|
||||||
|
BitwiseOrAssign,
|
||||||
|
BitwiseAndAssign,
|
||||||
|
BitwiseXorAssign,
|
||||||
|
ShiftRightAssign,
|
||||||
|
ShiftLeftAssign
|
||||||
|
}
|
34
parser/AssignmentOperatorExtensions.cs
Normal file
34
parser/AssignmentOperatorExtensions.cs
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public static class AssignmentOperatorExtensions
|
||||||
|
{
|
||||||
|
public static AssignmentOperator ToAssignmentOperator(this string str) => str switch
|
||||||
|
{
|
||||||
|
"=" => AssignmentOperator.Assign,
|
||||||
|
"+=" => AssignmentOperator.PlusAssign,
|
||||||
|
"-=" => AssignmentOperator.MinusAssign,
|
||||||
|
"*=" => AssignmentOperator.MultAssign,
|
||||||
|
"/=" => AssignmentOperator.DivAssign,
|
||||||
|
"%=" => AssignmentOperator.ModAssign,
|
||||||
|
"|=" => AssignmentOperator.BitwiseOrAssign,
|
||||||
|
"&=" => AssignmentOperator.BitwiseAndAssign,
|
||||||
|
"^=" => AssignmentOperator.BitwiseXorAssign,
|
||||||
|
">>=" => AssignmentOperator.ShiftRightAssign,
|
||||||
|
"<<=" => AssignmentOperator.ShiftLeftAssign,
|
||||||
|
};
|
||||||
|
|
||||||
|
public static string ToString(this AssignmentOperator op) => op switch
|
||||||
|
{
|
||||||
|
AssignmentOperator.Assign => "=",
|
||||||
|
AssignmentOperator.PlusAssign => "+=",
|
||||||
|
AssignmentOperator.MinusAssign => "-=",
|
||||||
|
AssignmentOperator.MultAssign => "*=",
|
||||||
|
AssignmentOperator.DivAssign => "/=",
|
||||||
|
AssignmentOperator.ModAssign => "%=",
|
||||||
|
AssignmentOperator.BitwiseOrAssign => "|=",
|
||||||
|
AssignmentOperator.BitwiseAndAssign => "&=",
|
||||||
|
AssignmentOperator.BitwiseXorAssign => "^=",
|
||||||
|
AssignmentOperator.ShiftRightAssign => ">>=",
|
||||||
|
AssignmentOperator.ShiftLeftAssign => "<<=",
|
||||||
|
};
|
||||||
|
}
|
3
parser/AttributeModel.cs
Normal file
3
parser/AttributeModel.cs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public record AttributeModel(Span Span, string Name, List<AttributeValueModel> Values) : ModelBase(Span);
|
3
parser/AttributeValueModel.cs
Normal file
3
parser/AttributeValueModel.cs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public abstract record AttributeValueModel(Span Span) : ModelBase(Span);
|
17
parser/AttributeValueVisitorNya.cs
Normal file
17
parser/AttributeValueVisitorNya.cs
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
using meowlang.parser.antlr;
|
||||||
|
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public class AttributeValueVisitorNya : MeowBaseVisitorNya<AttributeValueModel>
|
||||||
|
{
|
||||||
|
public override AttributeValueModel VisitAttributeValue(MeowParser.AttributeValueContext context)
|
||||||
|
{
|
||||||
|
if (context.id != null)
|
||||||
|
{
|
||||||
|
return new IdentifierAttributeValueModel(context.GetSpan(), context.id.Text);
|
||||||
|
}
|
||||||
|
|
||||||
|
var literal = new LiteralVisitorNya().Visit(context.literal());
|
||||||
|
return new LiteralAttributeValueModel(context.GetSpan(), literal);
|
||||||
|
}
|
||||||
|
}
|
13
parser/AttributeVisitorNya.cs
Normal file
13
parser/AttributeVisitorNya.cs
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
using meowlang.parser.antlr;
|
||||||
|
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public class AttributeVisitorNya : MeowBaseVisitorNya<AttributeModel>
|
||||||
|
{
|
||||||
|
public override AttributeModel VisitAttribute(MeowParser.AttributeContext context)
|
||||||
|
{
|
||||||
|
var name = context.name.Text;
|
||||||
|
var values = context.attributeValue().Select(x => new AttributeValueVisitorNya().Visit(x)).ToList();
|
||||||
|
return new AttributeModel(context.GetSpan(), name, values);
|
||||||
|
}
|
||||||
|
}
|
4
parser/BinaryOperationExpressionModel.cs
Normal file
4
parser/BinaryOperationExpressionModel.cs
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public record BinaryOperationExpressionModel(Span Span, ExpressionModel Left, BinaryOperator Operator,
|
||||||
|
ExpressionModel Right) : ExpressionModel(Span);
|
24
parser/BinaryOperator.cs
Normal file
24
parser/BinaryOperator.cs
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public enum BinaryOperator
|
||||||
|
{
|
||||||
|
LogicalOr,
|
||||||
|
LogicalAnd,
|
||||||
|
LogicalXor,
|
||||||
|
BitwiseOr,
|
||||||
|
BitwiseAnd,
|
||||||
|
BitwiseXor,
|
||||||
|
Equal,
|
||||||
|
NotEqual,
|
||||||
|
GreaterThan,
|
||||||
|
GreaterThanOrEqual,
|
||||||
|
LessThan,
|
||||||
|
LessThanOrEqual,
|
||||||
|
ShiftLeft,
|
||||||
|
ShiftRight,
|
||||||
|
Addition,
|
||||||
|
Subtraction,
|
||||||
|
Multiplication,
|
||||||
|
Division,
|
||||||
|
Modulo,
|
||||||
|
}
|
50
parser/BinaryOperatorExtensions.cs
Normal file
50
parser/BinaryOperatorExtensions.cs
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public static class BinaryOperatorExtensions
|
||||||
|
{
|
||||||
|
public static BinaryOperator ToBinaryOperator(this string str) => str switch
|
||||||
|
{
|
||||||
|
"||" => BinaryOperator.LogicalOr,
|
||||||
|
"&&" => BinaryOperator.LogicalAnd,
|
||||||
|
"^^" => BinaryOperator.LogicalXor,
|
||||||
|
"|" => BinaryOperator.BitwiseOr,
|
||||||
|
"&" => BinaryOperator.BitwiseAnd,
|
||||||
|
"^" => BinaryOperator.BitwiseXor,
|
||||||
|
"==" => BinaryOperator.Equal,
|
||||||
|
"!=" => BinaryOperator.NotEqual,
|
||||||
|
">" => BinaryOperator.GreaterThan,
|
||||||
|
">=" => BinaryOperator.GreaterThanOrEqual,
|
||||||
|
"<" => BinaryOperator.LessThan,
|
||||||
|
"<=" => BinaryOperator.LessThanOrEqual,
|
||||||
|
"<<" => BinaryOperator.ShiftLeft,
|
||||||
|
">>" => BinaryOperator.ShiftRight,
|
||||||
|
"+" => BinaryOperator.Addition,
|
||||||
|
"-" => BinaryOperator.Subtraction,
|
||||||
|
"*" => BinaryOperator.Multiplication,
|
||||||
|
"/" => BinaryOperator.Division,
|
||||||
|
"%" => BinaryOperator.Modulo,
|
||||||
|
};
|
||||||
|
|
||||||
|
public static string ToString(this BinaryOperator op) => op switch
|
||||||
|
{
|
||||||
|
BinaryOperator.LogicalOr => "||",
|
||||||
|
BinaryOperator.LogicalAnd => "&&",
|
||||||
|
BinaryOperator.LogicalXor => "^^",
|
||||||
|
BinaryOperator.BitwiseOr => "|",
|
||||||
|
BinaryOperator.BitwiseAnd => "&",
|
||||||
|
BinaryOperator.BitwiseXor => "^",
|
||||||
|
BinaryOperator.Equal => "==",
|
||||||
|
BinaryOperator.NotEqual => "!=",
|
||||||
|
BinaryOperator.GreaterThan => ">",
|
||||||
|
BinaryOperator.GreaterThanOrEqual => ">=",
|
||||||
|
BinaryOperator.LessThan => "<",
|
||||||
|
BinaryOperator.LessThanOrEqual => "<=",
|
||||||
|
BinaryOperator.ShiftLeft => "<<",
|
||||||
|
BinaryOperator.ShiftRight => ">>",
|
||||||
|
BinaryOperator.Addition => "+",
|
||||||
|
BinaryOperator.Subtraction => "-",
|
||||||
|
BinaryOperator.Multiplication => "*",
|
||||||
|
BinaryOperator.Division => "/",
|
||||||
|
BinaryOperator.Modulo => "%",
|
||||||
|
};
|
||||||
|
}
|
3
parser/BlockExpressionModel.cs
Normal file
3
parser/BlockExpressionModel.cs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public record BlockExpressionModel(Span Span, List<StatementModel> Statements, ExpressionModel? Value) : ExpressionModel(Span);
|
3
parser/BoolLiteralModel.cs
Normal file
3
parser/BoolLiteralModel.cs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public record BoolLiteralModel(Span Span, bool Value) : LiteralModel(Span);
|
3
parser/BreakStatementModel.cs
Normal file
3
parser/BreakStatementModel.cs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public record BreakStatementModel(Span Span, string? Label) : StatementModel(Span);
|
3
parser/CharacterLiteralModel.cs
Normal file
3
parser/CharacterLiteralModel.cs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public record CharacterLiteralModel(Span Span, string Value) : LiteralModel(Span);
|
4
parser/ConstantDeclarationStatementModel.cs
Normal file
4
parser/ConstantDeclarationStatementModel.cs
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public record ConstantDeclarationStatementModel
|
||||||
|
(Span Span, List<string> Names, ExpressionModel Initializer) : StatementModel(Span);
|
3
parser/ConstraintModel.cs
Normal file
3
parser/ConstraintModel.cs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public record ConstraintModel(Span Span, string Name, List<string> TypeNames) : ModelBase(Span);
|
3
parser/ConstraintRuleModel.cs
Normal file
3
parser/ConstraintRuleModel.cs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public abstract record ConstraintRuleModel(Span Span) : ModelBase(Span);
|
24
parser/ConstraintRuleVisitorNya.cs
Normal file
24
parser/ConstraintRuleVisitorNya.cs
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
using meowlang.parser.antlr;
|
||||||
|
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public class ConstraintRuleVisitorNya : MeowBaseVisitorNya<ConstraintRuleModel>
|
||||||
|
{
|
||||||
|
public override ConstraintRuleModel VisitEmbedConstraintRule(MeowParser.EmbedConstraintRuleContext context)
|
||||||
|
{
|
||||||
|
var name = context.name.Text;
|
||||||
|
var types = context._types.Select(x => new TypeReferenceVisitorNya().Visit(x)).ToList();
|
||||||
|
return new EmbedConstraintRuleModel(context.GetSpan(), name, types);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ConstraintRuleModel VisitFunctionConstraintRule(MeowParser.FunctionConstraintRuleContext context)
|
||||||
|
{
|
||||||
|
var name = context.name.Text;
|
||||||
|
var parameters = context.constraintFunctionParameters().typeReference()
|
||||||
|
.Select(x => new TypeReferenceVisitorNya().Visit(x)).ToList();
|
||||||
|
var returns =
|
||||||
|
context.functionReturn()?.typeReference().Select(x => new TypeReferenceVisitorNya().Visit(x)).ToList() ??
|
||||||
|
new List<TypeReferenceModel>();
|
||||||
|
return new FunctionConstraintRuleModel(context.GetSpan(), name, parameters, returns);
|
||||||
|
}
|
||||||
|
}
|
4
parser/ConstraintTopLevelConstructModel.cs
Normal file
4
parser/ConstraintTopLevelConstructModel.cs
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public record ConstraintTopLevelConstructModel
|
||||||
|
(Span Span, List<AttributeModel> Attributes, bool Pub, string Name, List<string> TypeNames, List<ConstraintRuleModel> Rules) : TopLevelConstructModel(Span);
|
3
parser/ContinueStatementModel.cs
Normal file
3
parser/ContinueStatementModel.cs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public record ContinueStatementModel(Span Span, string? Label) : StatementModel(Span);
|
101
parser/DeclarationVisitorNya.cs
Normal file
101
parser/DeclarationVisitorNya.cs
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
using Antlr4.Runtime.Tree;
|
||||||
|
using meowlang.parser.antlr;
|
||||||
|
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public class DeclarationVisitorNya : MeowBaseVisitorNya<TopLevelConstructModel>
|
||||||
|
{
|
||||||
|
public override TopLevelConstructModel VisitTopLevelStatement(MeowParser.TopLevelStatementContext context)
|
||||||
|
{
|
||||||
|
var statement = new StatementVisitorNya().Visit(context);
|
||||||
|
return new TopLevelStatementModel(context.GetSpan(), statement);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override TopLevelConstructModel VisitFunction(MeowParser.FunctionContext context)
|
||||||
|
{
|
||||||
|
var attributes = context.attribute().Select(x => new AttributeVisitorNya().Visit(x)).ToList();
|
||||||
|
var pub = context.pub != null;
|
||||||
|
var name = context.name.Text;
|
||||||
|
|
||||||
|
var typeParameters =
|
||||||
|
context.genericParameters()?._name.Select(x => new TypeParameterModel(x.GetSpan(), x.Text)).ToList() ??
|
||||||
|
new List<TypeParameterModel>();
|
||||||
|
var functionParameters = context.functionParameters().functionParameter()
|
||||||
|
.Select(x => new FunctionParameterVisitorNya().Visit(x)).ToList();
|
||||||
|
var functionReturns = context.functionReturn()?.typeReference().Select(x => new TypeReferenceVisitorNya().Visit(x))
|
||||||
|
.ToList() ?? new List<TypeReferenceModel>();
|
||||||
|
var constraints = context.constraint()?.Select(x => new FunctionConstraintVisitorNya().Visit(x)).ToList() ??
|
||||||
|
new List<ConstraintModel>();
|
||||||
|
|
||||||
|
var body = new ExpressionVisitorNya().Visit(context.body);
|
||||||
|
|
||||||
|
return new FunctionModel(context.GetSpan(), attributes, pub, name, typeParameters, functionParameters,
|
||||||
|
functionReturns, constraints, body);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ConstraintTopLevelConstructModel VisitConstraintDeclaration(
|
||||||
|
MeowParser.ConstraintDeclarationContext context)
|
||||||
|
{
|
||||||
|
var attributes = context.attribute().Select(x => new AttributeVisitorNya().Visit(x)).ToList();
|
||||||
|
var pub = context.pub != null;
|
||||||
|
var name = context.name.Text;
|
||||||
|
var typeNames = context._types.Select(x => x.Text).ToList();
|
||||||
|
var rules = context.constraintRule().Select(x => new ConstraintRuleVisitorNya().Visit(x)).ToList();
|
||||||
|
return new ConstraintTopLevelConstructModel(context.GetSpan(), attributes, pub, name, typeNames, rules);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override TopLevelConstructModel VisitStructDeclaration(MeowParser.StructDeclarationContext context)
|
||||||
|
{
|
||||||
|
var attributes = context.attribute().Select(x => new AttributeVisitorNya().Visit(x)).ToList();
|
||||||
|
var pub = context.pub != null;
|
||||||
|
var name = context.name.Text;
|
||||||
|
var typeParameters = context.genericParameters()?._name.Select(x => x.Text).ToList() ?? new List<string>();
|
||||||
|
var constraints = context.constraint()?.Select(x => new FunctionConstraintVisitorNya().Visit(x)).ToList() ??
|
||||||
|
new List<ConstraintModel>();
|
||||||
|
var structModel = new TypeReferenceVisitorNya().Visit(context.structType()) as StructTypeModel;
|
||||||
|
return new StructTopLevelConstructModel(context.GetSpan(), attributes, pub, name, typeParameters, constraints, structModel!);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override TopLevelConstructModel VisitEnumDeclaration(MeowParser.EnumDeclarationContext context)
|
||||||
|
{
|
||||||
|
var attributes = context.attribute().Select(x => new AttributeVisitorNya().Visit(x)).ToList();
|
||||||
|
var pub = context.pub != null;
|
||||||
|
var name = context.name.Text;
|
||||||
|
var typeParameters = context.genericParameters()?._name.Select(x => x.Text).ToList() ?? new List<string>();
|
||||||
|
var constraints = context.constraint()?.Select(x => new FunctionConstraintVisitorNya().Visit(x)).ToList() ??
|
||||||
|
new List<ConstraintModel>();
|
||||||
|
|
||||||
|
var enumModel = new TypeReferenceVisitorNya().Visit(context.enumType()) as EnumTypeModel;
|
||||||
|
return new EnumTopLevelConstructModel(context.GetSpan(), attributes, pub, name, typeParameters, constraints, enumModel!);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override TopLevelConstructModel VisitTupleDeclaration(MeowParser.TupleDeclarationContext context)
|
||||||
|
{
|
||||||
|
var attributes = context.attribute().Select(x => new AttributeVisitorNya().Visit(x)).ToList();
|
||||||
|
var pub = context.pub != null;
|
||||||
|
var name = context.name.Text;
|
||||||
|
var typeParameters = context.genericParameters()?._name.Select(x => x.Text).ToList() ?? new List<string>();
|
||||||
|
var constraints = context.constraint()?.Select(x => new FunctionConstraintVisitorNya().Visit(x)).ToList() ??
|
||||||
|
new List<ConstraintModel>();
|
||||||
|
var tupleModel = new TypeReferenceVisitorNya().Visit(context.tupleType()) as TupleTypeModel;
|
||||||
|
return new TupleTopLevelConstructModel(context.GetSpan(), attributes, pub, name, typeParameters, constraints, tupleModel!);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override TopLevelConstructModel VisitTypeAlias(MeowParser.TypeAliasContext context)
|
||||||
|
{
|
||||||
|
var attributes = context.attribute().Select(x => new AttributeVisitorNya().Visit(x)).ToList();
|
||||||
|
var pub = context.pub != null;
|
||||||
|
var name = context.name.Text;
|
||||||
|
var typeParameters = context.genericParameters()?._name.Select(x => x.Text).ToList() ?? new List<string>();
|
||||||
|
var type = new TypeReferenceVisitorNya().Visit(context.typeReference());
|
||||||
|
return new TypeAliasModel(context.GetSpan(), attributes, pub, name, typeParameters, type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class MeowBaseVisitorNya<T> : MeowBaseVisitor<T>
|
||||||
|
{
|
||||||
|
public T? TryVisit(IParseTree? tree)
|
||||||
|
{
|
||||||
|
return tree == null ? default : Visit(tree);
|
||||||
|
}
|
||||||
|
}
|
4
parser/EmbedConstraintRuleModel.cs
Normal file
4
parser/EmbedConstraintRuleModel.cs
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public record EmbedConstraintRuleModel
|
||||||
|
(Span Span, string Name, List<TypeReferenceModel> Types) : ConstraintRuleModel(Span);
|
3
parser/EnumConstructorExpressionModel.cs
Normal file
3
parser/EnumConstructorExpressionModel.cs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public record EnumConstructorExpressionModel(Span Span, TypeNameModel Type, string Name) : ExpressionModel(Span);
|
3
parser/EnumMemberModel.cs
Normal file
3
parser/EnumMemberModel.cs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public record EnumMemberModel(Span Span, string Name, TypeReferenceModel? Type) : ModelBase(Span);
|
20
parser/EnumMemberVisitorNya.cs
Normal file
20
parser/EnumMemberVisitorNya.cs
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
using meowlang.parser.antlr;
|
||||||
|
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public class EnumMemberVisitorNya : MeowBaseVisitorNya<EnumMemberModel>
|
||||||
|
{
|
||||||
|
public override EnumMemberModel VisitEnumMember(MeowParser.EnumMemberContext context)
|
||||||
|
{
|
||||||
|
var name = context.name.Text;
|
||||||
|
|
||||||
|
TypeReferenceModel? type = null;
|
||||||
|
var typeRef = context.typeReference();
|
||||||
|
if (typeRef != null)
|
||||||
|
{
|
||||||
|
type = new TypeReferenceVisitorNya().Visit(typeRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new EnumMemberModel(context.GetSpan(), name, type);
|
||||||
|
}
|
||||||
|
}
|
4
parser/EnumTopLevelConstructModel.cs
Normal file
4
parser/EnumTopLevelConstructModel.cs
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public record EnumTopLevelConstructModel(Span Span, List<AttributeModel> Attributes, bool Pub, string Name, List<string> TypeParameters,
|
||||||
|
List<ConstraintModel> Constraints, EnumTypeModel Enum) : TopLevelConstructModel(Span);
|
3
parser/EnumTypeModel.cs
Normal file
3
parser/EnumTypeModel.cs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public record EnumTypeModel(Span Span, List<EnumMemberModel> Members) : TypeReferenceModel(Span);
|
3
parser/ExpressionModel.cs
Normal file
3
parser/ExpressionModel.cs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public abstract record ExpressionModel(Span Span) : ModelBase(Span);
|
3
parser/ExpressionStatementModel.cs
Normal file
3
parser/ExpressionStatementModel.cs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public record ExpressionStatementModel(Span Span, ExpressionModel Expression) : StatementModel(Span);
|
255
parser/ExpressionVisitorNya.cs
Normal file
255
parser/ExpressionVisitorNya.cs
Normal file
|
@ -0,0 +1,255 @@
|
||||||
|
using Antlr4.Runtime;
|
||||||
|
using meowlang.parser.antlr;
|
||||||
|
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public class ExpressionVisitorNya : MeowBaseVisitorNya<ExpressionModel>
|
||||||
|
{
|
||||||
|
public override ExpressionModel VisitAssignmentExpression(MeowParser.AssignmentExpressionContext context)
|
||||||
|
{
|
||||||
|
var expression = Visit(context.logicalOrExpression());
|
||||||
|
if (context.op == null)
|
||||||
|
{
|
||||||
|
return expression;
|
||||||
|
}
|
||||||
|
|
||||||
|
var op = context.op.Text.ToAssignmentOperator();
|
||||||
|
var pattern = new PatternModel(context.pattern().GetSpan(),
|
||||||
|
new List<ExpressionModel>(context.pattern().pointerDereferenceExpression()
|
||||||
|
.Select(Visit).ToList()));
|
||||||
|
return new AssignmentExpressionModel(context.GetSpan(), pattern, op, expression);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ExpressionModel MakeBinOpTree(List<ExpressionModel> expressions, BinaryOperator op)
|
||||||
|
{
|
||||||
|
if (expressions.Count == 1) return expressions[0];
|
||||||
|
var left = MakeBinOpTree(expressions.Take(expressions.Count - 1).ToList(), op);
|
||||||
|
var right = expressions[^1];
|
||||||
|
var span = new Span(left.Span.Filename, left.Span.From, right.Span.To);
|
||||||
|
return new BinaryOperationExpressionModel(span, left, op, right);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ExpressionModel MakeBinOpTree(List<ExpressionModel> expressions, List<BinaryOperator> ops)
|
||||||
|
{
|
||||||
|
if (expressions.Count == 1) return expressions[0];
|
||||||
|
var op = ops[^1];
|
||||||
|
var right = expressions[^1];
|
||||||
|
var remainingExpressions = expressions.Take(expressions.Count - 1).ToList();
|
||||||
|
var remainingOps = ops.Take(ops.Count - 1).ToList();
|
||||||
|
var left = MakeBinOpTree(remainingExpressions, remainingOps);
|
||||||
|
var span = new Span(left.Span.Filename, left.Span.From, right.Span.To);
|
||||||
|
return new BinaryOperationExpressionModel(span, left, op, right);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ExpressionModel VisitLogicalOrExpression(MeowParser.LogicalOrExpressionContext context)
|
||||||
|
{
|
||||||
|
var expressions = context.logicalXorExpression().Select(Visit).ToList();
|
||||||
|
return MakeBinOpTree(expressions, BinaryOperator.LogicalOr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ExpressionModel VisitLogicalXorExpression(MeowParser.LogicalXorExpressionContext context)
|
||||||
|
{
|
||||||
|
var expressions = context.logicalAndExpression().Select(Visit).ToList();
|
||||||
|
return MakeBinOpTree(expressions, BinaryOperator.LogicalXor);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ExpressionModel VisitLogicalAndExpression(MeowParser.LogicalAndExpressionContext context)
|
||||||
|
{
|
||||||
|
var expressions = context.bitwiseOrExpression().Select(Visit).ToList();
|
||||||
|
return MakeBinOpTree(expressions, BinaryOperator.LogicalAnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ExpressionModel VisitBitwiseOrExpression(MeowParser.BitwiseOrExpressionContext context)
|
||||||
|
{
|
||||||
|
var expressions = context.bitwiseXorExpression().Select(Visit).ToList();
|
||||||
|
return MakeBinOpTree(expressions, BinaryOperator.BitwiseOr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ExpressionModel VisitBitwiseXorExpression(MeowParser.BitwiseXorExpressionContext context)
|
||||||
|
{
|
||||||
|
var expressions = context.bitwiseAndExpression().Select(Visit).ToList();
|
||||||
|
return MakeBinOpTree(expressions, BinaryOperator.BitwiseXor);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ExpressionModel VisitBitwiseAndExpression(MeowParser.BitwiseAndExpressionContext context)
|
||||||
|
{
|
||||||
|
var expressions = context.equalityExpression().Select(Visit).ToList();
|
||||||
|
return MakeBinOpTree(expressions, BinaryOperator.BitwiseAnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ExpressionModel VisitEqualityExpression(MeowParser.EqualityExpressionContext context)
|
||||||
|
{
|
||||||
|
var expressions = context.relationalExpression().Select(Visit).ToList();
|
||||||
|
var operators = context._op.Select(x => x.Text.ToBinaryOperator()).ToList();
|
||||||
|
return MakeBinOpTree(expressions, operators);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ExpressionModel VisitRelationalExpression(MeowParser.RelationalExpressionContext context)
|
||||||
|
{
|
||||||
|
var expressions = context.shiftExpression().Select(Visit).ToList();
|
||||||
|
var operators = context._op.Select(x => x.Text.ToBinaryOperator()).ToList();
|
||||||
|
return MakeBinOpTree(expressions, operators);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ExpressionModel VisitShiftExpression(MeowParser.ShiftExpressionContext context)
|
||||||
|
{
|
||||||
|
var expressions = context.addExpression().Select(Visit).ToList();
|
||||||
|
var operators = context._op.Select(x => x.Text.Replace(">", ">>").ToBinaryOperator()).ToList();
|
||||||
|
return MakeBinOpTree(expressions, operators);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ExpressionModel VisitAddExpression(MeowParser.AddExpressionContext context)
|
||||||
|
{
|
||||||
|
var expressions = context.multExpression().Select(Visit).ToList();
|
||||||
|
var operators = context._op.Select(x => x.Text.ToBinaryOperator()).ToList();
|
||||||
|
return MakeBinOpTree(expressions, operators);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ExpressionModel VisitMultExpression(MeowParser.MultExpressionContext context)
|
||||||
|
{
|
||||||
|
var expressions = context.unaryExpression().Select(Visit).ToList();
|
||||||
|
var operators = context._op.Select(x => x.Text.ToBinaryOperator()).ToList();
|
||||||
|
return MakeBinOpTree(expressions, operators);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ExpressionModel VisitUnaryExpression(MeowParser.UnaryExpressionContext context)
|
||||||
|
{
|
||||||
|
var expression = Visit(context.pointerDereferenceExpression());
|
||||||
|
foreach (var unaryOperator in context._op.Reverse())
|
||||||
|
{
|
||||||
|
var span = new Span(expression.Span.Filename, unaryOperator.StartIndex, expression.Span.To);
|
||||||
|
if (unaryOperator.Text == "&")
|
||||||
|
{
|
||||||
|
expression = new PointerReferenceExpressionModel(span, expression);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
expression = new UnaryOperationExpressionModel(span, unaryOperator.Text.ToUnaryOperator(), expression);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return expression;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ExpressionModel VisitPointerDereferenceExpression(
|
||||||
|
MeowParser.PointerDereferenceExpressionContext context)
|
||||||
|
{
|
||||||
|
var expression = Visit(context.accessExpression());
|
||||||
|
foreach (var op in context._op.Reverse())
|
||||||
|
{
|
||||||
|
var span = new Span(expression.Span.Filename, op.StartIndex, expression.Span.To);
|
||||||
|
expression = new PointerDereferenceExpressionModel(span, expression);
|
||||||
|
}
|
||||||
|
|
||||||
|
return expression;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ExpressionModel VisitAccessExpression(MeowParser.AccessExpressionContext context)
|
||||||
|
{
|
||||||
|
var expression = Visit(context.terminalExpression());
|
||||||
|
var current = context.accessExpression1();
|
||||||
|
while (current != null)
|
||||||
|
{
|
||||||
|
if (current.subscript != null) // array access
|
||||||
|
{
|
||||||
|
var span = new Span(expression.Span.Filename, expression.Span.From, current.end.StopIndex);
|
||||||
|
var indexer = Visit(current.subscript);
|
||||||
|
expression = new ArrayAccessExpressionModel(span, expression, indexer);
|
||||||
|
}
|
||||||
|
else // struct access
|
||||||
|
{
|
||||||
|
var span = new Span(expression.Span.Filename, expression.Span.From, current.name.StopIndex);
|
||||||
|
var name = current.name.Text;
|
||||||
|
if (name.Contains('.') || !Char.IsDigit(name.TrimStart('0')[0]))
|
||||||
|
{
|
||||||
|
throw new InvalidStructAccessorException(current.name, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
expression = new StructAccessExpressionModel(span, expression, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
current = current.accessExpression1();
|
||||||
|
}
|
||||||
|
|
||||||
|
return expression;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ExpressionModel VisitLiteralExpression(MeowParser.LiteralExpressionContext context)
|
||||||
|
{
|
||||||
|
var literal = new LiteralVisitorNya().Visit(context.literal());
|
||||||
|
return new LiteralExpressionModel(context.GetSpan(), literal);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public override ExpressionModel VisitNameExpression(MeowParser.NameExpressionContext context)
|
||||||
|
{
|
||||||
|
var name = new IdentifierNameVisitorNya().Visit(context.identifierName());
|
||||||
|
return new NameExpressionModel(context.GetSpan(), name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ExpressionModel VisitStructConstructor(MeowParser.StructConstructorContext context)
|
||||||
|
{
|
||||||
|
var typeName = new TypeReferenceVisitorNya().TryVisit(context.typeName()) as TypeNameModel;
|
||||||
|
var members = context.structConstructorMember().Select(x =>
|
||||||
|
new StructConstructorMemberModel(x.GetSpan(), x.name.Text, Visit(x.expression()))).ToList();
|
||||||
|
return new StructConstructorExpressionModel(context.GetSpan(), typeName, members);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ExpressionModel VisitArrayConstructor(MeowParser.ArrayConstructorContext context)
|
||||||
|
{
|
||||||
|
var type = new TypeReferenceVisitorNya().TryVisit(context.arrayType() ?? context.typeName() as ParserRuleContext);
|
||||||
|
var members = context.expression().Select(Visit).ToList();
|
||||||
|
return new ArrayConstructorExpressionModel(context.GetSpan(), type, members);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ExpressionModel VisitEnumConstructor(MeowParser.EnumConstructorContext context)
|
||||||
|
{
|
||||||
|
var typeName = new TypeReferenceVisitorNya().TryVisit(context.typeName()) as TypeNameModel;
|
||||||
|
var name = context.name.Text;
|
||||||
|
return new EnumConstructorExpressionModel(context.GetSpan(), typeName!, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ExpressionModel VisitTupleConstructor(MeowParser.TupleConstructorContext context)
|
||||||
|
{
|
||||||
|
var values = context.expression().Select(Visit).ToList();
|
||||||
|
return new TupleConstructorExpressionModel(context.GetSpan(), values);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ExpressionModel VisitFunctionCall(MeowParser.FunctionCallContext context)
|
||||||
|
{
|
||||||
|
var name = new IdentifierNameVisitorNya().Visit(context.identifierName());
|
||||||
|
var arguments = context.expression().Select(Visit).ToList();
|
||||||
|
return new FunctionCallExpressionModel(context.GetSpan(), name, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ExpressionModel VisitIfExpression(MeowParser.IfExpressionContext context)
|
||||||
|
{
|
||||||
|
var cond = Visit(context.cond);
|
||||||
|
var then = Visit(context.then) as BlockExpressionModel;
|
||||||
|
var @else = TryVisit(context.@else) as BlockExpressionModel;
|
||||||
|
var ifElses = context.elseIfExpression().Select(x => (Visit(x.cond), (Visit(x.then) as BlockExpressionModel)!))
|
||||||
|
.ToList();
|
||||||
|
return new IfExpressionModel(context.GetSpan(), cond, then!, ifElses, @else);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ExpressionModel VisitSwitchExpression(MeowParser.SwitchExpressionContext context)
|
||||||
|
{
|
||||||
|
var expression = Visit(context.expression());
|
||||||
|
var cases = context.switchCase().Select(x => (new LiteralVisitorNya().Visit(x.literal()), TryVisit(x.expression()))).ToList();
|
||||||
|
var defaultCase = TryVisit(context.switchDefault()?.expression());
|
||||||
|
return new SwitchExpressionModel(context.GetSpan(), expression, cases, defaultCase);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ExpressionModel VisitBlockExpression(MeowParser.BlockExpressionContext context)
|
||||||
|
{
|
||||||
|
var statements = context.terminatedStatement().Select(x => new StatementVisitorNya().Visit(x)).ToList();
|
||||||
|
var value = TryVisit(context.expression());
|
||||||
|
return new BlockExpressionModel(context.GetSpan(), statements, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ExpressionModel VisitParenthesisExpression(MeowParser.ParenthesisExpressionContext context)
|
||||||
|
{
|
||||||
|
var expression = Visit(context.expression());
|
||||||
|
return new ParenthesisExpressionModel(context.GetSpan(), expression);
|
||||||
|
}
|
||||||
|
}
|
5
parser/ForLoopStatementModel.cs
Normal file
5
parser/ForLoopStatementModel.cs
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public record ForLoopStatementModel(Span Span, List<StatementModel> Body,
|
||||||
|
VariableDeclarationStatementModel? InitStatement, ExpressionModel? InitExpression, ExpressionModel? Condition,
|
||||||
|
ExpressionModel? Increment) : LoopStatementModel(Span, Body);
|
4
parser/FunctionCallExpressionModel.cs
Normal file
4
parser/FunctionCallExpressionModel.cs
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public record FunctionCallExpressionModel
|
||||||
|
(Span Span, IdentifierNameModel Name, List<ExpressionModel> Arguments) : ExpressionModel(Span);
|
4
parser/FunctionConstraintRuleModel.cs
Normal file
4
parser/FunctionConstraintRuleModel.cs
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public record FunctionConstraintRuleModel(Span Span, string Name, List<TypeReferenceModel> Parameters,
|
||||||
|
List<TypeReferenceModel> Returns) : ConstraintRuleModel(Span);
|
13
parser/FunctionConstraintVisitorNya.cs
Normal file
13
parser/FunctionConstraintVisitorNya.cs
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
using meowlang.parser.antlr;
|
||||||
|
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public class FunctionConstraintVisitorNya : MeowBaseVisitorNya<ConstraintModel>
|
||||||
|
{
|
||||||
|
public override ConstraintModel VisitConstraint(MeowParser.ConstraintContext context)
|
||||||
|
{
|
||||||
|
var name = context.name.Text;
|
||||||
|
var typeNames = context._typenames.Select(x => x.Text).ToList();
|
||||||
|
return new ConstraintModel(context.GetSpan(), name, typeNames);
|
||||||
|
}
|
||||||
|
}
|
5
parser/FunctionModel.cs
Normal file
5
parser/FunctionModel.cs
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public record FunctionModel(Span Span, List<AttributeModel> Attributes, bool Pub, string Name,
|
||||||
|
List<TypeParameterModel> TypeParameters, List<FunctionParameterModel> Parameters, List<TypeReferenceModel> Returns,
|
||||||
|
List<ConstraintModel> Constraints, ExpressionModel Body) : TopLevelConstructModel(Span);
|
3
parser/FunctionParameterModel.cs
Normal file
3
parser/FunctionParameterModel.cs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public record FunctionParameterModel(Span Span, TypeReferenceModel Type, string Name) : ModelBase(Span);
|
13
parser/FunctionParameterVisitorNya.cs
Normal file
13
parser/FunctionParameterVisitorNya.cs
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
using meowlang.parser.antlr;
|
||||||
|
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public class FunctionParameterVisitorNya : MeowBaseVisitorNya<FunctionParameterModel>
|
||||||
|
{
|
||||||
|
public override FunctionParameterModel VisitFunctionParameter(MeowParser.FunctionParameterContext context)
|
||||||
|
{
|
||||||
|
var type = new TypeReferenceVisitorNya().Visit(context.typeReference());
|
||||||
|
var name = context.name.Text;
|
||||||
|
return new FunctionParameterModel(context.GetSpan(), type, name);
|
||||||
|
}
|
||||||
|
}
|
3
parser/IdentifierAttributeValueModel.cs
Normal file
3
parser/IdentifierAttributeValueModel.cs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public record IdentifierAttributeValueModel(Span Span, string Name) : AttributeValueModel(Span);
|
3
parser/IdentifierNameModel.cs
Normal file
3
parser/IdentifierNameModel.cs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public record IdentifierNameModel(Span Span, string? ImportName, string Name) : ModelBase(Span);
|
13
parser/IdentifierNameVisitorNya.cs
Normal file
13
parser/IdentifierNameVisitorNya.cs
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
using meowlang.parser.antlr;
|
||||||
|
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public class IdentifierNameVisitorNya : MeowBaseVisitorNya<IdentifierNameModel>
|
||||||
|
{
|
||||||
|
public override IdentifierNameModel VisitIdentifierName(MeowParser.IdentifierNameContext context)
|
||||||
|
{
|
||||||
|
var import = context.importName?.Text;
|
||||||
|
var name = context.name.Text;
|
||||||
|
return new IdentifierNameModel(context.GetSpan(), import, name);
|
||||||
|
}
|
||||||
|
}
|
5
parser/IfExpressionModel.cs
Normal file
5
parser/IfExpressionModel.cs
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public record IfExpressionModel(Span Span, ExpressionModel Condition, BlockExpressionModel Block,
|
||||||
|
List<(ExpressionModel Condition, BlockExpressionModel Block)> IfElses,
|
||||||
|
BlockExpressionModel? Else) : ExpressionModel(Span);
|
3
parser/ImportModel.cs
Normal file
3
parser/ImportModel.cs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public record ImportModel(Span Span, string? Project, string Path, string? Alias) : ModelBase(Span);
|
50
parser/ImportVisitorNya.cs
Normal file
50
parser/ImportVisitorNya.cs
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using meowlang.parser.antlr;
|
||||||
|
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public class ImportVisitorNya : MeowBaseVisitorNya<ImportModel>
|
||||||
|
{
|
||||||
|
private static readonly string PathSegmentPattern = "[a-z][a-z0-9_]*";
|
||||||
|
|
||||||
|
private static readonly Regex ProjectRegex = new Regex("^[a-z][a-z0-9_]*$");
|
||||||
|
|
||||||
|
private static readonly Regex PathRegexNoProject =
|
||||||
|
new Regex($"^({PathSegmentPattern}|\\.|\\.\\.)(/{PathSegmentPattern})*$");
|
||||||
|
|
||||||
|
private static readonly Regex PathRegex = new Regex($"^{PathSegmentPattern}(/{PathSegmentPattern})*$");
|
||||||
|
|
||||||
|
public override ImportModel VisitImportStatement(MeowParser.ImportStatementContext context)
|
||||||
|
{
|
||||||
|
var path = context.importpath.Text[1..^1].Unescape();
|
||||||
|
|
||||||
|
string? project = null;
|
||||||
|
|
||||||
|
if (path.Contains(':'))
|
||||||
|
{
|
||||||
|
var parts = path.Split(':');
|
||||||
|
project = parts[0];
|
||||||
|
if (!ProjectRegex.IsMatch(project))
|
||||||
|
{
|
||||||
|
throw new InvalidImportPathException(context.importpath, "malformed project name");
|
||||||
|
}
|
||||||
|
|
||||||
|
path = parts[1];
|
||||||
|
if (!PathRegex.IsMatch(path))
|
||||||
|
{
|
||||||
|
throw new InvalidImportPathException(context.importpath, "malformed path");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!PathRegexNoProject.IsMatch(path))
|
||||||
|
{
|
||||||
|
throw new InvalidImportPathException(context.importpath, "malformed path");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var alias = context.importname?.Text;
|
||||||
|
|
||||||
|
return new ImportModel(context.GetSpan(), project, path, alias);
|
||||||
|
}
|
||||||
|
}
|
3
parser/InfiniteLoopStatementModel.cs
Normal file
3
parser/InfiniteLoopStatementModel.cs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public record InfiniteLoopStatementModel(Span Span, List<StatementModel> Body) : LoopStatementModel(Span, Body);
|
8
parser/InvalidEscapeSequenceException.cs
Normal file
8
parser/InvalidEscapeSequenceException.cs
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public class InvalidEscapeSequenceException : Exception
|
||||||
|
{
|
||||||
|
public InvalidEscapeSequenceException(string escapeSequence) : base($"invalid escape sequence `{escapeSequence}`")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
10
parser/InvalidImportPathException.cs
Normal file
10
parser/InvalidImportPathException.cs
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
using Antlr4.Runtime;
|
||||||
|
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public class InvalidImportPathException : MeowVisitorException
|
||||||
|
{
|
||||||
|
public InvalidImportPathException(IToken context, string message) : base(context, message)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
10
parser/InvalidStructAccessorException.cs
Normal file
10
parser/InvalidStructAccessorException.cs
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
using Antlr4.Runtime;
|
||||||
|
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public class InvalidStructAccessorException : MeowVisitorException
|
||||||
|
{
|
||||||
|
public InvalidStructAccessorException(IToken token, string message) : base(token, message)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
3
parser/LiteralAttributeValueModel.cs
Normal file
3
parser/LiteralAttributeValueModel.cs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public record LiteralAttributeValueModel(Span Span, LiteralModel Literal) : AttributeValueModel(Span);
|
3
parser/LiteralExpressionModel.cs
Normal file
3
parser/LiteralExpressionModel.cs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public record LiteralExpressionModel(Span Span, LiteralModel Literal) : ExpressionModel(Span);
|
3
parser/LiteralModel.cs
Normal file
3
parser/LiteralModel.cs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public abstract record LiteralModel(Span Span) : ModelBase(Span);
|
30
parser/LiteralVisitorNya.cs
Normal file
30
parser/LiteralVisitorNya.cs
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
using meowlang.parser.antlr;
|
||||||
|
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public class LiteralVisitorNya : MeowBaseVisitorNya<LiteralModel>
|
||||||
|
{
|
||||||
|
public override LiteralModel VisitStringLiteral(MeowParser.StringLiteralContext context)
|
||||||
|
{
|
||||||
|
var value = context.val.Text[1..^1].Unescape();
|
||||||
|
return new StringLiteralModel(context.GetSpan(), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override LiteralModel VisitBoolLiteral(MeowParser.BoolLiteralContext context)
|
||||||
|
{
|
||||||
|
var text = context.val.Text;
|
||||||
|
var value = text == "true";
|
||||||
|
return new BoolLiteralModel(context.GetSpan(), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override LiteralModel VisitNumericLiteral(MeowParser.NumericLiteralContext context)
|
||||||
|
{
|
||||||
|
return new NumericLiteralModel(context.GetSpan(), context.val.Text);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override LiteralModel VisitCharacterLiteral(MeowParser.CharacterLiteralContext context)
|
||||||
|
{
|
||||||
|
var value = context.val.Text[1..^1].Unescape();
|
||||||
|
return new CharacterLiteralModel(context.GetSpan(), value);
|
||||||
|
}
|
||||||
|
}
|
3
parser/LoopStatementModel.cs
Normal file
3
parser/LoopStatementModel.cs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public abstract record LoopStatementModel(Span Span, List<StatementModel> Body) : StatementModel(Span);
|
292
parser/Meow.g4
292
parser/Meow.g4
|
@ -1,41 +1,50 @@
|
||||||
grammar Meow;
|
grammar Meow;
|
||||||
|
|
||||||
file
|
file
|
||||||
: importStatement* declaration* EOF
|
: importStatement* topLevelDeclaration* EOF
|
||||||
;
|
;
|
||||||
|
|
||||||
importStatement
|
importStatement
|
||||||
: ImportKeyword importpath=StringLiteral (AsKeyword importname=Identifier)? ';'
|
: ImportKeyword importpath=StringLiteral (AsKeyword importname=Identifier)? ';'
|
||||||
;
|
;
|
||||||
|
|
||||||
declaration
|
|
||||||
: function ';'?
|
topLevelDeclaration
|
||||||
| constraintDeclaration ';'?
|
: unterminatedTopLevelDeclaration ';'?
|
||||||
| structDeclaration ';'?
|
;
|
||||||
| enumDeclaration ';'?
|
|
||||||
| tupleDeclaration ';'?
|
unterminatedTopLevelDeclaration
|
||||||
| typeAlias ';'?
|
: function
|
||||||
;
|
| constraintDeclaration
|
||||||
|
| structDeclaration
|
||||||
|
| enumDeclaration
|
||||||
|
| tupleDeclaration
|
||||||
|
| typeAlias
|
||||||
|
| topLevelStatement
|
||||||
|
;
|
||||||
|
|
||||||
|
topLevelStatement
|
||||||
|
: constantDeclarationStatement
|
||||||
|
;
|
||||||
|
|
||||||
structDeclaration
|
structDeclaration
|
||||||
: StructKeyword name=Identifier (genericParameters constraint*)? structType
|
: attribute* pub=PubKeyword? StructKeyword name=Identifier (genericParameters constraint*)? structType
|
||||||
;
|
;
|
||||||
|
|
||||||
enumDeclaration
|
enumDeclaration
|
||||||
: EnumKeyword name=Identifier (genericParameters constraint*)? enumType
|
: attribute* pub=PubKeyword? EnumKeyword name=Identifier (genericParameters constraint*)? enumType
|
||||||
;
|
;
|
||||||
|
|
||||||
tupleDeclaration
|
tupleDeclaration
|
||||||
: TupleKeyword name=Identifier (genericParameters constraint*)? tupleType
|
: attribute* pub=PubKeyword? TupleKeyword name=Identifier (genericParameters constraint*)? tupleType
|
||||||
;
|
;
|
||||||
|
|
||||||
typeAlias
|
typeAlias
|
||||||
: TypeKeyword name=Identifier genericParameters? '=' typeReference
|
: attribute* pub=PubKeyword? TypeKeyword name=Identifier genericParameters? '=' typeReference
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
constraintDeclaration
|
constraintDeclaration
|
||||||
: ConstraintKeyword name=Identifier types+=Identifier+ '{' constraintRule* '}'
|
: attribute* pub=PubKeyword? ConstraintKeyword name=Identifier types+=Identifier+ '{' constraintRule* '}'
|
||||||
;
|
;
|
||||||
|
|
||||||
constraintRule
|
constraintRule
|
||||||
|
@ -56,8 +65,8 @@ constraintFunctionParameters
|
||||||
;
|
;
|
||||||
|
|
||||||
function
|
function
|
||||||
: attribute* pub=PubKeyword? FnKeyword name=Identifier functionParameters functionReturn? functionBody
|
: attribute* pub=PubKeyword? FnKeyword name=Identifier functionParameters functionReturn? body=blockExpression
|
||||||
| attribute* pub=PubKeyword? FnKeyword name=Identifier genericParameters functionParameters functionReturn? constraint* functionBody
|
| attribute* pub=PubKeyword? FnKeyword name=Identifier genericParameters functionParameters functionReturn? constraint* body=blockExpression
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
|
@ -91,22 +100,17 @@ functionParameters
|
||||||
;
|
;
|
||||||
|
|
||||||
functionParameter
|
functionParameter
|
||||||
: typeReference name=Identifier
|
: name=Identifier ':' typeReference
|
||||||
;
|
;
|
||||||
|
|
||||||
functionReturn
|
functionReturn
|
||||||
: '->' (typeReference (',' typeReference)*)
|
: ':' (typeReference (',' typeReference)*)
|
||||||
;
|
;
|
||||||
|
|
||||||
constraint
|
constraint
|
||||||
: WhereKeyword name=Identifier typenames+=Identifier+
|
: WhereKeyword name=Identifier typenames+=Identifier+
|
||||||
;
|
;
|
||||||
|
|
||||||
functionBody
|
|
||||||
: '{' statement* expression? '}'
|
|
||||||
;
|
|
||||||
|
|
||||||
|
|
||||||
typeReference
|
typeReference
|
||||||
: nonPointerTypeReference pointer='*'?
|
: nonPointerTypeReference pointer='*'?
|
||||||
;
|
;
|
||||||
|
@ -119,8 +123,13 @@ nonPointerTypeReference
|
||||||
| EnumKeyword enumType
|
| EnumKeyword enumType
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
typeName
|
typeName
|
||||||
: (importName=Identifier ':')? name+=Identifier ('<' genericType+=typeName (',' genericType+=typeName)* '>')? ('@' name+=Identifier)*
|
: identifierName ('<' genericType+=typeName (',' genericType+=typeName)* '>')? ('@' name+=Identifier)*
|
||||||
|
;
|
||||||
|
|
||||||
|
identifierName
|
||||||
|
: (importName=Identifier ':')? name=Identifier
|
||||||
;
|
;
|
||||||
|
|
||||||
arrayType
|
arrayType
|
||||||
|
@ -132,11 +141,11 @@ tupleType
|
||||||
;
|
;
|
||||||
|
|
||||||
structType
|
structType
|
||||||
: '{' structMember* '}'
|
: '{' structMember+ '}'
|
||||||
;
|
;
|
||||||
|
|
||||||
structMember
|
structMember
|
||||||
: typeReference name=Identifier ';'
|
: name=Identifier ':' typeReference ';'
|
||||||
;
|
;
|
||||||
|
|
||||||
enumType
|
enumType
|
||||||
|
@ -148,97 +157,214 @@ enumMember
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
|
terminatedStatement
|
||||||
|
: statement ';'
|
||||||
|
| blockStatement
|
||||||
|
;
|
||||||
|
|
||||||
statement
|
statement
|
||||||
: breakStatement
|
: breakStatement
|
||||||
| continueStatement
|
| continueStatement
|
||||||
| returnStatement
|
| returnStatement
|
||||||
| loopStatement
|
|
||||||
| expressionStatement
|
| expressionStatement
|
||||||
|
| variableDeclarationStatement
|
||||||
|
| constantDeclarationStatement
|
||||||
|
;
|
||||||
|
|
||||||
|
blockStatement
|
||||||
|
: ifExpression
|
||||||
|
| switchExpression
|
||||||
|
| blockExpression
|
||||||
|
| loopStatement
|
||||||
;
|
;
|
||||||
|
|
||||||
breakStatement
|
breakStatement
|
||||||
: BreakKeyword label=Identifier? ';'
|
: BreakKeyword label=Identifier?
|
||||||
;
|
;
|
||||||
|
|
||||||
|
variableDeclarationStatement
|
||||||
|
: 'let' name+=Identifier (',' name+= Identifier)* '=' expression
|
||||||
|
;
|
||||||
|
constantDeclarationStatement
|
||||||
|
: 'const' Identifier (',' name+= Identifier)* '=' expression
|
||||||
|
;
|
||||||
|
|
||||||
continueStatement
|
continueStatement
|
||||||
: ContinueKeyword label=Identifier? ';'
|
: ContinueKeyword label=Identifier?
|
||||||
;
|
;
|
||||||
returnStatement
|
returnStatement
|
||||||
: ReturnKeyword expression? ';'
|
: ReturnKeyword expression?
|
||||||
;
|
;
|
||||||
loopStatement
|
loopStatement
|
||||||
: LoopKeyword '{' statement* '}'
|
: (label=Identifier ':')? LoopKeyword '{' terminatedStatement* '}'
|
||||||
| LoopKeyword condition=expression '{' statement* '}'
|
| (label=Identifier ':')? LoopKeyword condition=expression '{' terminatedStatement* '}'
|
||||||
| LoopKeyword init=expression? ';' condition=expression? ';' increment=expression? '{' statement* '}'
|
| (label=Identifier ':')? LoopKeyword (initExpression=expression|initDeclaration=variableDeclarationStatement)? forIndicator=';' condition=expression? ';' increment=expression? '{' terminatedStatement* '}'
|
||||||
;
|
;
|
||||||
|
|
||||||
expressionStatement
|
expressionStatement
|
||||||
: expression ';'
|
: expression
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
todo: use C operator precedence: https://en.cppreference.com/w/c/language/operator_precedence
|
|
||||||
|
|
||||||
binary operators:
|
|
||||||
== != > >= < <=
|
|
||||||
||
|
|
||||||
&&
|
|
||||||
+ -
|
|
||||||
* / %
|
|
||||||
&
|
|
||||||
|
|
|
||||||
^
|
|
||||||
<<
|
|
||||||
>>
|
|
||||||
|
|
||||||
unary operators:
|
|
||||||
+
|
|
||||||
-
|
|
||||||
~
|
|
||||||
!
|
|
||||||
|
|
||||||
|
|
||||||
assignment:
|
|
||||||
=
|
|
||||||
+=
|
|
||||||
-=
|
|
||||||
/=
|
|
||||||
*=
|
|
||||||
%=
|
|
||||||
&=
|
|
||||||
|=
|
|
||||||
^=
|
|
||||||
<<=
|
|
||||||
>>=
|
|
||||||
|
|
||||||
|
|
||||||
*/
|
|
||||||
expression
|
expression
|
||||||
: addExpression
|
: assignmentExpression
|
||||||
|
;
|
||||||
|
|
||||||
|
assignmentExpression
|
||||||
|
: pattern op=AssignmentOperator logicalOrExpression
|
||||||
|
| logicalOrExpression
|
||||||
;
|
;
|
||||||
|
|
||||||
|
pattern
|
||||||
|
: pointerDereferenceExpression (',' pointerDereferenceExpression)*
|
||||||
|
;
|
||||||
|
|
||||||
|
logicalOrExpression
|
||||||
|
: logicalXorExpression ('||' logicalXorExpression)*
|
||||||
|
;
|
||||||
|
|
||||||
|
logicalXorExpression
|
||||||
|
: logicalAndExpression ('^^' logicalAndExpression)*
|
||||||
|
;
|
||||||
|
|
||||||
|
logicalAndExpression
|
||||||
|
: bitwiseOrExpression ('&&' bitwiseOrExpression)*
|
||||||
|
;
|
||||||
|
|
||||||
|
bitwiseOrExpression
|
||||||
|
: bitwiseXorExpression ('|' bitwiseXorExpression)*
|
||||||
|
;
|
||||||
|
|
||||||
|
bitwiseXorExpression
|
||||||
|
: bitwiseAndExpression ('^' bitwiseAndExpression)*
|
||||||
|
;
|
||||||
|
|
||||||
|
bitwiseAndExpression
|
||||||
|
: equalityExpression ('&' equalityExpression)*
|
||||||
|
;
|
||||||
|
|
||||||
|
equalityExpression
|
||||||
|
: relationalExpression ((op+='=='|op+='!=') relationalExpression)*
|
||||||
|
;
|
||||||
|
|
||||||
|
relationalExpression
|
||||||
|
: shiftExpression ((op+='<'|op+='>'|op+='<='|op+='>=') shiftExpression)*
|
||||||
|
;
|
||||||
|
|
||||||
|
shiftExpression
|
||||||
|
: addExpression ((op+='<<'|op+='>' '>') addExpression)*
|
||||||
|
;
|
||||||
|
|
||||||
addExpression
|
addExpression
|
||||||
: multExpression ((op='+'|op='-') multExpression)*
|
: multExpression ((op+='+'|op+='-') multExpression)*
|
||||||
;
|
;
|
||||||
|
|
||||||
multExpression
|
multExpression
|
||||||
: terminalExpression ((op='*'|op='/'|op='%') terminalExpression)*
|
: unaryExpression ((op+='*'|op+='/'|op+='%') unaryExpression)*
|
||||||
|
;
|
||||||
|
|
||||||
|
unaryExpression
|
||||||
|
: (op+='!'|op+='~'|op+='-'|op+='&')* pointerDereferenceExpression
|
||||||
;
|
;
|
||||||
|
|
||||||
|
pointerDereferenceExpression
|
||||||
|
: op+='*'* accessExpression
|
||||||
|
;
|
||||||
|
|
||||||
|
accessExpression
|
||||||
|
: terminalExpression accessExpression1?
|
||||||
|
;
|
||||||
|
|
||||||
|
accessExpression1
|
||||||
|
: '[' subscript=expression end=']' accessExpression1?
|
||||||
|
| '.' (name=Identifier|name=NumericLiteral) accessExpression1?
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
terminalExpression
|
terminalExpression
|
||||||
: literal
|
: literalExpression
|
||||||
|
| nameExpression
|
||||||
| structConstructor
|
| structConstructor
|
||||||
| arrayConstructor
|
| arrayConstructor
|
||||||
| enumConstructor
|
| enumConstructor
|
||||||
|
| tupleConstructor
|
||||||
| functionCall
|
| functionCall
|
||||||
| ifExpression
|
| ifExpression
|
||||||
| switchExpression
|
| switchExpression
|
||||||
| blockExpression
|
| blockExpression
|
||||||
| parenthesisExpression
|
| parenthesisExpression
|
||||||
;
|
;
|
||||||
|
|
||||||
|
literalExpression
|
||||||
|
: literal
|
||||||
|
;
|
||||||
|
|
||||||
|
nameExpression
|
||||||
|
: identifierName
|
||||||
|
;
|
||||||
|
|
||||||
|
structConstructor
|
||||||
|
: typeName? '{' structConstructorMember (',' structConstructorMember)* ','? '}'
|
||||||
|
;
|
||||||
|
|
||||||
|
structConstructorMember
|
||||||
|
: name=Identifier ':' expression
|
||||||
|
;
|
||||||
|
|
||||||
|
arrayConstructor
|
||||||
|
: (arrayType | typeName? '[' ']') '{' (expression (',' expression)* ','?)? '}'
|
||||||
|
;
|
||||||
|
|
||||||
|
enumConstructor
|
||||||
|
: typeName? '\'' name=Identifier
|
||||||
|
;
|
||||||
|
|
||||||
|
tupleConstructor
|
||||||
|
: '(' ')'
|
||||||
|
| '(' expression ',' ')'
|
||||||
|
| '(' expression (',' expression)+ ','? ')'
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
functionCall
|
||||||
|
: identifierName '(' (expression (',' expression)*)? ')'
|
||||||
|
;
|
||||||
|
|
||||||
|
ifExpression
|
||||||
|
: IfKeyword cond=expression then=blockExpression elseIfExpression* (ElseKeyword else=blockExpression)?
|
||||||
|
;
|
||||||
|
|
||||||
|
elseIfExpression
|
||||||
|
: ElseKeyword IfKeyword cond=expression then=blockExpression
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
switchExpression
|
||||||
|
: SwitchKeyword expression '{' (switchDefault ','?)? '}'
|
||||||
|
| SwitchKeyword expression '{' switchCase (',' switchCase)* (',' switchDefault ','?)? '}'
|
||||||
|
;
|
||||||
|
|
||||||
|
switchCase
|
||||||
|
: CaseKeyword literal ':' (expression|FallthroughKeyword)
|
||||||
|
;
|
||||||
|
|
||||||
|
switchDefault
|
||||||
|
: DefaultKeyword ':' expression
|
||||||
|
;
|
||||||
|
|
||||||
|
blockExpression
|
||||||
|
: '{' terminatedStatement* expression? '}'
|
||||||
|
;
|
||||||
|
|
||||||
|
parenthesisExpression
|
||||||
|
: '(' expression ')'
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////
|
///////////////////////////
|
||||||
|
|
||||||
|
MeowKeyword: 'm' 'e'+ 'o'* 'w' -> channel(HIDDEN); // ignores all me+o*ws in the code
|
||||||
|
NyaKeyword: '-ny' 'a'+ -> channel(HIDDEN); // ignores all -nya+s in the code
|
||||||
|
|
||||||
ImportKeyword: 'import';
|
ImportKeyword: 'import';
|
||||||
AsKeyword: 'as';
|
AsKeyword: 'as';
|
||||||
PubKeyword: 'pub';
|
PubKeyword: 'pub';
|
||||||
|
@ -253,6 +379,16 @@ BreakKeyword: 'break';
|
||||||
ContinueKeyword: 'continue';
|
ContinueKeyword: 'continue';
|
||||||
ReturnKeyword: 'return';
|
ReturnKeyword: 'return';
|
||||||
LoopKeyword: 'loop';
|
LoopKeyword: 'loop';
|
||||||
|
IfKeyword: 'if';
|
||||||
|
ElseKeyword: 'else';
|
||||||
|
SwitchKeyword: 'switch';
|
||||||
|
CaseKeyword: 'case';
|
||||||
|
FallthroughKeyword: 'fallthrough';
|
||||||
|
DefaultKeyword: 'default';
|
||||||
|
|
||||||
|
|
||||||
|
AssignmentOperator: '='|'+='|'-='|'*='|'/='|'%='|'&='|'|='|'^='|'<<='|'>>=';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
13
parser/MeowVisitorException.cs
Normal file
13
parser/MeowVisitorException.cs
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
using Antlr4.Runtime;
|
||||||
|
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public class MeowVisitorException : Exception
|
||||||
|
{
|
||||||
|
public IToken Token { get; }
|
||||||
|
|
||||||
|
public MeowVisitorException(IToken token, string message) : base(message)
|
||||||
|
{
|
||||||
|
Token = token;
|
||||||
|
}
|
||||||
|
}
|
3
parser/Model.cs
Normal file
3
parser/Model.cs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public record Model(Span Span, List<ImportModel> Imports, List<TopLevelConstructModel> Declarations) : ModelBase(Span);
|
|
@ -1,3 +1,3 @@
|
||||||
namespace meowlang.parser;
|
namespace meowlang.parser;
|
||||||
|
|
||||||
public record ModelBase([property:Ignore] Span span);
|
public record ModelBase([property:Ignore] Span Span);
|
3
parser/NameExpressionModel.cs
Normal file
3
parser/NameExpressionModel.cs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public record NameExpressionModel(Span Span, IdentifierNameModel Name): ExpressionModel(Span);
|
3
parser/NumericLiteralModel.cs
Normal file
3
parser/NumericLiteralModel.cs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public record NumericLiteralModel(Span Span, string StringValue) : LiteralModel(Span);
|
3
parser/ParenthesisExpressionModel.cs
Normal file
3
parser/ParenthesisExpressionModel.cs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public record ParenthesisExpressionModel(Span Span, ExpressionModel Expression) : ExpressionModel(Span);
|
|
@ -8,8 +8,9 @@ public class Parser
|
||||||
public static Model? Parse(string path)
|
public static Model? Parse(string path)
|
||||||
{
|
{
|
||||||
var lexer = new MeowLexer(new AntlrFileStream(path));
|
var lexer = new MeowLexer(new AntlrFileStream(path));
|
||||||
var parser = new MeowParser(new CommonTokenStream(lexer));
|
var tokenStream = new CommonTokenStream(lexer);
|
||||||
var visitor = new Visitor();
|
var parser = new MeowParser(tokenStream);
|
||||||
|
var visitor = new VisitorNya();
|
||||||
var file = parser.file();
|
var file = parser.file();
|
||||||
if (parser.NumberOfSyntaxErrors > 0)
|
if (parser.NumberOfSyntaxErrors > 0)
|
||||||
{
|
{
|
||||||
|
|
3
parser/PatternModel.cs
Normal file
3
parser/PatternModel.cs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public record PatternModel(Span Span, List<ExpressionModel> Expressions) : ModelBase(Span);
|
3
parser/PointerDereferenceExpressionModel.cs
Normal file
3
parser/PointerDereferenceExpressionModel.cs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public record PointerDereferenceExpressionModel(Span Span, ExpressionModel Expression) : ExpressionModel(Span);
|
3
parser/PointerReferenceExpressionModel.cs
Normal file
3
parser/PointerReferenceExpressionModel.cs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public record PointerReferenceExpressionModel(Span Span, ExpressionModel Expression) : ExpressionModel(Span);
|
3
parser/PointerTypeReferenceModel.cs
Normal file
3
parser/PointerTypeReferenceModel.cs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public record PointerTypeReferenceModel(Span Span, TypeReferenceModel Type) : TypeReferenceModel(Span);
|
3
parser/ReturnStatementModel.cs
Normal file
3
parser/ReturnStatementModel.cs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public record ReturnStatementModel(Span Span, ExpressionModel? Expression) : StatementModel(Span);
|
3
parser/SliceTypeModel.cs
Normal file
3
parser/SliceTypeModel.cs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public record SliceTypeModel(Span Span, TypeReferenceModel Type) : TypeReferenceModel(Span);
|
3
parser/StatementModel.cs
Normal file
3
parser/StatementModel.cs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public abstract record StatementModel(Span Span) : ModelBase(Span);
|
83
parser/StatementVisitorNya.cs
Normal file
83
parser/StatementVisitorNya.cs
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
using Antlr4.Runtime;
|
||||||
|
using meowlang.parser.antlr;
|
||||||
|
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public class StatementVisitorNya : MeowBaseVisitorNya<StatementModel>
|
||||||
|
{
|
||||||
|
public override StatementModel VisitTerminatedStatement(MeowParser.TerminatedStatementContext context)
|
||||||
|
{
|
||||||
|
return Visit(context.statement() ?? context.blockStatement() as ParserRuleContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override StatementModel VisitBlockStatement(MeowParser.BlockStatementContext context)
|
||||||
|
{
|
||||||
|
if (context.loopStatement() != null)
|
||||||
|
{
|
||||||
|
return Visit(context.loopStatement());
|
||||||
|
}
|
||||||
|
|
||||||
|
var expression = new ExpressionVisitorNya().Visit(context);
|
||||||
|
return new ExpressionStatementModel(context.GetSpan(), expression);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override StatementModel VisitLoopStatement(MeowParser.LoopStatementContext context)
|
||||||
|
{
|
||||||
|
var body = context.terminatedStatement().Select(Visit).ToList();
|
||||||
|
if (context.condition == null)
|
||||||
|
{
|
||||||
|
return new InfiniteLoopStatementModel(context.GetSpan(), body);
|
||||||
|
}
|
||||||
|
|
||||||
|
var condition = new ExpressionVisitorNya().Visit(context.condition);
|
||||||
|
if (context.forIndicator == null)
|
||||||
|
{
|
||||||
|
return new WhileLoopStatementModel(context.GetSpan(), body, condition);
|
||||||
|
}
|
||||||
|
|
||||||
|
var increment = new ExpressionVisitorNya().TryVisit(context.increment);
|
||||||
|
var initStatement = TryVisit(context.initDeclaration) as VariableDeclarationStatementModel;
|
||||||
|
var initExpression = new ExpressionVisitorNya().TryVisit(context.initExpression);
|
||||||
|
return new ForLoopStatementModel(context.GetSpan(), body, initStatement, initExpression, condition, increment);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override StatementModel VisitBreakStatement(MeowParser.BreakStatementContext context)
|
||||||
|
{
|
||||||
|
var label = context.label?.Text;
|
||||||
|
return new BreakStatementModel(context.GetSpan(), label);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override StatementModel VisitContinueStatement(MeowParser.ContinueStatementContext context)
|
||||||
|
{
|
||||||
|
var label = context.label?.Text;
|
||||||
|
return new ContinueStatementModel(context.GetSpan(), label);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override StatementModel VisitReturnStatement(MeowParser.ReturnStatementContext context)
|
||||||
|
{
|
||||||
|
var expression = new ExpressionVisitorNya().TryVisit(context.expression());
|
||||||
|
return new ReturnStatementModel(context.GetSpan(), expression);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override StatementModel VisitExpressionStatement(MeowParser.ExpressionStatementContext context)
|
||||||
|
{
|
||||||
|
var expression = new ExpressionVisitorNya().Visit(context.expression());
|
||||||
|
return new ExpressionStatementModel(context.GetSpan(), expression);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override StatementModel VisitVariableDeclarationStatement(
|
||||||
|
MeowParser.VariableDeclarationStatementContext context)
|
||||||
|
{
|
||||||
|
var names = context._name.Select(x => x.Text).ToList();
|
||||||
|
var initializer = new ExpressionVisitorNya().Visit(context.expression());
|
||||||
|
return new VariableDeclarationStatementModel(context.GetSpan(), names, initializer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override StatementModel VisitConstantDeclarationStatement(
|
||||||
|
MeowParser.ConstantDeclarationStatementContext context)
|
||||||
|
{
|
||||||
|
var names = context._name.Select(x => x.Text).ToList();
|
||||||
|
var initializer = new ExpressionVisitorNya().Visit(context.expression());
|
||||||
|
return new ConstantDeclarationStatementModel(context.GetSpan(), names, initializer);
|
||||||
|
}
|
||||||
|
}
|
3
parser/StringLiteralModel.cs
Normal file
3
parser/StringLiteralModel.cs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public record StringLiteralModel(Span Span, string Value) : LiteralModel(Span);
|
3
parser/StructAccessExpressionModel.cs
Normal file
3
parser/StructAccessExpressionModel.cs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public record StructAccessExpressionModel(Span Span, ExpressionModel Expression, string Name) : ExpressionModel(Span);
|
4
parser/StructConstructorExpressionModel.cs
Normal file
4
parser/StructConstructorExpressionModel.cs
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public record StructConstructorExpressionModel(Span Span, TypeNameModel? Type,
|
||||||
|
List<StructConstructorMemberModel> Members) : ExpressionModel(Span);
|
3
parser/StructConstructorMemberModel.cs
Normal file
3
parser/StructConstructorMemberModel.cs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public record StructConstructorMemberModel(Span Span, string Name, ExpressionModel Value) : ModelBase(Span);
|
3
parser/StructMemberModel.cs
Normal file
3
parser/StructMemberModel.cs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public record StructMemberModel(Span Span, TypeReferenceModel Type, string Name) : ModelBase(Span);
|
13
parser/StructMemberVisitorNya.cs
Normal file
13
parser/StructMemberVisitorNya.cs
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
using meowlang.parser.antlr;
|
||||||
|
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public class StructMemberVisitorNya : MeowBaseVisitorNya<StructMemberModel>
|
||||||
|
{
|
||||||
|
public override StructMemberModel VisitStructMember(MeowParser.StructMemberContext context)
|
||||||
|
{
|
||||||
|
var type = new TypeReferenceVisitorNya().Visit(context.typeReference());
|
||||||
|
var name = context.name.Text;
|
||||||
|
return new StructMemberModel(context.GetSpan(), type, name);
|
||||||
|
}
|
||||||
|
}
|
4
parser/StructTopLevelConstructModel.cs
Normal file
4
parser/StructTopLevelConstructModel.cs
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public record StructTopLevelConstructModel(Span Span, List<AttributeModel> Attributes, bool Pub, string Name, List<string> TypeParameters,
|
||||||
|
List<ConstraintModel> Constraints, StructTypeModel Struct) : TopLevelConstructModel(Span);
|
3
parser/StructTypeModel.cs
Normal file
3
parser/StructTypeModel.cs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public record StructTypeModel(Span Span, List<StructMemberModel> Members) : TypeReferenceModel(Span);
|
4
parser/SwitchExpressionModel.cs
Normal file
4
parser/SwitchExpressionModel.cs
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public record SwitchExpressionModel(Span Span, ExpressionModel Expression,
|
||||||
|
List<(LiteralModel Value, ExpressionModel? Body)> Cases, ExpressionModel? Default) : ExpressionModel(Span);
|
3
parser/TopLevelConstructModel.cs
Normal file
3
parser/TopLevelConstructModel.cs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public abstract record TopLevelConstructModel(Span Span) : ModelBase(Span);
|
3
parser/TopLevelStatementModel.cs
Normal file
3
parser/TopLevelStatementModel.cs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public record TopLevelStatementModel(Span Span, StatementModel Statement): TopLevelConstructModel(Span);
|
3
parser/TupleConstructorExpressionModel.cs
Normal file
3
parser/TupleConstructorExpressionModel.cs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public record TupleConstructorExpressionModel(Span Span, List<ExpressionModel> Values) : ExpressionModel(Span);
|
4
parser/TupleTopLevelConstructModel.cs
Normal file
4
parser/TupleTopLevelConstructModel.cs
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public record TupleTopLevelConstructModel(Span Span, List<AttributeModel> Attributes, bool Pub, string Name, List<string> TypeParameters,
|
||||||
|
List<ConstraintModel> Constraints, TupleTypeModel Tuple) : TopLevelConstructModel(Span);
|
3
parser/TupleTypeModel.cs
Normal file
3
parser/TupleTypeModel.cs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public record TupleTypeModel(Span Span, List<TypeReferenceModel> Types) : TypeReferenceModel(Span);
|
5
parser/TypeAliasModel.cs
Normal file
5
parser/TypeAliasModel.cs
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public record TypeAliasModel
|
||||||
|
(Span Span, List<AttributeModel> Attributes, bool Pub, string Name, List<string> TypeParameters, TypeReferenceModel Type) : TopLevelConstructModel(Span);
|
||||||
|
|
4
parser/TypeNameModel.cs
Normal file
4
parser/TypeNameModel.cs
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public record TypeNameModel(Span Span, IdentifierNameModel Name, List<TypeReferenceModel> TypeParameters,
|
||||||
|
List<string> Nested) : TypeReferenceModel(Span);
|
3
parser/TypeParameterModel.cs
Normal file
3
parser/TypeParameterModel.cs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public record TypeParameterModel(Span Span, string Name) : ModelBase(Span);
|
3
parser/TypeReferenceModel.cs
Normal file
3
parser/TypeReferenceModel.cs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public abstract record TypeReferenceModel(Span Span) : ModelBase(Span);
|
54
parser/TypeReferenceVisitorNya.cs
Normal file
54
parser/TypeReferenceVisitorNya.cs
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
using meowlang.parser.antlr;
|
||||||
|
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public class TypeReferenceVisitorNya : MeowBaseVisitorNya<TypeReferenceModel>
|
||||||
|
{
|
||||||
|
public override TypeReferenceModel VisitTypeReference(MeowParser.TypeReferenceContext context)
|
||||||
|
{
|
||||||
|
var type = Visit(context.nonPointerTypeReference());
|
||||||
|
if (context.pointer != null)
|
||||||
|
{
|
||||||
|
return new PointerTypeReferenceModel(context.GetSpan(), type);
|
||||||
|
}
|
||||||
|
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override TypeReferenceModel VisitTypeName(MeowParser.TypeNameContext context)
|
||||||
|
{
|
||||||
|
var name = new IdentifierNameVisitorNya().Visit(context.identifierName());
|
||||||
|
var typeParameters = context._genericType.Select(Visit).ToList();
|
||||||
|
var nestedName = context._name.Select(x => x.Text).ToList();
|
||||||
|
return new TypeNameModel(context.GetSpan(), name, typeParameters, nestedName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override TypeReferenceModel VisitArrayType(MeowParser.ArrayTypeContext context)
|
||||||
|
{
|
||||||
|
var type = Visit(context.typeReference());
|
||||||
|
if (context.length == null)
|
||||||
|
{
|
||||||
|
return new SliceTypeModel(context.GetSpan(), type);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ArrayTypeModel(context.GetSpan(), type, context.length.Text);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override TypeReferenceModel VisitTupleType(MeowParser.TupleTypeContext context)
|
||||||
|
{
|
||||||
|
var types = context.typeReference().Select(Visit).ToList();
|
||||||
|
return new TupleTypeModel(context.GetSpan(), types);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override TypeReferenceModel VisitStructType(MeowParser.StructTypeContext context)
|
||||||
|
{
|
||||||
|
var members = context.structMember().Select(x => new StructMemberVisitorNya().Visit(x)).ToList();
|
||||||
|
return new StructTypeModel(context.GetSpan(), members);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override TypeReferenceModel VisitEnumType(MeowParser.EnumTypeContext context)
|
||||||
|
{
|
||||||
|
var members = context.enumMember().Select(x => new EnumMemberVisitorNya().Visit(x)).ToList();
|
||||||
|
return new EnumTypeModel(context.GetSpan(), members);
|
||||||
|
}
|
||||||
|
}
|
4
parser/UnaryOperationExpressionModel.cs
Normal file
4
parser/UnaryOperationExpressionModel.cs
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public record UnaryOperationExpressionModel
|
||||||
|
(Span Span, UnaryOperator Operator, ExpressionModel Expression) : ExpressionModel(Span);
|
8
parser/UnaryOperator.cs
Normal file
8
parser/UnaryOperator.cs
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public enum UnaryOperator
|
||||||
|
{
|
||||||
|
LogicalNot,
|
||||||
|
BitwiseNot,
|
||||||
|
Negative,
|
||||||
|
}
|
18
parser/UnaryOperatorExtensions.cs
Normal file
18
parser/UnaryOperatorExtensions.cs
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public static class UnaryOperatorExtensions
|
||||||
|
{
|
||||||
|
public static UnaryOperator ToUnaryOperator(this string str) => str switch
|
||||||
|
{
|
||||||
|
"!" => UnaryOperator.LogicalNot,
|
||||||
|
"~" => UnaryOperator.BitwiseNot,
|
||||||
|
"-" => UnaryOperator.Negative,
|
||||||
|
};
|
||||||
|
|
||||||
|
public static string ToString(this UnaryOperator op) => op switch
|
||||||
|
{
|
||||||
|
UnaryOperator.LogicalNot => "!",
|
||||||
|
UnaryOperator.BitwiseNot => "~",
|
||||||
|
UnaryOperator.Negative => "-",
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Antlr4.Runtime;
|
using Antlr4.Runtime;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
@ -41,6 +42,12 @@ public static class ObjectExtensions
|
||||||
|
|
||||||
string json;
|
string json;
|
||||||
|
|
||||||
|
if (o is ITuple t)
|
||||||
|
{
|
||||||
|
var values = Enumerable.Range(0, t.Length).Select(i => t[i]).ToList();
|
||||||
|
return values.AutoToString();
|
||||||
|
}
|
||||||
|
|
||||||
if (type.IsAssignableTo(typeof(IEnumerable)))
|
if (type.IsAssignableTo(typeof(IEnumerable)))
|
||||||
{
|
{
|
||||||
var enumerable = (o as IEnumerable)!.Cast<object>();
|
var enumerable = (o as IEnumerable)!.Cast<object>();
|
||||||
|
|
4
parser/VariableDeclarationStatementModel.cs
Normal file
4
parser/VariableDeclarationStatementModel.cs
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public record VariableDeclarationStatementModel
|
||||||
|
(Span Span, List<string> Names, ExpressionModel Initializer) : StatementModel(Span);
|
|
@ -1,412 +0,0 @@
|
||||||
using System.Reflection.Metadata;
|
|
||||||
using System.Text;
|
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using Antlr4.Runtime;
|
|
||||||
using meowlang.parser.antlr;
|
|
||||||
|
|
||||||
namespace meowlang.parser;
|
|
||||||
|
|
||||||
public class InvalidEscapeSequenceException : Exception
|
|
||||||
{
|
|
||||||
public InvalidEscapeSequenceException(string escapeSequence) : base($"invalid escape sequence `{escapeSequence}`")
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class MeowVisitorException : Exception
|
|
||||||
{
|
|
||||||
public IToken Token { get; }
|
|
||||||
|
|
||||||
public MeowVisitorException(IToken token, string message) : base(message)
|
|
||||||
{
|
|
||||||
Token = token;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class InvalidImportPathException : MeowVisitorException
|
|
||||||
{
|
|
||||||
public InvalidImportPathException(IToken context, string message) : base(context, message)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class Visitor : MeowBaseVisitor<Model>
|
|
||||||
{
|
|
||||||
public override Model VisitFile(MeowParser.FileContext context)
|
|
||||||
{
|
|
||||||
var imports = context.importStatement().Select(x => new ImportVisitor().Visit(x)).ToList();
|
|
||||||
var declarations = context.declaration().Select(x => new DeclarationVisitor().Visit(x)).ToList();
|
|
||||||
|
|
||||||
return new Model(context.GetSpan(), imports, declarations);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ImportVisitor : MeowBaseVisitor<ImportModel>
|
|
||||||
{
|
|
||||||
private static readonly string PathSegmentPattern = "[a-z][a-z0-9_]*";
|
|
||||||
|
|
||||||
private static readonly Regex ProjectRegex = new Regex("^[a-z][a-z0-9_]*$");
|
|
||||||
|
|
||||||
private static readonly Regex PathRegexNoProject =
|
|
||||||
new Regex($"^({PathSegmentPattern}|\\.|\\.\\.)(/{PathSegmentPattern})*$");
|
|
||||||
|
|
||||||
private static readonly Regex PathRegex = new Regex($"^{PathSegmentPattern}(/{PathSegmentPattern})*$");
|
|
||||||
|
|
||||||
public override ImportModel VisitImportStatement(MeowParser.ImportStatementContext context)
|
|
||||||
{
|
|
||||||
var path = context.importpath.Text[1..^1].Unescape();
|
|
||||||
|
|
||||||
string? project = null;
|
|
||||||
|
|
||||||
if (path.Contains(':'))
|
|
||||||
{
|
|
||||||
var parts = path.Split(':');
|
|
||||||
project = parts[0];
|
|
||||||
if (!ProjectRegex.IsMatch(project))
|
|
||||||
{
|
|
||||||
throw new InvalidImportPathException(context.importpath, "malformed project name");
|
|
||||||
}
|
|
||||||
|
|
||||||
path = parts[1];
|
|
||||||
if (!PathRegex.IsMatch(path))
|
|
||||||
{
|
|
||||||
throw new InvalidImportPathException(context.importpath, "malformed path");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!PathRegexNoProject.IsMatch(path))
|
|
||||||
{
|
|
||||||
throw new InvalidImportPathException(context.importpath, "malformed path");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var alias = context.importname?.Text;
|
|
||||||
|
|
||||||
return new ImportModel(context.GetSpan(), project, path, alias);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class DeclarationVisitor : MeowBaseVisitor<DeclarationModel>
|
|
||||||
{
|
|
||||||
public override DeclarationModel VisitFunction(MeowParser.FunctionContext context)
|
|
||||||
{
|
|
||||||
var attributes = context.attribute().Select(x => new AttributeVisitor().Visit(x)).ToList();
|
|
||||||
var pub = context.pub != null;
|
|
||||||
var name = context.name.Text;
|
|
||||||
|
|
||||||
var typeParameters =
|
|
||||||
context.genericParameters()?._name.Select(x => new TypeParameterModel(x.GetSpan(), x.Text)).ToList() ??
|
|
||||||
new List<TypeParameterModel>();
|
|
||||||
var functionParameters = context.functionParameters().functionParameter()
|
|
||||||
.Select(x => new FunctionParameterVisitor().Visit(x)).ToList();
|
|
||||||
var functionReturns = context.functionReturn()?.typeReference().Select(x => new TypeReferenceVisitor().Visit(x))
|
|
||||||
.ToList() ?? new List<TypeReferenceModel>();
|
|
||||||
var constraints = context.constraint()?.Select(x => new FunctionConstraintVisitor().Visit(x)).ToList() ??
|
|
||||||
new List<ConstraintModel>();
|
|
||||||
|
|
||||||
return new FunctionModel(context.GetSpan(), attributes, pub, name, typeParameters, functionParameters,
|
|
||||||
functionReturns, constraints,
|
|
||||||
new FunctionBodyModel(context.functionBody().GetSpan())); // TODO: visit function body
|
|
||||||
}
|
|
||||||
|
|
||||||
public override ConstraintDeclarationModel VisitConstraintDeclaration(
|
|
||||||
MeowParser.ConstraintDeclarationContext context)
|
|
||||||
{
|
|
||||||
var name = context.name.Text;
|
|
||||||
var typeNames = context._types.Select(x => x.Text).ToList();
|
|
||||||
var rules = context.constraintRule().Select(x => new ConstraintRuleVisitor().Visit(x)).ToList();
|
|
||||||
return new ConstraintDeclarationModel(context.GetSpan(), name, typeNames, rules);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override DeclarationModel VisitStructDeclaration(MeowParser.StructDeclarationContext context)
|
|
||||||
{
|
|
||||||
var name = context.name.Text;
|
|
||||||
var typeParameters = context.genericParameters()?._name.Select(x => x.Text).ToList() ?? new List<string>();
|
|
||||||
var constraints = context.constraint()?.Select(x => new FunctionConstraintVisitor().Visit(x)).ToList() ??
|
|
||||||
new List<ConstraintModel>();
|
|
||||||
var structModel = new TypeReferenceVisitor().Visit(context.structType()) as StructTypeModel;
|
|
||||||
return new StructDeclarationModel(context.GetSpan(), name, typeParameters, constraints, structModel!);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override DeclarationModel VisitEnumDeclaration(MeowParser.EnumDeclarationContext context)
|
|
||||||
{
|
|
||||||
var name = context.name.Text;
|
|
||||||
var typeParameters = context.genericParameters()?._name.Select(x => x.Text).ToList() ?? new List<string>();
|
|
||||||
var constraints = context.constraint()?.Select(x => new FunctionConstraintVisitor().Visit(x)).ToList() ??
|
|
||||||
new List<ConstraintModel>();
|
|
||||||
|
|
||||||
var enumModel = new TypeReferenceVisitor().Visit(context.enumType()) as EnumTypeModel;
|
|
||||||
return new EnumDeclarationModel(context.GetSpan(), name, typeParameters, constraints, enumModel!);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override DeclarationModel VisitTupleDeclaration(MeowParser.TupleDeclarationContext context)
|
|
||||||
{
|
|
||||||
var name = context.name.Text;
|
|
||||||
var typeParameters = context.genericParameters()?._name.Select(x => x.Text).ToList() ?? new List<string>();
|
|
||||||
var constraints = context.constraint()?.Select(x => new FunctionConstraintVisitor().Visit(x)).ToList() ??
|
|
||||||
new List<ConstraintModel>();
|
|
||||||
var tupleModel = new TypeReferenceVisitor().Visit(context.tupleType()) as TupleTypeModel;
|
|
||||||
return new TupleDeclarationModel(context.GetSpan(), name, typeParameters, constraints, tupleModel!);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override DeclarationModel VisitTypeAlias(MeowParser.TypeAliasContext context)
|
|
||||||
{
|
|
||||||
var name = context.name.Text;
|
|
||||||
var typeParameters = context.genericParameters()?._name.Select(x => x.Text).ToList() ?? new List<string>();
|
|
||||||
var type = new TypeReferenceVisitor().Visit(context.typeReference());
|
|
||||||
return new TypeAliasModel(context.GetSpan(), name, typeParameters, type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class AttributeVisitor : MeowBaseVisitor<AttributeModel>
|
|
||||||
{
|
|
||||||
public override AttributeModel VisitAttribute(MeowParser.AttributeContext context)
|
|
||||||
{
|
|
||||||
var name = context.name.Text;
|
|
||||||
var values = context.attributeValue().Select(x => new AttributeValueVisitor().Visit(x)).ToList();
|
|
||||||
return new AttributeModel(context.GetSpan(), name, values);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class AttributeValueVisitor : MeowBaseVisitor<AttributeValueModel>
|
|
||||||
{
|
|
||||||
public override AttributeValueModel VisitAttributeValue(MeowParser.AttributeValueContext context)
|
|
||||||
{
|
|
||||||
if (context.id != null)
|
|
||||||
{
|
|
||||||
return new IdentifierAttributeValueModel(context.GetSpan(), context.id.Text);
|
|
||||||
}
|
|
||||||
|
|
||||||
var literal = new LiteralVisitor().Visit(context.literal());
|
|
||||||
return new LiteralAttributeValueModel(context.GetSpan(), literal);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class FunctionParameterVisitor : MeowBaseVisitor<FunctionParameterModel>
|
|
||||||
{
|
|
||||||
public override FunctionParameterModel VisitFunctionParameter(MeowParser.FunctionParameterContext context)
|
|
||||||
{
|
|
||||||
var type = new TypeReferenceVisitor().Visit(context.typeReference());
|
|
||||||
var name = context.name.Text;
|
|
||||||
return new FunctionParameterModel(context.GetSpan(), type, name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class TypeReferenceVisitor : MeowBaseVisitor<TypeReferenceModel>
|
|
||||||
{
|
|
||||||
public override TypeReferenceModel VisitTypeReference(MeowParser.TypeReferenceContext context)
|
|
||||||
{
|
|
||||||
var type = Visit(context.nonPointerTypeReference());
|
|
||||||
if (context.pointer != null)
|
|
||||||
{
|
|
||||||
return new PointerTypeReferenceModel(context.GetSpan(), type);
|
|
||||||
}
|
|
||||||
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override TypeReferenceModel VisitTypeName(MeowParser.TypeNameContext context)
|
|
||||||
{
|
|
||||||
var import = context.importName?.Text;
|
|
||||||
var nestedName = context._name.Select(x => x.Text).ToList();
|
|
||||||
|
|
||||||
var typeParameters = context._genericType.Select(Visit).ToList();
|
|
||||||
|
|
||||||
return new TypeNameModel(context.GetSpan(), import, nestedName[0], typeParameters, nestedName.Skip(1).ToList());
|
|
||||||
}
|
|
||||||
|
|
||||||
public override TypeReferenceModel VisitArrayType(MeowParser.ArrayTypeContext context)
|
|
||||||
{
|
|
||||||
var type = Visit(context.typeReference());
|
|
||||||
if (context.length == null)
|
|
||||||
{
|
|
||||||
return new SliceTypeModel(context.GetSpan(), type);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new ArrayTypeModel(context.GetSpan(), type, context.length.Text);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override TypeReferenceModel VisitTupleType(MeowParser.TupleTypeContext context)
|
|
||||||
{
|
|
||||||
var types = context.typeReference().Select(Visit).ToList();
|
|
||||||
return new TupleTypeModel(context.GetSpan(), types);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override TypeReferenceModel VisitStructType(MeowParser.StructTypeContext context)
|
|
||||||
{
|
|
||||||
var members = context.structMember().Select(x => new StructMemberVisitor().Visit(x)).ToList();
|
|
||||||
return new StructTypeModel(context.GetSpan(), members);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override TypeReferenceModel VisitEnumType(MeowParser.EnumTypeContext context)
|
|
||||||
{
|
|
||||||
var members = context.enumMember().Select(x => new EnumMemberVisitor().Visit(x)).ToList();
|
|
||||||
return new EnumTypeModel(context.GetSpan(), members);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class StructMemberVisitor : MeowBaseVisitor<StructMemberModel>
|
|
||||||
{
|
|
||||||
public override StructMemberModel VisitStructMember(MeowParser.StructMemberContext context)
|
|
||||||
{
|
|
||||||
var type = new TypeReferenceVisitor().Visit(context.typeReference());
|
|
||||||
var name = context.name.Text;
|
|
||||||
return new StructMemberModel(context.GetSpan(), type, name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class EnumMemberVisitor : MeowBaseVisitor<EnumMemberModel>
|
|
||||||
{
|
|
||||||
public override EnumMemberModel VisitEnumMember(MeowParser.EnumMemberContext context)
|
|
||||||
{
|
|
||||||
var name = context.name.Text;
|
|
||||||
|
|
||||||
TypeReferenceModel? type = null;
|
|
||||||
var typeRef = context.typeReference();
|
|
||||||
if (typeRef != null)
|
|
||||||
{
|
|
||||||
type = new TypeReferenceVisitor().Visit(typeRef);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new EnumMemberModel(context.GetSpan(), name, type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class FunctionConstraintVisitor : MeowBaseVisitor<ConstraintModel>
|
|
||||||
{
|
|
||||||
public override ConstraintModel VisitConstraint(MeowParser.ConstraintContext context)
|
|
||||||
{
|
|
||||||
var name = context.name.Text;
|
|
||||||
var typeNames = context._typenames.Select(x => x.Text).ToList();
|
|
||||||
return new ConstraintModel(context.GetSpan(), name, typeNames);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class LiteralVisitor : MeowBaseVisitor<LiteralModel>
|
|
||||||
{
|
|
||||||
public override LiteralModel VisitStringLiteral(MeowParser.StringLiteralContext context)
|
|
||||||
{
|
|
||||||
var value = context.val.Text[1..^1].Unescape();
|
|
||||||
return new StringLiteralModel(context.GetSpan(), value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override LiteralModel VisitBoolLiteral(MeowParser.BoolLiteralContext context)
|
|
||||||
{
|
|
||||||
var text = context.val.Text;
|
|
||||||
var value = text == "true";
|
|
||||||
return new BoolLiteralModel(context.GetSpan(), value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override LiteralModel VisitNumericLiteral(MeowParser.NumericLiteralContext context)
|
|
||||||
{
|
|
||||||
return new NumericLiteralModel(context.GetSpan(), context.val.Text);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override LiteralModel VisitCharacterLiteral(MeowParser.CharacterLiteralContext context)
|
|
||||||
{
|
|
||||||
var value = context.val.Text[1..^1].Unescape();
|
|
||||||
return new CharacterLiteralModel(context.GetSpan(), value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ConstraintRuleVisitor : MeowBaseVisitor<ConstraintRuleModel>
|
|
||||||
{
|
|
||||||
public override ConstraintRuleModel VisitEmbedConstraintRule(MeowParser.EmbedConstraintRuleContext context)
|
|
||||||
{
|
|
||||||
var name = context.name.Text;
|
|
||||||
var types = context._types.Select(x => new TypeReferenceVisitor().Visit(x)).ToList();
|
|
||||||
return new EmbedConstraintRuleModel(context.GetSpan(), name, types);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override ConstraintRuleModel VisitFunctionConstraintRule(MeowParser.FunctionConstraintRuleContext context)
|
|
||||||
{
|
|
||||||
var name = context.name.Text;
|
|
||||||
var parameters = context.constraintFunctionParameters().typeReference()
|
|
||||||
.Select(x => new TypeReferenceVisitor().Visit(x)).ToList();
|
|
||||||
var returns =
|
|
||||||
context.functionReturn()?.typeReference().Select(x => new TypeReferenceVisitor().Visit(x)).ToList() ??
|
|
||||||
new List<TypeReferenceModel>();
|
|
||||||
return new FunctionConstraintRuleModel(context.GetSpan(), name, parameters, returns);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public record Model(Span span, List<ImportModel> Imports, List<DeclarationModel> Declarations) : ModelBase(span);
|
|
||||||
|
|
||||||
public record ImportModel(Span span, string? Project, string Path, string? Alias) : ModelBase(span);
|
|
||||||
|
|
||||||
public abstract record DeclarationModel(Span span) : ModelBase(span);
|
|
||||||
|
|
||||||
public record FunctionModel(Span span, List<AttributeModel> Attributes, bool Pub, string Name,
|
|
||||||
List<TypeParameterModel> TypeParameters, List<FunctionParameterModel> Parameters, List<TypeReferenceModel> Returns,
|
|
||||||
List<ConstraintModel> Constraints, FunctionBodyModel Body) : DeclarationModel(span);
|
|
||||||
|
|
||||||
public record AttributeModel(Span span, string Name, List<AttributeValueModel> Values) : ModelBase(span);
|
|
||||||
|
|
||||||
public abstract record AttributeValueModel(Span span) : ModelBase(span);
|
|
||||||
|
|
||||||
public record IdentifierAttributeValueModel(Span span, string Name) : AttributeValueModel(span);
|
|
||||||
|
|
||||||
public record LiteralAttributeValueModel(Span span, LiteralModel Literal) : AttributeValueModel(span);
|
|
||||||
|
|
||||||
public record TypeParameterModel(Span span, string Name) : ModelBase(span);
|
|
||||||
|
|
||||||
public record FunctionParameterModel(Span span, TypeReferenceModel Type, string Name) : ModelBase(span);
|
|
||||||
|
|
||||||
public abstract record TypeReferenceModel(Span span) : ModelBase(span);
|
|
||||||
|
|
||||||
public record PointerTypeReferenceModel(Span span, TypeReferenceModel Type) : TypeReferenceModel(span);
|
|
||||||
|
|
||||||
public record TypeNameModel(Span span, string? ImportName, string Name, List<TypeReferenceModel> TypeParameters,
|
|
||||||
List<string> Nested) : TypeReferenceModel(span);
|
|
||||||
|
|
||||||
public record ArrayTypeModel(Span span, TypeReferenceModel Type, string Length) : TypeReferenceModel(span);
|
|
||||||
|
|
||||||
public record SliceTypeModel(Span span, TypeReferenceModel Type) : TypeReferenceModel(span);
|
|
||||||
|
|
||||||
public record TupleTypeModel(Span span, List<TypeReferenceModel> Types) : TypeReferenceModel(span);
|
|
||||||
|
|
||||||
public record StructTypeModel(Span span, List<StructMemberModel> Members) : TypeReferenceModel(span);
|
|
||||||
|
|
||||||
public record StructMemberModel(Span span, TypeReferenceModel Type, string Name) : ModelBase(span);
|
|
||||||
|
|
||||||
public record EnumTypeModel(Span span, List<EnumMemberModel> Members) : TypeReferenceModel(span);
|
|
||||||
|
|
||||||
public record EnumMemberModel(Span span, string Name, TypeReferenceModel? Type) : ModelBase(span);
|
|
||||||
|
|
||||||
public record ConstraintModel(Span span, string Name, List<string> TypeNames) : ModelBase(span);
|
|
||||||
|
|
||||||
public record FunctionBodyModel(Span span) : ModelBase(span);
|
|
||||||
|
|
||||||
public abstract record LiteralModel(Span span) : ModelBase(span);
|
|
||||||
|
|
||||||
public record StringLiteralModel(Span span, string Value) : LiteralModel(span);
|
|
||||||
|
|
||||||
public record CharacterLiteralModel(Span span, string Value) : LiteralModel(span);
|
|
||||||
|
|
||||||
public record NumericLiteralModel(Span span, string StringValue) : LiteralModel(span);
|
|
||||||
|
|
||||||
public record BoolLiteralModel(Span span, bool Value) : LiteralModel(span);
|
|
||||||
|
|
||||||
public record ConstraintDeclarationModel
|
|
||||||
(Span span, string Name, List<string> TypeNames, List<ConstraintRuleModel> Rules) : DeclarationModel(span);
|
|
||||||
|
|
||||||
public abstract record ConstraintRuleModel(Span span) : ModelBase(span);
|
|
||||||
|
|
||||||
public record EmbedConstraintRuleModel
|
|
||||||
(Span span, string Name, List<TypeReferenceModel> Types) : ConstraintRuleModel(span);
|
|
||||||
|
|
||||||
public record FunctionConstraintRuleModel(Span span, string Name, List<TypeReferenceModel> Parameters,
|
|
||||||
List<TypeReferenceModel> Returns) : ConstraintRuleModel(span);
|
|
||||||
|
|
||||||
public record StructDeclarationModel(Span span, string Name, List<string> TypeParameters,
|
|
||||||
List<ConstraintModel> Constraints, StructTypeModel Struct) : DeclarationModel(span);
|
|
||||||
|
|
||||||
public record EnumDeclarationModel(Span span, string Name, List<string> TypeParameters,
|
|
||||||
List<ConstraintModel> Constraints, EnumTypeModel Enum) : DeclarationModel(span);
|
|
||||||
|
|
||||||
public record TupleDeclarationModel(Span span, string Name, List<string> TypeParameters,
|
|
||||||
List<ConstraintModel> Constraints, TupleTypeModel Tuple) : DeclarationModel(span);
|
|
||||||
|
|
||||||
public record TypeAliasModel
|
|
||||||
(Span span, string Name, List<string> TypeParameters, TypeReferenceModel Type) : DeclarationModel(span);
|
|
17
parser/VisitorNya.cs
Normal file
17
parser/VisitorNya.cs
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
using System.Linq.Expressions;
|
||||||
|
using System.Reflection.Metadata;
|
||||||
|
using System.Text;
|
||||||
|
using meowlang.parser.antlr;
|
||||||
|
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public class VisitorNya : MeowBaseVisitorNya<Model>
|
||||||
|
{
|
||||||
|
public override Model VisitFile(MeowParser.FileContext context)
|
||||||
|
{
|
||||||
|
var imports = context.importStatement().Select(x => new ImportVisitorNya().Visit(x)).ToList();
|
||||||
|
var declarations = context.topLevelDeclaration().Select(x => new DeclarationVisitorNya().Visit(x)).ToList();
|
||||||
|
|
||||||
|
return new Model(context.GetSpan(), imports, declarations);
|
||||||
|
}
|
||||||
|
}
|
4
parser/WhileLoopStatementModel.cs
Normal file
4
parser/WhileLoopStatementModel.cs
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
namespace meowlang.parser;
|
||||||
|
|
||||||
|
public record WhileLoopStatementModel
|
||||||
|
(Span Span, List<StatementModel> Body, ExpressionModel Condition) : LoopStatementModel(Span, Body);
|
Loading…
Reference in a new issue