Skip to content

Commit

Permalink
Fix parsing of nested member accesses (thanks @ninjadev for spotting …
Browse files Browse the repository at this point in the history
…that)
  • Loading branch information
stackotter committed Apr 26, 2024
1 parent 77f5aba commit 2451f84
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 13 deletions.
24 changes: 12 additions & 12 deletions Sources/GalahInterpreter/AST.swift
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,13 @@ public enum Type: Hashable, CustomStringConvertible {
}
}

public struct VarDecl {
public struct VarDecl: Equatable {
public var ident: WithSpan<String>
public var type: WithSpan<Type>?
public var value: WithSpan<Expr>
}

public enum Stmt {
public enum Stmt: Equatable {
case expr(Expr)
case `if`(IfStmt)
case `return`(WithSpan<Expr>?)
Expand All @@ -93,8 +93,8 @@ extension Stmt {
}
}

public struct IfStmt {
public indirect enum ElseBlock {
public struct IfStmt: Equatable {
public indirect enum ElseBlock: Equatable {
case elseIf(WithSpan<IfStmt>)
case `else`([WithSpan<Stmt>])
}
Expand All @@ -104,7 +104,7 @@ public struct IfStmt {
public var `else`: ElseBlock?
}

public indirect enum Expr {
public indirect enum Expr: Equatable {
case stringLiteral(String)
case integerLiteral(Int)
case fnCall(FnCallExpr)
Expand Down Expand Up @@ -143,12 +143,12 @@ extension Expr: CustomStringConvertible {
}
}

public struct StructInitExpr {
public struct StructInitExpr: Equatable {
let ident: WithSpan<String>
let fields: WithSpan<[WithSpan<StructInitField>]>
}

public struct StructInitField: CustomStringConvertible {
public struct StructInitField: CustomStringConvertible, Equatable {
let ident: WithSpan<String>
let value: WithSpan<Expr>

Expand All @@ -157,27 +157,27 @@ public struct StructInitField: CustomStringConvertible {
}
}

public struct MemberAccessExpr {
public struct MemberAccessExpr: Equatable {
let base: WithSpan<Expr>
let memberIdent: WithSpan<String>
}

public struct UnaryOpExpr {
public struct UnaryOpExpr: Equatable {
let op: WithSpan<Op>
let operand: WithSpan<Expr>
}

public struct BinaryOpExpr {
public struct BinaryOpExpr: Equatable {
let op: WithSpan<Op>
let leftOperand: WithSpan<Expr>
let rightOperand: WithSpan<Expr>
}

public struct FnCallExpr {
public struct FnCallExpr: Equatable {
public var ident: WithSpan<String>
public var arguments: [WithSpan<Expr>]
}

public struct Tuple {
public struct Tuple: Equatable {
public var elements: [WithSpan<Expr>]
}
2 changes: 1 addition & 1 deletion Sources/GalahInterpreter/Parser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ public struct Parser {
}
var endLocation = location()

if case .period = peek() {
while case .period = peek() {
next()
let memberIdent = try expectIdentWithSpan()
expr = .memberAccess(
Expand Down
31 changes: 31 additions & 0 deletions Tests/GalahInterpreterTests/GalahInterpreterTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -95,4 +95,35 @@ final class GalahInterpreterTests: XCTestCase {
XCTFail("Self-referential structs must fail to type-check")
} catch {}
}

func testNestedMemberAccesses() throws {
let ast = try Parser.parse(
try Lexer.lex(
"""
fn main() {
x.a.b
}
"""
)
)

XCTAssertEqual(
ast.fnDecls[0].stmts[0].inner,
.expr(
.memberAccess(
MemberAccessExpr.init(
base: WithSpan(
builtin: .memberAccess(
.init(
base: WithSpan(builtin: .ident("x")),
memberIdent: WithSpan(builtin: "a")
)
)
),
memberIdent: WithSpan(builtin: "b")
)
)
)
)
}
}

0 comments on commit 2451f84

Please sign in to comment.