Skip to content

Commit

Permalink
Work on type parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
optimisticside committed May 29, 2022
1 parent 144ef0f commit 90a464f
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 16 deletions.
11 changes: 8 additions & 3 deletions src/AstNode.lua
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ AstNode.__index = AstNode
AstNode.Kind = enumerate("AstNode.Kind", {
-- Simple types
"True", "False", "Nil", "Dot3",
"String", "Number",
"String", "Number", "Name",

-- Unary operators
"Len", "Neg", "Not",
Expand Down Expand Up @@ -40,18 +40,23 @@ AstNode.Kind = enumerate("AstNode.Kind", {
"SingletonBool", "SingletonString",
})

function AstNode.fromArray(nodeKind, children)
function AstNode.fromArray(nodeKind, children, value)
local self = {}
setmetatable(self, AstNode)

self.value = value
self.kind = nodeKind
self.children = children

return self
end

function AstNode.new(nodeKind, ...)
return AstNode.fromArray(nodeKind, table.pack(...))
return AstNode.fromArray(nodeKind, nil, table.pack(...))
end

function AstNode.fromValue(nodeKind, value, ...)
return AstNode.fromArray(nodeKind, table.pack(...), value)
end

function AstNode.is(object)
Expand Down
34 changes: 21 additions & 13 deletions src/Parser.lua
Original file line number Diff line number Diff line change
Expand Up @@ -425,13 +425,13 @@ function Parser:parseSimpleExpr()
-- String parser.
local str = self:_accept(Token.Kind.QuotedString) or self:_accept(Token.Kind.LongString)
if str then
return AstNode.new(AstNode.Kind.String, str)
return AstNode.fromValue(AstNode.Kind.String, str.value)
end

-- Number parser.
local number = self:_accept(Token.Kind.Number)
if number then
return AstNode.new(AstNode.Kind.Number, number)
return AstNode.fromValue(AstNode.Kind.Number, number.value)
end

return self:parsePrimaryExpr()
Expand Down Expand Up @@ -475,9 +475,9 @@ function Parser:parseTypeParams()
-- TODO: Implement this.
end

-- luacheck: ignore
function Parser:parseName(context)
return self:_expect(Token.Kind.Name)
function Parser:parseName()
local name = self:_expect(Token.Kind.Name)
return AstNode.fromValue(AstNode.Kind.Name, name.value)
end

function Parser:parseGenericTypeList()
Expand All @@ -492,20 +492,20 @@ function Parser:parseSimpleTypeAnnotation()
-- We should have a better system for builin types that don't rely
-- on the actual keywords, like `nil` and `true`.
if self:_accept(Token.Kind.ReservedNil) then
return AstNode.new(AstNode.Kind.TypeReference, AstNode.Kind.Nil)
return AstNode.fromValue(AstNode.Kind.TypeReference, nil)
end

if self:_accept(Token.Kind.ReservedTrue) then
return AstNode.new(AstNode.Kind.SingletonBool, AstNode.Kind.True)
return AstNode.fromValue(AstNode.Kind.SingletonBool, true)
end

if self:_accept(Token.Kind.ReservedFalse) then
return AstNode.new(AstNode.Kind.SingletonBool, AstNode.Kind.False)
return AstNode.fromValue(AstNode.Kind.SingletonBool, false)
end

local stringType = self:_accept(Token.Kind.QuotedString) or self:_accept(Token.Kind.LongString)
if stringType then
return AstNode.new(AstNode.Kind.SingletonString, stringType)
return AstNode.fromValue(AstNode.Kind.SingletonString, stringType.value)
end

if self:_peek(Token.Kind.Name) then
Expand Down Expand Up @@ -630,6 +630,14 @@ function Parser:parseTypeAnnotation()
return parts[1]
end

function Parser:parseTypeAlias(isExported)
local name = self:parseName()
local generics = self:parseGenericTypeList(true)

self:_expect(Token.Kind.Equal)
return AstNode.new(AstNode.Kind.TypeAlias, name, generics, self:parseTypeAnnotation(), isExported)
end

function Parser:parseFunctionArgs(selfParameter)
local args = {}

Expand Down Expand Up @@ -882,12 +890,12 @@ function Parser:parseStat()
-- keywords so we handle them as if they were identifiers.
-- TODO: Take another look at this code. Identifiers should be same thing
-- as names.
if expr.kind == AstNode.Kind.Iden then
if expr.kind == AstNode.Kind.Name then
if self._options.allowTypeAnnotations then
-- I did not know that `type` was actually an operator until now.
if expr.value == "type" then
return self:parseTypeAlias(expr, false)
elseif expr.value == "export" and self._token.kind == Token.Kind.Iden and self._token.value == "type" then
elseif expr.value == "export" and self._token.kind == Token.Kind.Name and self._token.value == "type" then
return self:parseTypeAlias(expr, true)
end
end
Expand All @@ -899,9 +907,9 @@ function Parser:parseStat()
if self._options.allowTypeAnnotations and expr.value == "declare" then
return self:parseDeclaration()
end

return self:_error("Incomplete statement: expected assignment or a function call")
end

return self:_error("Incomplete statement: expected assignment or a function call")
end

function Parser:parseBlock()
Expand Down

0 comments on commit 90a464f

Please sign in to comment.