From 18d35a5f1e8d774cf90d99c6261b582e07e0b596 Mon Sep 17 00:00:00 2001 From: Gwendolyn Date: Sun, 13 Feb 2022 03:02:23 +0100 Subject: [PATCH] make exceptions cooler and fix example code --- compiler/example.mew | 57 +++--- parser/ExpressionVisitorNya.cs | 12 +- parser/MeowModelVisitor.cs | 258 +++++++++++++++------------- parser/MeowModelVisitorException.cs | 11 ++ parser/MeowVisitorException.cs | 2 +- parser/Span.cs | 2 +- parser/Utils.cs | 4 +- visitorgenerator/Program.cs | 22 ++- 8 files changed, 196 insertions(+), 172 deletions(-) create mode 100644 parser/MeowModelVisitorException.cs diff --git a/compiler/example.mew b/compiler/example.mew index 877de5c..8ff9d2c 100644 --- a/compiler/example.mew +++ b/compiler/example.mew @@ -2,18 +2,18 @@ import "std:strings"; import "foo" as bar; import "./foobar"; -/* + fn foo() {} -pub fn bar(int x) -> int {} +pub fn bar(x: int): int {} -pub fn multiret() -> int, int {} +pub fn multiret(): int, int {} -[c_export] pub fn add(int a, int b) -> int {} +[c_export] pub fn add(a: int, b: int): int {} -[c_export("add_floats")] pub fn add(float a, float b) -> float {} +[c_export("add_floats")] pub fn add(a: float,b: float): float {} -fn sub(T a, T b) -> T +fn sub(a: T, b: T): T where SUBTRACT T { // do something @@ -21,19 +21,19 @@ fn sub(T a, T b) -> T -fn ret_arr() -> [int; 10] {} -fn ret_slice() -> [int] {} -fn ret_multislice() -> [[int]] {} -fn ret_ptr() -> int* {} -fn ret_ptrslice() -> [int*] {} -fn ret_arrayptr() -> [int; 5]* {} -fn ret_tuple() -> (int, int) {} +fn ret_arr(): [int; 10] {} +fn ret_slice(): [int] {} +fn ret_multislice(): [[int]] {} +fn ret_ptr(): int* {} +fn ret_ptrslice(): [int*] {} +fn ret_arrayptr(): [int; 5]* {} +fn ret_tuple(): (int, int) {} -fn ret_imported() -> strings:StringBuilder {} +fn ret_imported(): strings:StringBuilder {} -fn ret_nested() -> foo@bar {} +fn ret_nested(): foo@bar {} -fn ret_imported_nested() -> foo:bar@some@nested@shit {} +fn ret_imported_nested(): foo:bar@some@nested@shit {} constraint Foo A { @@ -47,10 +47,7 @@ constraint Bar B { constraint Foo SomeType; } -*/ - -/* struct Foo { something: int; bar: struct { @@ -65,13 +62,13 @@ enum X { C } -enum X { +enum X1 { A(T1), B(T2), C(T3), } -enum X where Constraint T1 T2 where Constraint T2 T3 { +enum X2 where Constraint T1 T2 where Constraint T2 T3 { A(T1), B(T2), C(T3), @@ -91,14 +88,12 @@ type F = Foo>; -type X = [Y; 10]; +type Xa = [Y; 10]; -*/ -/* -tuple X (A,A,A); +tuple Xa (A,A,A); -type X = [T; 10]; +type Xaa = [T; 10]; type X = (T1, T2); fn foo() { @@ -132,7 +127,7 @@ struct Bar { } -struct Foo { +struct Fooo { x: enum {Foo, Bar}; } @@ -175,15 +170,13 @@ fn test() { -type A = int*; +type Aaaaa = int*; struct B { x: (int, int); -}*/ +} -type A = [(T,int); 10]; - -struct A { +struct Aaaaa { x: B; y: s32; } diff --git a/parser/ExpressionVisitorNya.cs b/parser/ExpressionVisitorNya.cs index 3a1ea0e..5302d77 100644 --- a/parser/ExpressionVisitorNya.cs +++ b/parser/ExpressionVisitorNya.cs @@ -25,7 +25,7 @@ public class ExpressionVisitorNya : MeowBaseVisitorNya 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); + var span = new Span(left.Span.Filename, left.Span.From, right.Span.To, left.Span.Line); return new BinaryOperationExpressionModel(span, left, op, right); } @@ -37,7 +37,7 @@ public class ExpressionVisitorNya : MeowBaseVisitorNya 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); + var span = new Span(left.Span.Filename, left.Span.From, right.Span.To, left.Span.Line); return new BinaryOperationExpressionModel(span, left, op, right); } @@ -117,7 +117,7 @@ public class ExpressionVisitorNya : MeowBaseVisitorNya var expression = Visit(context.pointerDereferenceExpression()); foreach (var unaryOperator in context._op.Reverse()) { - var span = new Span(expression.Span.Filename, unaryOperator.StartIndex, expression.Span.To); + var span = new Span(expression.Span.Filename, unaryOperator.StartIndex, expression.Span.To, expression.Span.Line); if (unaryOperator.Text == "&") { expression = new PointerReferenceExpressionModel(span, expression); @@ -137,7 +137,7 @@ public class ExpressionVisitorNya : MeowBaseVisitorNya var expression = Visit(context.accessExpression()); foreach (var op in context._op.Reverse()) { - var span = new Span(expression.Span.Filename, op.StartIndex, expression.Span.To); + var span = new Span(expression.Span.Filename, op.StartIndex, expression.Span.To, expression.Span.Line); expression = new PointerDereferenceExpressionModel(span, expression); } @@ -152,13 +152,13 @@ public class ExpressionVisitorNya : MeowBaseVisitorNya { if (current.subscript != null) // array access { - var span = new Span(expression.Span.Filename, expression.Span.From, current.end.StopIndex); + var span = new Span(expression.Span.Filename, expression.Span.From, current.end.StopIndex, expression.Span.Line); 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 span = new Span(expression.Span.Filename, expression.Span.From, current.name.StopIndex, expression.Span.Line); var name = current.name.Text; if (name.Contains('.') || (char.IsDigit(name[0]) && !char.IsDigit(name.TrimStart('0')[0]))) { diff --git a/parser/MeowModelVisitor.cs b/parser/MeowModelVisitor.cs index 5d775b7..827c59c 100644 --- a/parser/MeowModelVisitor.cs +++ b/parser/MeowModelVisitor.cs @@ -20,69 +20,75 @@ public class MeowModelVisitor public T Visit(ModelBase m) { - switch(m) - { + try { + switch(m) + { - case ArrayAccessExpressionModel x: return VisitArrayAccessExpression(x); - case ArrayConstructorExpressionModel x: return VisitArrayConstructorExpression(x); - case ArrayTypeModel x: return VisitArrayType(x); - case AssignmentExpressionModel x: return VisitAssignmentExpression(x); - case AttributeModel x: return VisitAttribute(x); - case BinaryOperationExpressionModel x: return VisitBinaryOperationExpression(x); - case BlockExpressionModel x: return VisitBlockExpression(x); - case BoolLiteralModel x: return VisitBoolLiteral(x); - case BreakStatementModel x: return VisitBreakStatement(x); - case CharacterLiteralModel x: return VisitCharacterLiteral(x); - case ConstantDeclarationStatementModel x: return VisitConstantDeclarationStatement(x); - case ConstraintDeclarationModel x: return VisitConstraintDeclaration(x); - case ConstraintModel x: return VisitConstraint(x); - case ContinueStatementModel x: return VisitContinueStatement(x); - case EmbedConstraintRuleModel x: return VisitEmbedConstraintRule(x); - case EnumConstructorExpressionModel x: return VisitEnumConstructorExpression(x); - case EnumDeclarationModel x: return VisitEnumDeclaration(x); - case EnumMemberModel x: return VisitEnumMember(x); - case EnumTypeModel x: return VisitEnumType(x); - case ExpressionStatementModel x: return VisitExpressionStatement(x); - case ForLoopStatementModel x: return VisitForLoopStatement(x); - case FunctionCallExpressionModel x: return VisitFunctionCallExpression(x); - case FunctionConstraintRuleModel x: return VisitFunctionConstraintRule(x); - case FunctionModel x: return VisitFunction(x); - case FunctionParameterModel x: return VisitFunctionParameter(x); - case IdentifierAttributeValueModel x: return VisitIdentifierAttributeValue(x); - case IdentifierNameModel x: return VisitIdentifierName(x); - case IfExpressionModel x: return VisitIfExpression(x); - case ImportModel x: return VisitImport(x); - case InfiniteLoopStatementModel x: return VisitInfiniteLoopStatement(x); - case LiteralAttributeValueModel x: return VisitLiteralAttributeValue(x); - case LiteralExpressionModel x: return VisitLiteralExpression(x); - case Model x: return Visit(x); - case NameExpressionModel x: return VisitNameExpression(x); - case NumericLiteralModel x: return VisitNumericLiteral(x); - case ParenthesisExpressionModel x: return VisitParenthesisExpression(x); - case PatternModel x: return VisitPattern(x); - case PointerDereferenceExpressionModel x: return VisitPointerDereferenceExpression(x); - case PointerReferenceExpressionModel x: return VisitPointerReferenceExpression(x); - case PointerTypeReferenceModel x: return VisitPointerTypeReference(x); - case ReturnStatementModel x: return VisitReturnStatement(x); - case SliceTypeModel x: return VisitSliceType(x); - case StringLiteralModel x: return VisitStringLiteral(x); - case StructAccessExpressionModel x: return VisitStructAccessExpression(x); - case StructConstructorExpressionModel x: return VisitStructConstructorExpression(x); - case StructConstructorMemberModel x: return VisitStructConstructorMember(x); - case StructDeclarationModel x: return VisitStructDeclaration(x); - case StructMemberModel x: return VisitStructMember(x); - case StructTypeModel x: return VisitStructType(x); - case SwitchExpressionModel x: return VisitSwitchExpression(x); - case TopLevelStatementModel x: return VisitTopLevelStatement(x); - case TupleConstructorExpressionModel x: return VisitTupleConstructorExpression(x); - case TupleDeclarationModel x: return VisitTupleDeclaration(x); - case TupleTypeModel x: return VisitTupleType(x); - case TypeAliasModel x: return VisitTypeAlias(x); - case TypeNameModel x: return VisitTypeName(x); - case TypeParameterModel x: return VisitTypeParameter(x); - case UnaryOperationExpressionModel x: return VisitUnaryOperationExpression(x); - case VariableDeclarationStatementModel x: return VisitVariableDeclarationStatement(x); - case WhileLoopStatementModel x: return VisitWhileLoopStatement(x); + case ArrayAccessExpressionModel x: return VisitArrayAccessExpression(x); + case ArrayConstructorExpressionModel x: return VisitArrayConstructorExpression(x); + case ArrayTypeModel x: return VisitArrayType(x); + case AssignmentExpressionModel x: return VisitAssignmentExpression(x); + case AttributeModel x: return VisitAttribute(x); + case BinaryOperationExpressionModel x: return VisitBinaryOperationExpression(x); + case BlockExpressionModel x: return VisitBlockExpression(x); + case BoolLiteralModel x: return VisitBoolLiteral(x); + case BreakStatementModel x: return VisitBreakStatement(x); + case CharacterLiteralModel x: return VisitCharacterLiteral(x); + case ConstantDeclarationStatementModel x: return VisitConstantDeclarationStatement(x); + case ConstraintDeclarationModel x: return VisitConstraintDeclaration(x); + case ConstraintModel x: return VisitConstraint(x); + case ContinueStatementModel x: return VisitContinueStatement(x); + case EmbedConstraintRuleModel x: return VisitEmbedConstraintRule(x); + case EnumConstructorExpressionModel x: return VisitEnumConstructorExpression(x); + case EnumDeclarationModel x: return VisitEnumDeclaration(x); + case EnumMemberModel x: return VisitEnumMember(x); + case EnumTypeModel x: return VisitEnumType(x); + case ExpressionStatementModel x: return VisitExpressionStatement(x); + case ForLoopStatementModel x: return VisitForLoopStatement(x); + case FunctionCallExpressionModel x: return VisitFunctionCallExpression(x); + case FunctionConstraintRuleModel x: return VisitFunctionConstraintRule(x); + case FunctionModel x: return VisitFunction(x); + case FunctionParameterModel x: return VisitFunctionParameter(x); + case IdentifierAttributeValueModel x: return VisitIdentifierAttributeValue(x); + case IdentifierNameModel x: return VisitIdentifierName(x); + case IfExpressionModel x: return VisitIfExpression(x); + case ImportModel x: return VisitImport(x); + case InfiniteLoopStatementModel x: return VisitInfiniteLoopStatement(x); + case LiteralAttributeValueModel x: return VisitLiteralAttributeValue(x); + case LiteralExpressionModel x: return VisitLiteralExpression(x); + case Model x: return Visit(x); + case NameExpressionModel x: return VisitNameExpression(x); + case NumericLiteralModel x: return VisitNumericLiteral(x); + case ParenthesisExpressionModel x: return VisitParenthesisExpression(x); + case PatternModel x: return VisitPattern(x); + case PointerDereferenceExpressionModel x: return VisitPointerDereferenceExpression(x); + case PointerReferenceExpressionModel x: return VisitPointerReferenceExpression(x); + case PointerTypeReferenceModel x: return VisitPointerTypeReference(x); + case ReturnStatementModel x: return VisitReturnStatement(x); + case SliceTypeModel x: return VisitSliceType(x); + case StringLiteralModel x: return VisitStringLiteral(x); + case StructAccessExpressionModel x: return VisitStructAccessExpression(x); + case StructConstructorExpressionModel x: return VisitStructConstructorExpression(x); + case StructConstructorMemberModel x: return VisitStructConstructorMember(x); + case StructDeclarationModel x: return VisitStructDeclaration(x); + case StructMemberModel x: return VisitStructMember(x); + case StructTypeModel x: return VisitStructType(x); + case SwitchExpressionModel x: return VisitSwitchExpression(x); + case TopLevelStatementModel x: return VisitTopLevelStatement(x); + case TupleConstructorExpressionModel x: return VisitTupleConstructorExpression(x); + case TupleDeclarationModel x: return VisitTupleDeclaration(x); + case TupleTypeModel x: return VisitTupleType(x); + case TypeAliasModel x: return VisitTypeAlias(x); + case TypeNameModel x: return VisitTypeName(x); + case TypeParameterModel x: return VisitTypeParameter(x); + case UnaryOperationExpressionModel x: return VisitUnaryOperationExpression(x); + case VariableDeclarationStatementModel x: return VisitVariableDeclarationStatement(x); + case WhileLoopStatementModel x: return VisitWhileLoopStatement(x); + } + } catch(Exception e) + { + if (e is MeowModelVisitorException) throw; + throw new MeowModelVisitorException(m, e); } return default; } @@ -754,69 +760,73 @@ public class MeowModelVisitor { public void Visit(ModelBase m) { - switch(m) - { + try { + switch(m) + { - case ArrayAccessExpressionModel x: VisitArrayAccessExpression(x); break; - case ArrayConstructorExpressionModel x: VisitArrayConstructorExpression(x); break; - case ArrayTypeModel x: VisitArrayType(x); break; - case AssignmentExpressionModel x: VisitAssignmentExpression(x); break; - case AttributeModel x: VisitAttribute(x); break; - case BinaryOperationExpressionModel x: VisitBinaryOperationExpression(x); break; - case BlockExpressionModel x: VisitBlockExpression(x); break; - case BoolLiteralModel x: VisitBoolLiteral(x); break; - case BreakStatementModel x: VisitBreakStatement(x); break; - case CharacterLiteralModel x: VisitCharacterLiteral(x); break; - case ConstantDeclarationStatementModel x: VisitConstantDeclarationStatement(x); break; - case ConstraintDeclarationModel x: VisitConstraintDeclaration(x); break; - case ConstraintModel x: VisitConstraint(x); break; - case ContinueStatementModel x: VisitContinueStatement(x); break; - case EmbedConstraintRuleModel x: VisitEmbedConstraintRule(x); break; - case EnumConstructorExpressionModel x: VisitEnumConstructorExpression(x); break; - case EnumDeclarationModel x: VisitEnumDeclaration(x); break; - case EnumMemberModel x: VisitEnumMember(x); break; - case EnumTypeModel x: VisitEnumType(x); break; - case ExpressionStatementModel x: VisitExpressionStatement(x); break; - case ForLoopStatementModel x: VisitForLoopStatement(x); break; - case FunctionCallExpressionModel x: VisitFunctionCallExpression(x); break; - case FunctionConstraintRuleModel x: VisitFunctionConstraintRule(x); break; - case FunctionModel x: VisitFunction(x); break; - case FunctionParameterModel x: VisitFunctionParameter(x); break; - case IdentifierAttributeValueModel x: VisitIdentifierAttributeValue(x); break; - case IdentifierNameModel x: VisitIdentifierName(x); break; - case IfExpressionModel x: VisitIfExpression(x); break; - case ImportModel x: VisitImport(x); break; - case InfiniteLoopStatementModel x: VisitInfiniteLoopStatement(x); break; - case LiteralAttributeValueModel x: VisitLiteralAttributeValue(x); break; - case LiteralExpressionModel x: VisitLiteralExpression(x); break; - case Model x: Visit(x); break; - case NameExpressionModel x: VisitNameExpression(x); break; - case NumericLiteralModel x: VisitNumericLiteral(x); break; - case ParenthesisExpressionModel x: VisitParenthesisExpression(x); break; - case PatternModel x: VisitPattern(x); break; - case PointerDereferenceExpressionModel x: VisitPointerDereferenceExpression(x); break; - case PointerReferenceExpressionModel x: VisitPointerReferenceExpression(x); break; - case PointerTypeReferenceModel x: VisitPointerTypeReference(x); break; - case ReturnStatementModel x: VisitReturnStatement(x); break; - case SliceTypeModel x: VisitSliceType(x); break; - case StringLiteralModel x: VisitStringLiteral(x); break; - case StructAccessExpressionModel x: VisitStructAccessExpression(x); break; - case StructConstructorExpressionModel x: VisitStructConstructorExpression(x); break; - case StructConstructorMemberModel x: VisitStructConstructorMember(x); break; - case StructDeclarationModel x: VisitStructDeclaration(x); break; - case StructMemberModel x: VisitStructMember(x); break; - case StructTypeModel x: VisitStructType(x); break; - case SwitchExpressionModel x: VisitSwitchExpression(x); break; - case TopLevelStatementModel x: VisitTopLevelStatement(x); break; - case TupleConstructorExpressionModel x: VisitTupleConstructorExpression(x); break; - case TupleDeclarationModel x: VisitTupleDeclaration(x); break; - case TupleTypeModel x: VisitTupleType(x); break; - case TypeAliasModel x: VisitTypeAlias(x); break; - case TypeNameModel x: VisitTypeName(x); break; - case TypeParameterModel x: VisitTypeParameter(x); break; - case UnaryOperationExpressionModel x: VisitUnaryOperationExpression(x); break; - case VariableDeclarationStatementModel x: VisitVariableDeclarationStatement(x); break; - case WhileLoopStatementModel x: VisitWhileLoopStatement(x); break; + case ArrayAccessExpressionModel x: VisitArrayAccessExpression(x); break; + case ArrayConstructorExpressionModel x: VisitArrayConstructorExpression(x); break; + case ArrayTypeModel x: VisitArrayType(x); break; + case AssignmentExpressionModel x: VisitAssignmentExpression(x); break; + case AttributeModel x: VisitAttribute(x); break; + case BinaryOperationExpressionModel x: VisitBinaryOperationExpression(x); break; + case BlockExpressionModel x: VisitBlockExpression(x); break; + case BoolLiteralModel x: VisitBoolLiteral(x); break; + case BreakStatementModel x: VisitBreakStatement(x); break; + case CharacterLiteralModel x: VisitCharacterLiteral(x); break; + case ConstantDeclarationStatementModel x: VisitConstantDeclarationStatement(x); break; + case ConstraintDeclarationModel x: VisitConstraintDeclaration(x); break; + case ConstraintModel x: VisitConstraint(x); break; + case ContinueStatementModel x: VisitContinueStatement(x); break; + case EmbedConstraintRuleModel x: VisitEmbedConstraintRule(x); break; + case EnumConstructorExpressionModel x: VisitEnumConstructorExpression(x); break; + case EnumDeclarationModel x: VisitEnumDeclaration(x); break; + case EnumMemberModel x: VisitEnumMember(x); break; + case EnumTypeModel x: VisitEnumType(x); break; + case ExpressionStatementModel x: VisitExpressionStatement(x); break; + case ForLoopStatementModel x: VisitForLoopStatement(x); break; + case FunctionCallExpressionModel x: VisitFunctionCallExpression(x); break; + case FunctionConstraintRuleModel x: VisitFunctionConstraintRule(x); break; + case FunctionModel x: VisitFunction(x); break; + case FunctionParameterModel x: VisitFunctionParameter(x); break; + case IdentifierAttributeValueModel x: VisitIdentifierAttributeValue(x); break; + case IdentifierNameModel x: VisitIdentifierName(x); break; + case IfExpressionModel x: VisitIfExpression(x); break; + case ImportModel x: VisitImport(x); break; + case InfiniteLoopStatementModel x: VisitInfiniteLoopStatement(x); break; + case LiteralAttributeValueModel x: VisitLiteralAttributeValue(x); break; + case LiteralExpressionModel x: VisitLiteralExpression(x); break; + case Model x: Visit(x); break; + case NameExpressionModel x: VisitNameExpression(x); break; + case NumericLiteralModel x: VisitNumericLiteral(x); break; + case ParenthesisExpressionModel x: VisitParenthesisExpression(x); break; + case PatternModel x: VisitPattern(x); break; + case PointerDereferenceExpressionModel x: VisitPointerDereferenceExpression(x); break; + case PointerReferenceExpressionModel x: VisitPointerReferenceExpression(x); break; + case PointerTypeReferenceModel x: VisitPointerTypeReference(x); break; + case ReturnStatementModel x: VisitReturnStatement(x); break; + case SliceTypeModel x: VisitSliceType(x); break; + case StringLiteralModel x: VisitStringLiteral(x); break; + case StructAccessExpressionModel x: VisitStructAccessExpression(x); break; + case StructConstructorExpressionModel x: VisitStructConstructorExpression(x); break; + case StructConstructorMemberModel x: VisitStructConstructorMember(x); break; + case StructDeclarationModel x: VisitStructDeclaration(x); break; + case StructMemberModel x: VisitStructMember(x); break; + case StructTypeModel x: VisitStructType(x); break; + case SwitchExpressionModel x: VisitSwitchExpression(x); break; + case TopLevelStatementModel x: VisitTopLevelStatement(x); break; + case TupleConstructorExpressionModel x: VisitTupleConstructorExpression(x); break; + case TupleDeclarationModel x: VisitTupleDeclaration(x); break; + case TupleTypeModel x: VisitTupleType(x); break; + case TypeAliasModel x: VisitTypeAlias(x); break; + case TypeNameModel x: VisitTypeName(x); break; + case TypeParameterModel x: VisitTypeParameter(x); break; + case UnaryOperationExpressionModel x: VisitUnaryOperationExpression(x); break; + case VariableDeclarationStatementModel x: VisitVariableDeclarationStatement(x); break; + case WhileLoopStatementModel x: VisitWhileLoopStatement(x); break; + } + } catch(Exception e) { + throw new MeowModelVisitorException(m, e); } } diff --git a/parser/MeowModelVisitorException.cs b/parser/MeowModelVisitorException.cs new file mode 100644 index 0000000..3074ba2 --- /dev/null +++ b/parser/MeowModelVisitorException.cs @@ -0,0 +1,11 @@ +namespace meowlang.parser; + +public class MeowModelVisitorException : Exception +{ + public ModelBase Model { get; } + + public MeowModelVisitorException(ModelBase model, Exception inner) : base($"{inner.Message} on line {model.Span.Line}", inner) + { + Model = model; + } +} \ No newline at end of file diff --git a/parser/MeowVisitorException.cs b/parser/MeowVisitorException.cs index 76de573..6cadf69 100644 --- a/parser/MeowVisitorException.cs +++ b/parser/MeowVisitorException.cs @@ -6,7 +6,7 @@ public class MeowVisitorException : Exception { public IToken Token { get; } - public MeowVisitorException(IToken token, string message) : base(message) + public MeowVisitorException(IToken token, string message) : base($"{message} on line {token.Line}") { Token = token; } diff --git a/parser/Span.cs b/parser/Span.cs index cce3422..09e96b4 100644 --- a/parser/Span.cs +++ b/parser/Span.cs @@ -1,3 +1,3 @@ namespace meowlang.parser; -public record Span(string Filename, int From, int To); \ No newline at end of file +public record Span(string Filename, int From, int To, int Line); \ No newline at end of file diff --git a/parser/Utils.cs b/parser/Utils.cs index 4bfe3c2..ac75fd4 100644 --- a/parser/Utils.cs +++ b/parser/Utils.cs @@ -118,7 +118,7 @@ internal static class ParserRuleContextExtensions { public static Span GetSpan(this ParserRuleContext context) { - return new Span(context.Start.TokenSource.SourceName, context.Start.StartIndex, context.Stop.StopIndex); + return new Span(context.Start.TokenSource.SourceName, context.Start.StartIndex, context.Stop.StopIndex, context.Start.Line); } } @@ -126,7 +126,7 @@ internal static class TokenExtensions { public static Span GetSpan(this IToken token) { - return new Span(token.TokenSource.SourceName, token.StartIndex, token.StopIndex); + return new Span(token.TokenSource.SourceName, token.StartIndex, token.StopIndex, token.Line); } } diff --git a/visitorgenerator/Program.cs b/visitorgenerator/Program.cs index b8882c1..b3f02ff 100644 --- a/visitorgenerator/Program.cs +++ b/visitorgenerator/Program.cs @@ -57,8 +57,8 @@ string MakeSwitchArm(TypeInfo model, bool isVoid) var typeName = model.Name; var visitorName = $"Visit{UnModelifyName(typeName)}"; return isVoid ? $@" - case {typeName} x: {visitorName}(x); break;" : $@" - case {typeName} x: return {visitorName}(x);"; + case {typeName} x: {visitorName}(x); break;" : $@" + case {typeName} x: return {visitorName}(x);"; } var arms = new List(); @@ -97,9 +97,14 @@ public class {className} public T Visit(ModelBase m) {{ - switch(m) - {{ + try {{ + switch(m) + {{ {string.Join("", arms)} + }} + }} catch(Exception e) {{ + if (e is MeowModelVisitorException) throw; + throw new MeowModelVisitorException(m, e); }} return default; }} @@ -111,9 +116,14 @@ public class {className} {{ public void Visit(ModelBase m) {{ - switch(m) - {{ + try {{ + switch(m) + {{ {string.Join("", voidArms)} + }} + }} catch(Exception e) {{ + if (e is MeowModelVisitorException) throw; + throw new MeowModelVisitorException(m, e); }} }} {string.Join("", voidMethods)}