Skip to content

Commit

Permalink
rename types to reduce inconsistency of APIs; start 0.3.0
Browse files Browse the repository at this point in the history
  • Loading branch information
tiye committed Jan 24, 2021
1 parent f5a03f4 commit 5359673
Show file tree
Hide file tree
Showing 10 changed files with 134 additions and 134 deletions.
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,24 +18,24 @@ parseCirru "a b"
which returns:

```nim
(kind: cirruSeq, list: @[(kind: cirruSeq, list: @[(kind: cirruString, text: "a"), (kind: cirruString, text: "b")])]) : CirruNode
(kind: cirruList, list: @[(kind: cirruList, list: @[(kind: cirruToken, token: "a"), (kind: cirruToken, token: "b")])]) : CirruNode
```

`CirruNode` is the type of exprssions and tokens parsed from Cirru code. Browse [types.nim](src/cirru_parser/types.nim) for definitions.

```nim
type
CirruNodeKind* = enum
cirruString,
cirruSeq
cirruToken,
cirruList
CirruNode* = object
line*: int
column*: int
case kind*: CirruNodeKind
of cirruString:
text*: string
of cirruSeq:
of cirruToken:
token*: string
of cirruList:
list*: DoublyLinkedList[CirruNode]
```

Expand Down
8 changes: 4 additions & 4 deletions cirru_parser.nimble
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Package

version = "0.2.4"
version = "0.3.0"
author = "jiyinyiyong"
description = "Parser for Cirru syntax"
license = "MIT"
Expand All @@ -14,9 +14,9 @@ requires "nim >= 0.20.0"

task t, "Runs the test suite":
exec "nim c --hints:off -r tests/test_iterator"
# exec "nim c --hints:off -r tests/test_parser"
# exec "nim c --hints:off -r tests/test_lexer"
# exec "nim c --hints:off -r tests/test_types"
exec "nim c --hints:off -r tests/test_parser"
exec "nim c --hints:off -r tests/test_lexer"
exec "nim c --hints:off -r tests/test_types"

task perf, "try large file":
exec "nim compile --verbosity:0 --profiler:on --stackTrace:on --hints:off -r tests/parse_cost"
26 changes: 13 additions & 13 deletions src/cirru_parser.nim
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import cirru_parser/helpers
import cirru_parser/lexer
import cirru_parser/transformer

export CirruNode, CirruNodeKind, isSeq, isToken, `==`, `!=`, CirruParseError, formatParserFailure
export CirruNode, CirruNodeKind, isList, isToken, `==`, `!=`, CirruParseError, formatParserFailure
export toCirru, toJson, items, `[]`, len, first, isEmpty, rest, restInLinkedList

proc digestParsingParens*(tokens: var DoublyLinkedList[LexNode]): DoublyLinkedList[CirruNode] =
Expand All @@ -23,15 +23,15 @@ proc digestParsingParens*(tokens: var DoublyLinkedList[LexNode]): DoublyLinkedLi

case cursor.kind
of lexToken:
exprs.append CirruNode(kind: cirruString, text: cursor.text, line: cursor.line, column: cursor.column)
exprs.append CirruNode(kind: cirruToken, token: cursor.token, line: cursor.line, column: cursor.column)
tokens.remove tokens.head
continue
of lexControl:
of lexOperator:
case cursor.operator
of controlParenOpen:
tokens.remove tokens.head
let children = digestParsingParens(tokens)
exprs.append CirruNode(kind: cirruSeq, list: children, line: cursor.line, column: cursor.column)
exprs.append CirruNode(kind: cirruList, list: children, line: cursor.line, column: cursor.column)
continue
of controlParenClose:
tokens.remove tokens.head
Expand All @@ -50,25 +50,25 @@ proc digestParsingIndentation*(tokens: var DoublyLinkedList[LexNode]): DoublyLin
let cursor = tokens.head.value
case cursor.kind
of lexToken:
exprs.append CirruNode(kind: cirruString, text: cursor.text, line: cursor.line, column: cursor.column)
exprs.append CirruNode(kind: cirruToken, token: cursor.token, line: cursor.line, column: cursor.column)
tokens.remove tokens.head
continue
of lexControl:
of lexOperator:
case cursor.operator
of controlParenOpen:
tokens.remove tokens.head
if tokens.head.isNil:
raiseParseExceptionAtNode("Wrong open paren here", cursor)
let children = digestParsingParens(tokens)
exprs.append CirruNode(kind: cirruSeq, list: children, line: cursor.line, column: cursor.column)
exprs.append CirruNode(kind: cirruList, list: children, line: cursor.line, column: cursor.column)
continue
of controlParenClose:
raiseParseExceptionAtNode("Unexpected paren close inside a line", cursor)

of controlIndent:
tokens.remove tokens.head
let children = digestParsingIndentation(tokens)
exprs.append CirruNode(kind: cirruSeq, list: children, line: cursor.line, column: cursor.column)
exprs.append CirruNode(kind: cirruList, list: children, line: cursor.line, column: cursor.column)
continue
of controlOutdent:
tokens.remove tokens.head
Expand All @@ -83,20 +83,20 @@ proc parseCirru*(code: string): CirruNode {.exportc.} =
# echo "tokens: ", tokens

if tokens.head.isNil:
return CirruNode(kind: cirruSeq, list: initDoublyLinkedList[CirruNode](), line: 1, column: 0)
return CirruNode(kind: cirruList, list: initDoublyLinkedList[CirruNode](), line: 1, column: 0)

let r0 = tokens.head.value
let firstExpr = digestParsingIndentation(tokens)
lines.append CirruNode(kind: cirruSeq, list: firstExpr, line: r0.line, column: r0.column)
lines.append CirruNode(kind: cirruList, list: firstExpr, line: r0.line, column: r0.column)

while tokens.head.isNil.not:
let r0 = tokens.head.value
if r0.kind == lexControl and r0.operator == controlIndent:
if r0.kind == lexOperator and r0.operator == controlIndent:
tokens.remove tokens.head
let children = digestParsingIndentation(tokens)
lines.append CirruNode(kind: cirruSeq, list: children, line: r0.line, column: r0.column)
lines.append CirruNode(kind: cirruList, list: children, line: r0.line, column: r0.column)
else:
echo tokens
raiseParseExceptionAtNode("Unexpected tokens sequence!", r0)

return resolveComma(resolveDollar(CirruNode(kind: cirruSeq, list: lines, line: 1, column: 0)))
return resolveComma(resolveDollar(CirruNode(kind: cirruList, list: lines, line: 1, column: 0)))
28 changes: 14 additions & 14 deletions src/cirru_parser/helpers.nim
Original file line number Diff line number Diff line change
Expand Up @@ -7,34 +7,34 @@ import options

import ./types

proc createCirruString*(x: string): CirruNode =
return CirruNode(kind: cirruString, text: x)
proc createCirruToken*(x: string): CirruNode =
return CirruNode(kind: cirruToken, token: x)

proc toCirru*(xs: JsonNode): CirruNode =
case xs.kind:
of JArray:
var b: DoublyLinkedList[CirruNode]
for k, v in xs.elems:
b.append toCirru(v)
return CirruNode(kind: cirruSeq, list: b)
return CirruNode(kind: cirruList, list: b)
of JString:
return CirruNode(kind: cirruString, text: xs.str)
return CirruNode(kind: cirruToken, token: xs.str)
else:
echo xs
raiseParseException("Unknown type in JSON", 1, 0)

proc toJson*(xs: CirruNode): JsonNode =
case xs.kind:
of cirruString:
return JsonNode(kind: JString, str: xs.text)
of cirruSeq:
of cirruToken:
return JsonNode(kind: JString, str: xs.token)
of cirruList:
return JsonNode(kind: JArray, elems: xs.list.toSeq.map(toJson))

proc genLexToken*(text: string): LexNode =
return LexNode(kind: lexToken, text: text)
proc genLexToken*(x: string): LexNode =
return LexNode(kind: lexToken, token: x)

proc genLexControl*(operator: ControlOperator): LexNode =
return LexNode(kind: lexControl, operator: operator)
proc genLexOperator*(operator: ControlOperator): LexNode =
return LexNode(kind: lexOperator, operator: operator)

proc formatParserFailure*(code, msg, filename: string, line, column: int): string =
let lines = splitLines(code)
Expand All @@ -47,13 +47,13 @@ proc formatParserFailure*(code, msg, filename: string, line, column: int): strin
return "At " & filename & ":" & $line & ":" & $column & "\n" & $previousLine & failureLine & "\n" & spaces & "^ " & msg

iterator items*(xs: CirruNode): CirruNode =
if xs.kind == cirruString:
if xs.kind == cirruToken:
raise newException(ValueError, "Cannot create iterator on a cirru string")
for child in xs.list:
yield child

proc `[]`*(xs: CirruNode, fromTo: HSlice[int, int]): seq[CirruNode] =
if xs.kind == cirruString:
if xs.kind == cirruToken:
raise newException(ValueError, "Cannot create iterator on a cirru string")

let fromA = fromTo.a
Expand All @@ -64,7 +64,7 @@ proc `[]`*(xs: CirruNode, fromTo: HSlice[int, int]): seq[CirruNode] =
result[idx] = xs[fromA + idx].get

proc `[]`*(xs: CirruNode, fromTo: HSlice[int, BackwardsIndex]): seq[CirruNode] =
if xs.kind == cirruString:
if xs.kind == cirruToken:
raise newException(ValueError, "Cannot create iterator on a cirru string")

let fromA = fromTo.a
Expand Down
28 changes: 14 additions & 14 deletions src/cirru_parser/lexer.nim
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ proc lexCode*(code: string): DoublyLinkedList[LexNode] =

proc digestBuffer(): void =
if buffer.len > 0:
pieces.append LexNode(kind: lexToken, text: buffer, line: line, column: column)
pieces.append LexNode(kind: lexToken, token: buffer, line: line, column: column)
buffer = ""

proc digestIdentation(): void =
Expand All @@ -30,18 +30,18 @@ proc lexCode*(code: string): DoublyLinkedList[LexNode] =
# echo "indentation:", level
if level > 0:
for i in 1..level.int:
pieces.append LexNode(kind: lexControl, operator: controlIndent, line: line, column: column)
pieces.append LexNode(kind: lexOperator, operator: controlIndent, line: line, column: column)
elif level < 0:
for i in 1..(-level.int):
pieces.append LexNode(kind: lexControl, operator: controlOutdent, line: line, column: column)
pieces.append LexNode(kind: lexOperator, operator: controlOutdent, line: line, column: column)
# special logic to generate extra newline ops
pieces.append LexNode(kind: lexControl, operator: controlOutdent, line: line, column: column)
pieces.append LexNode(kind: lexControl, operator: controlIndent, line: line, column: column)
pieces.append LexNode(kind: lexOperator, operator: controlOutdent, line: line, column: column)
pieces.append LexNode(kind: lexOperator, operator: controlIndent, line: line, column: column)

else:
if pieces.head.isNil.not:
pieces.append LexNode(kind: lexControl, operator: controlOutdent, line: line, column: column)
pieces.append LexNode(kind: lexControl, operator: controlIndent, line: line, column: column)
pieces.append LexNode(kind: lexOperator, operator: controlOutdent, line: line, column: column)
pieces.append LexNode(kind: lexOperator, operator: controlIndent, line: line, column: column)

previousIndentation = indentation
# echo "previousIndentation: ", previousIndentation
Expand Down Expand Up @@ -73,7 +73,7 @@ proc lexCode*(code: string): DoublyLinkedList[LexNode] =
lexingState = lexStateString
of '(':
digestIdentation()
pieces.append LexNode(kind: lexControl, operator: controlParenOpen, line: line, column: column)
pieces.append LexNode(kind: lexOperator, operator: controlParenOpen, line: line, column: column)
lexingState = lexStateSpace
of ')':
raiseParseException("Unexpected ) in line head", line, column)
Expand All @@ -97,7 +97,7 @@ proc lexCode*(code: string): DoublyLinkedList[LexNode] =
of '"':
lexingState = lexStateSpace
# special case, add even if token is empty
pieces.append LexNode(kind: lexToken, text: buffer, line: line, column: column)
pieces.append LexNode(kind: lexToken, token: buffer, line: line, column: column)
buffer = ""
else:
buffer.add c
Expand All @@ -113,10 +113,10 @@ proc lexCode*(code: string): DoublyLinkedList[LexNode] =
of '(':
if buffer.strip().len > 0:
digestBuffer()
pieces.append LexNode(kind: lexControl, operator: controlParenOpen, line: line, column: column)
pieces.append LexNode(kind: lexOperator, operator: controlParenOpen, line: line, column: column)
lexingState = lexStateSpace
of ')':
pieces.append LexNode(kind: lexControl, operator: controlParenClose, line: line, column: column)
pieces.append LexNode(kind: lexOperator, operator: controlParenClose, line: line, column: column)
digestBuffer()
lexingState = lexStateSpace
else:
Expand All @@ -130,11 +130,11 @@ proc lexCode*(code: string): DoublyLinkedList[LexNode] =
of '(':
if buffer.len > 0:
digestBuffer()
pieces.append LexNode(kind: lexControl, operator: controlParenOpen, line: line, column: column)
pieces.append LexNode(kind: lexOperator, operator: controlParenOpen, line: line, column: column)
lexingState = lexStateSpace
of ')':
digestBuffer()
pieces.append LexNode(kind: lexControl, operator: controlParenClose, line: line, column: column)
pieces.append LexNode(kind: lexOperator, operator: controlParenClose, line: line, column: column)
lexingState = lexStateSpace
of '\n':
digestBuffer()
Expand All @@ -144,7 +144,7 @@ proc lexCode*(code: string): DoublyLinkedList[LexNode] =

case lexingState
of lexStateToken:
pieces.append LexNode(kind: lexToken, text: buffer, line: line, column: column)
pieces.append LexNode(kind: lexToken, token: buffer, line: line, column: column)
of lexStateEscape:
raiseParseException("EOF at escape", line, column)
of lexStateString:
Expand Down
44 changes: 22 additions & 22 deletions src/cirru_parser/transformer.nim
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,20 @@ import ./types

proc resolveDollar*(expr: CirruNode): CirruNode =
case expr.kind
of cirruString:
of cirruToken:
return expr
of cirruSeq:
of cirruList:

# try to skip some children
var hasDollar = false
var hasList = false
for child in expr.list:
case child.kind
of cirruString:
if child.text == "$":
of cirruToken:
if child.token == "$":
hasDollar = true
break
of cirruSeq:
of cirruList:
hasList = true
break
if not hasDollar and not hasList:
Expand All @@ -28,35 +28,35 @@ proc resolveDollar*(expr: CirruNode): CirruNode =
var k = 0
for child in expr.list:
case child.kind
of cirruString:
if child.text == "$":
let following = resolveDollar(CirruNode(kind: cirruSeq, list: expr.list.copyFrom(k+1), line: child.line, column: child.column))
of cirruToken:
if child.token == "$":
let following = resolveDollar(CirruNode(kind: cirruList, list: expr.list.copyFrom(k+1), line: child.line, column: child.column))
case following.kind
of cirruSeq:
buffer.append CirruNode(kind: cirruSeq, list: following.list, line: child.line, column: child.column)
of cirruList:
buffer.append CirruNode(kind: cirruList, list: following.list, line: child.line, column: child.column)
break
of cirruString:
raiseParseException("Should not return cirruString", following.line, following.column)
of cirruToken:
raiseParseException("Should not return cirruToken", following.line, following.column)
else:
buffer.append child
of cirruSeq:
of cirruList:
buffer.append resolveDollar(child)
k += 1
return CirruNode(kind: cirruSeq, list: buffer, line: expr.line, column: expr.column)
return CirruNode(kind: cirruList, list: buffer, line: expr.line, column: expr.column)

proc resolveComma*(expr: CirruNode): CirruNode =
case expr.kind
of cirruString:
of cirruToken:
return expr
of cirruSeq:
of cirruList:

# try to skip some children
var hasList = false
for child in expr.list:
case child.kind
of cirruString:
of cirruToken:
discard
of cirruSeq:
of cirruList:
hasList = true
break
if not hasList:
Expand All @@ -65,13 +65,13 @@ proc resolveComma*(expr: CirruNode): CirruNode =
var buffer: DoublyLinkedList[CirruNode]
for child in expr.list:
case child.kind
of cirruString:
of cirruToken:
buffer.append child
of cirruSeq:
if child.list.head.isNil.not and child.list.head.value.kind == cirruString and child.list.head.value.text == ",":
of cirruList:
if child.list.head.isNil.not and child.list.head.value.kind == cirruToken and child.list.head.value.token == ",":
let resolvedChild = resolveComma(child)
for x in resolvedChild.list.copyFrom(1):
buffer.append resolveComma(x)
else:
buffer.append resolveComma(child)
return CirruNode(kind: cirruSeq, list: buffer, line: expr.line, column: expr.column)
return CirruNode(kind: cirruList, list: buffer, line: expr.line, column: expr.column)
Loading

0 comments on commit 5359673

Please sign in to comment.