Skip to content

Commit

Permalink
Merge pull request #245 from vein-lang/feature/type-aliases
Browse files Browse the repository at this point in the history
Type Aliases
  • Loading branch information
0xF6 authored Jun 26, 2024
2 parents e878b04 + 28bfd3b commit cba7fe2
Show file tree
Hide file tree
Showing 20 changed files with 450 additions and 267 deletions.
15 changes: 15 additions & 0 deletions lib/ast/syntax/Aliases.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
namespace vein.syntax;

using Sprache;

public partial class VeinSyntax
{
internal virtual Parser<AliasSyntax> AliasDeclaration =>
from global in KeywordExpression("global").Token().Optional()
from keyword in KeywordExpression("alias").Token()
from aliasName in IdentifierExpression.Token()
from s in Parse.String("<|").Token()
from body in MethodParametersAndBody.Token().Select(x => new TypeOrMethod(null, x))
.Or(TypeExpression.Token().Then(_ => Parse.Char(';').Token().Return(_)).Select(x => new TypeOrMethod(x, null)))
select new AliasSyntax(global.IsDefined, aliasName, body);
}
18 changes: 9 additions & 9 deletions lib/ast/syntax/Classes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ from type in TypeReference.Token().Positioned()
/// [special] public foo: Type;
/// </example>
protected internal virtual Parser<PropertyDeclarationSyntax> PropertyDeclaration =>
from heading in MemberDeclarationHeading
from typeAndName in NameAndType
from heading in MemberDeclarationHeading.Positioned()
from typeAndName in NameAndType.Positioned()
from accessors in PropertyBody
select new PropertyDeclarationSyntax(heading)
{
Expand All @@ -41,8 +41,8 @@ from accessors in PropertyBody
Accessors = accessors.Accessors,
};
protected internal virtual Parser<PropertyDeclarationSyntax> PropertyDeclarationShortform =>
from heading in MemberDeclarationHeading
from typeAndName in NameAndType
from heading in MemberDeclarationHeading.Positioned()
from typeAndName in NameAndType.Positioned()
from op in Parse.String("|>").Token()
from exp in QualifiedExpression.Positioned()
from end in Parse.IgnoreCase(";").Token()
Expand Down Expand Up @@ -73,7 +73,7 @@ from expression in Parse.Char('=').Token().Then(_ => QualifiedExpression).Positi
};
/// examples: get; private set; get { return 0; }
protected internal virtual Parser<AccessorDeclarationSyntax> PropertyAccessor =>
from heading in MemberDeclarationHeading
from heading in MemberDeclarationHeading.Positioned()
from keyword in Parse.IgnoreCase("get").Or(Parse.IgnoreCase("set")).Token().Text()
from body in Parse.Char(';').Return(default(BlockSyntax)).Or(Block).Commented(this)
select new AccessorDeclarationSyntax(heading)
Expand All @@ -85,19 +85,19 @@ from keyword in Parse.IgnoreCase("get").Or(Parse.IgnoreCase("set")).Token().Text
/// example: { get; set; }
protected internal virtual Parser<PropertyDeclarationSyntax> PropertyBody =>
from openBrace in Parse.Char('{').Token()
from accessors in PropertyAccessor.Many()
from accessors in PropertyAccessor.Positioned().Many()
from closeBrace in Parse.Char('}').Token()
select new PropertyDeclarationSyntax(accessors);

/// method or property declaration starting with the type and name
protected internal virtual Parser<MemberDeclarationSyntax> MethodDeclaration =>
from dec in MemberDeclarationHeading
from name in IdentifierExpression
from dec in MemberDeclarationHeading.Positioned()
from name in IdentifierExpression.Positioned()
from member in MethodParametersAndBody.Select(c => c as MemberDeclarationSyntax)
select member.WithName(name).WithProperties(dec);

protected internal virtual Parser<MemberDeclarationSyntax> CtorDeclaration =>
from dec in MemberDeclarationHeading
from dec in MemberDeclarationHeading.Positioned()
from kw in KeywordExpression("new").Or(
KeywordExpression("delete"))
from member in CtorParametersAndBody.Select(c => c as MemberDeclarationSyntax)
Expand Down
47 changes: 23 additions & 24 deletions lib/ast/syntax/Directives.cs
Original file line number Diff line number Diff line change
@@ -1,27 +1,26 @@
namespace vein.syntax
{
using Sprache;
namespace vein.syntax;

using Sprache;

public partial class VeinSyntax
{
internal virtual Parser<DirectiveType> DirectiveDeclarator(DirectiveType type) =>
from start in Parse.Char('#')
from keyword in Parse.String(type.ToString().ToLowerInvariant())
select type;
public partial class VeinSyntax
{
internal virtual Parser<DirectiveType> DirectiveDeclarator(DirectiveType type) =>
from start in Parse.Char('#')
from keyword in Parse.String(type.ToString().ToLowerInvariant())
select type;

internal virtual Parser<DirectiveSyntax> UseSyntax =>
(from start in DirectiveDeclarator(DirectiveType.Use)
from str in StringLiteralExpression.Token()
select new UseSyntax
{
Value = str
}).Token().Named("use directive").Positioned();
internal virtual Parser<DirectiveSyntax> SpaceSyntax =>
(from start in DirectiveDeclarator(DirectiveType.Space)
from str in StringLiteralExpression.Token()
select new SpaceSyntax
{
Value = str
}).Token().Named("space directive").Positioned();
}
internal virtual Parser<DirectiveSyntax> UseSyntax =>
(from start in DirectiveDeclarator(DirectiveType.Use)
from str in StringLiteralExpression.Token()
select new UseSyntax
{
Value = str
}).Token().Named("use directive").Positioned();
internal virtual Parser<DirectiveSyntax> SpaceSyntax =>
(from start in DirectiveDeclarator(DirectiveType.Space)
from str in StringLiteralExpression.Token()
select new SpaceSyntax
{
Value = str
}).Token().Named("space directive").Positioned();
}
5 changes: 3 additions & 2 deletions lib/ast/syntax/DocumentDeclaration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,14 @@ public string Name
public IEnumerable<DirectiveSyntax> Directives { get; set; }
public IEnumerable<MemberDeclarationSyntax> Members { get; set; }
public IEnumerable<AspectDeclarationSyntax> Aspects { get; set; }
public IEnumerable<AliasSyntax> Aliases { get; set; }
public FileInfo FileEntity { get; set; }
public string SourceText { get; set; }
public string[] SourceLines => SourceText.Replace("\r", "").Split("\n");

private List<string> _includes;
private List<string>? _includes;

public int[] _line_offsets;
public int[]? _line_offsets;

public List<string> Includes => _includes ??= Directives.OfExactType<UseSyntax>().Select(x =>
{
Expand Down
46 changes: 34 additions & 12 deletions lib/ast/syntax/ErrorDiff.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
namespace vein.syntax
{
using System;
using System.Diagnostics;
using System.Linq;
using ishtar;
using Spectre.Console;
Expand Down Expand Up @@ -31,8 +32,9 @@ public static string DiffErrorFull(this Transform t, FileInfo doc)
return "";
return $"\n\t[grey] {diff.EscapeMarkup().EscapeArgumentSymbols()} [/]\n\t[red] {arrow_line.EscapeMarkup().EscapeArgumentSymbols()} [/]";
}
catch
catch(Exception e)
{
Trace.WriteLine(e.ToString());
return ""; // TODO analytic
}
}
Expand Down Expand Up @@ -71,21 +73,41 @@ public static (string line, string arrow_line) DiffError(this Transform t, strin
{
return NewDiffError(t, sourceLines);
}
catch { }
catch (Exception e)
{
Trace.WriteLine(e.ToString());
}

var line = sourceLines[t.pos.Line].Length < t.len ?
t.pos.Line - 1 :
/*t.pos.Line*/throw new Exception("cannot detect line");
(string line, string arrow_line) cast(int line)
{
var original = sourceLines[line];
var err_line = original[(t.pos.Column - 1)..];
var space1 = original[..(t.pos.Column - 1)];
var space2 = (t.pos.Column - 1) + t.len > original.Length ? "" : original[((t.pos.Column - 1) + t.len)..];

var original = sourceLines[line];
var err_line = original[(t.pos.Column - 1)..];
var space1 = original[..(t.pos.Column - 1)];
var space2 = (t.pos.Column - 1) + t.len > original.Length ? "" : original[((t.pos.Column - 1) + t.len)..];
return (original,
$"{new string(' ', space1.Length)}{new string('^', err_line.Length)}{new string(' ', space2.Length)}");
}

return (original,
$"{new string(' ', space1.Length)}{new string('^', err_line.Length)}{new string(' ', space2.Length)}");
}

try
{
return cast(t.pos.Line - 1);
}
catch (Exception e)
{
Trace.WriteLine(e.ToString());
}
try
{
return cast(t.pos.Line);
}
catch (Exception e)
{
Trace.WriteLine(e.ToString());
}

throw new Exception($"Cant detect line");
}
}
}
64 changes: 61 additions & 3 deletions lib/ast/syntax/VeinSyntax.cs
Original file line number Diff line number Diff line change
Expand Up @@ -168,14 +168,13 @@ from identifier in QualifiedIdentifier
};
// native("args")
protected internal virtual Parser<AspectSyntax> AspectSyntax =>
(from kind in Aspect
(from kind in Aspect.Positioned()
from args in object_creation_expression.Optional()
select new AspectSyntax(kind, args))
.Positioned()
.Token()
.Named("aspect");


protected internal virtual Parser<AspectSyntax[]> AspectsExpression =>
(from open in Parse.Char('[')
from kinds in Parse.Ref(() => AspectSyntax).Positioned().DelimitedBy(Parse.Char(',').Token())
Expand All @@ -194,7 +193,66 @@ from trailingComments in CommentParser.AnyComment.Token().Many().End()
select new DocumentDeclaration
{
Directives = directives,
Members = members.Select(x => x.WithTrailingComments(trailingComments))
Members = members.Select(x => x.WithTrailingComments(trailingComments)),
//Aliases = aliases.GetOrEmpty()
};

public virtual Parser<DocumentDeclaration> CompilationUnitV2 =>
from entities in (from members in
AnyCommentUnit
.Or(DirectivesUnit)
.Or(AliasesUnit)
.Or(AspectUnit)
.Or(ClassUnit) select members).Many()
select recast(entities.SelectMany(x => x).ToList());

private static DocumentDeclaration recast(List<CompilationUnitEntity> entities) => new()
{
Aspects = entities.Where(x => x.kind == UnitKind.Aspect).Select(x => x.syntax)
.OfType<AspectDeclarationSyntax>(),
Aliases = entities.Where(x => x.kind == UnitKind.Aliases).Select(x => x.syntax).OfType<AliasSyntax>(),
Directives = entities.Where(x => x.kind == UnitKind.Directive).Select(x => x.syntax)
.OfType<DirectiveSyntax>(),
Members = entities.Where(x => x.kind == UnitKind.Class).Select(x => x.syntax)
.OfType<MemberDeclarationSyntax>(),
};

public virtual Parser<List<CompilationUnitEntity>> AnyCommentUnit =>
from trailingComments in CommentParser.AnyComment.Token().Many()
select trailingComments.Select(x => new CompilationUnitEntity(null, UnitKind.Comments)).ToList();

public virtual Parser<List<CompilationUnitEntity>> DirectivesUnit =>
from directives in SpaceSyntax.Token().Or(UseSyntax.Token()).Many()
select directives.Select(x => new CompilationUnitEntity(x, UnitKind.Directive))
.ToList();

public virtual Parser<List<CompilationUnitEntity>> AliasesUnit =>
from aliases in AliasDeclaration.Token().Many()
select aliases.Select(x => new CompilationUnitEntity(x, UnitKind.Aliases))
.ToList();

public virtual Parser<List<CompilationUnitEntity>> AspectUnit =>
from aliases in AspectDeclaration.Token().Many()
select aliases.Select(x => new CompilationUnitEntity(x, UnitKind.Aspect))
.ToList();

public virtual Parser<List<CompilationUnitEntity>> ClassUnit =>
from aliases in ClassDeclaration.Token().Many()
select aliases.Select(x => new CompilationUnitEntity(x, UnitKind.Class))
.ToList();
}
}

public enum UnitKind
{
Comments,
Directive,
Aliases,
Aspect,
Class
}

public record CompilationUnitEntity(BaseSyntax syntax, UnitKind kind)
{

}
11 changes: 9 additions & 2 deletions lib/ast/syntax/ast/AccessorDeclarationSyntax.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
namespace vein.syntax;

using System.Collections.Generic;
using Sprache;

public class AccessorDeclarationSyntax : MemberDeclarationSyntax
public class AccessorDeclarationSyntax : MemberDeclarationSyntax, IPositionAware<AccessorDeclarationSyntax>
{
public AccessorDeclarationSyntax(MemberDeclarationSyntax heading = null)
public AccessorDeclarationSyntax(MemberDeclarationSyntax? heading = null)
: base(heading)
{
}
Expand All @@ -20,4 +21,10 @@ public AccessorDeclarationSyntax(MemberDeclarationSyntax heading = null)
public BlockSyntax Body { get; set; }

public bool IsEmpty => Body == null;

public new AccessorDeclarationSyntax SetPos(Position startPos, int length)
{
base.SetPos(startPos, length);
return this;
}
}
27 changes: 27 additions & 0 deletions lib/ast/syntax/ast/AliasSyntax.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
namespace vein.syntax;

using Sprache;


public record TypeOrMethod(TypeExpression type, MethodDeclarationSyntax method);

public class AliasSyntax(bool isGlobal, IdentifierExpression aliasName, TypeOrMethod body) : BaseSyntax, IPositionAware<AliasSyntax>
{
public bool IsGlobal { get; } = isGlobal;
public IdentifierExpression AliasName { get; } = aliasName;
public TypeExpression? Type { get; } = body.type;
public MethodDeclarationSyntax? MethodDeclaration { get; } = body.method;

public bool IsMethod => MethodDeclaration != null;
public bool IsType => Type != null;

public override SyntaxType Kind => SyntaxType.Alias;
public override IEnumerable<BaseSyntax> ChildNodes
=> GetNodes([AliasName, Type, MethodDeclaration]);

public AliasSyntax SetPos(Position startPos, int length)
{
base.SetPos(startPos, length);
return this;
}
}
1 change: 0 additions & 1 deletion lib/ast/syntax/ast/AspectSyntax.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ public AspectSyntax(IdentifierExpression kind, IOption<ExpressionSyntax> args)
public bool IsNative => Name.ExpressionString.Equals("native", StringComparison.InvariantCultureIgnoreCase);
public bool IsSpecial => Name.ExpressionString.Equals("special", StringComparison.InvariantCultureIgnoreCase);
public bool IsForwarded => Name.ExpressionString.Equals("forwarded", StringComparison.InvariantCultureIgnoreCase);
public bool IsAlias => Name.ExpressionString.Equals("alias", StringComparison.InvariantCultureIgnoreCase);
public bool IsAspectUsage => Name.ExpressionString.Equals("aspectUsage", StringComparison.InvariantCultureIgnoreCase);

public new AspectSyntax SetPos(Position startPos, int length)
Expand Down
Loading

0 comments on commit cba7fe2

Please sign in to comment.