Compare commits

..

No commits in common. "edf164df90f546d34beccc8a3fbbcc5fcb378883" and "dff40e6b275a340d03b21a1f522b6d94eb59d468" have entirely different histories.

7 changed files with 25 additions and 50 deletions

View file

@ -9,5 +9,6 @@ installExt = @["nim"]
bin = @["noether", "nlx"] bin = @["noether", "nlx"]
backend = "c" backend = "c"
# Dependencies # Dependencies
requires "nim >= 2.2.0" requires "nim >= 2.2.0"

View file

@ -1,5 +1,5 @@
import os import os
import noether/lexer/tokstream import noether/lex
when isMainModule: when isMainModule:
echo "Noether Lang Extras v0.1.0 - nlx" echo "Noether Lang Extras v0.1.0 - nlx"

View file

@ -1,5 +1,7 @@
include lstream include lstream
import os # TEMP import
type type
# Provides a stream-like interface for lexing nlToks # Provides a stream-like interface for lexing nlToks
# Internally reliant on the functionality of nlLStream # Internally reliant on the functionality of nlLStream
@ -8,7 +10,7 @@ type
build: nlTok # the current token we're building build: nlTok # the current token we're building
# Resets the build token to an "empty" nlTok where # Resets the build token to an "empty" nlTok where
# only tType, lit, and startPos are initialised. # only tokType, lit, and startPos are initialised.
proc resetBuild(tokStream: var nlTokStream) = proc resetBuild(tokStream: var nlTokStream) =
tokStream.build = emptyTok(tokStream.lstream.pos) tokStream.build = emptyTok(tokStream.lstream.pos)
@ -18,7 +20,7 @@ proc resetBuild(tokStream: var nlTokStream) =
proc finishBuild(tokStream: var nlTokStream) = proc finishBuild(tokStream: var nlTokStream) =
# if we've reached \0 terminator then forge the start # if we've reached \0 terminator then forge the start
# and end positions to point OUTSIDE the line # and end positions to point OUTSIDE the line
let endPos = if isTokTerm(tokStream.build.tType): let endPos = if isTokTerm(tokStream.build.tokType):
inc tokStream.build.startPos; inc tokStream.build.startPos;
tokStream.build.startPos tokStream.build.startPos
else: Natural tokStream.lstream.pos else: Natural tokStream.lstream.pos
@ -36,30 +38,30 @@ proc flushBuild(tokStream: var nlTokStream): nlTok =
# This indicates that the build token should inherit # This indicates that the build token should inherit
# the nlTokType of the nlLStream's next character. # the nlTokType of the nlLStream's next character.
proc isUntypedBuild(tokStream: nlTokStream): bool = proc isUntypedBuild(tokStream: nlTokStream): bool =
result = isTokUntyped(tokStream.build.tType) result = isTokUntyped(tokStream.build.tokType)
# Check whether an nlTokType is "compatible" with # Check whether an nlTokType is "compatible" with
# the build token. flushBuild() should be called # the build token. flushBuild() should be called
# when an incompatible token is discovered. # when an incompatible token is discovered.
proc isCompatibleBuild(tokStream: nlTokStream, tType: nlTokType): bool = proc isCompatibleBuild(tokStream: nlTokStream, tokType: nlTokType): bool =
result = (tType == tokStream.build.tType) result = (tokType == tokStream.build.tokType)
# Add a character to the nlTokStream's build token. # Add a character to the nlTokStream's build token.
# Returns a bool indicating if a new nlTok has been built # Returns a bool indicating if a new nlTok has been built
# or not. flushBuild should then be called. # or not. flushBuild should then be called.
proc appendBuild(tokStream: var nlTokStream, c: char): Option[nlTok] = proc appendBuild(tokStream: var nlTokStream, c: char): Option[nlTok] =
let tType = getTokType(c) let tokType = getTokType(c)
# check whether build token should inherit type # check whether build token should inherit type
if isUntypedBuild(tokStream): if isUntypedBuild(tokStream):
tokStream.build.tType = tType tokStream.build.tokType = tokType
# check character and build token compatability # check character and build token compatability
elif not isCompatibleBuild(tokStream, tType): elif not isCompatibleBuild(tokStream, tokType):
# return flushed build token, and reset # return flushed build token, and reset
result = some(flushBuild(tokStream)) result = some(flushBuild(tokStream))
# new build token is untyped so inherit type # new build token is untyped so inherit type
tokStream.build.tType = tType tokStream.build.tokType = tokType
# check if \0 terminator reached # check if \0 terminator reached
elif isTokTerm(tokStream.build.tType): elif isTokTerm(tokStream.build.tokType):
# return immediately to avoid concatinating '\0' # return immediately to avoid concatinating '\0'
return some(flushBuild(tokStream)) return some(flushBuild(tokStream))
# else return none to indicate no build was completed # else return none to indicate no build was completed
@ -69,7 +71,7 @@ proc appendBuild(tokStream: var nlTokStream, c: char): Option[nlTok] =
tokStream.build.lit.add(c) tokStream.build.lit.add(c)
# Generates and returns the next token in the stream, # Generates and returns the next token in the stream,
# result.tType == nlTokType.NTERM implies line ended # result.tokType == nlTokType.NTERM implies line ended
proc nextTok(tokStream: var nlTokStream): nlTok = proc nextTok(tokStream: var nlTokStream): nlTok =
# try progress to next char, receives none option on failure # try progress to next char, receives none option on failure
for optchar in iterChars(tokStream.lstream): for optchar in iterChars(tokStream.lstream):
@ -96,7 +98,7 @@ iterator toks*(tokStream: var nlTokStream): nlTok =
tok = nextTok(tokStream) tok = nextTok(tokStream)
# \0 terminator means the line ended OR the file # \0 terminator means the line ended OR the file
# has ended, so always yield a line-feed just in case # has ended, so always yield a line-feed just in case
if isTokTerm(tok.tType): if isTokTerm(tok.tokType):
yield tokTermToLineFeed(tok) yield tokTermToLineFeed(tok)
break break
yield tok yield tok

View file

@ -1,7 +1,7 @@
import std/streams import std/streams
import std/options import std/options
include tok include tokens
type type
# Character streaming for the nlTokStream # Character streaming for the nlTokStream

View file

@ -1,7 +0,0 @@
# Attempt to form an nlAST from a nlTokStream
proc arborise(tokStream: nlTokStream): nlNode =
for tok in toks(tokStream):
case tok.tokType:
of nlTokType.DQUO:
# Attempt to parse string literal
parse_strl()

View file

@ -1,18 +0,0 @@
from ../lexer/tok import nlTok
from ../lexer/tokstraem import
type
# NOTE: by the end of parsing NO nodes should
# NOTE: have nlNodeType.NONE
nlNodeType = enum
NONE, # Placeholder Value
TERM, # Indicates the tree has terminated
STRL, # String Literal
CHRL, # Character Literal
nlNode {.acyclic.} = ref object of RootObj
nType: nlNodeType
toks: seq[nlTok] # nodes store the tokens that build them
left, right: nlNode
proc parse()

View file

@ -23,10 +23,9 @@ type
SQUO, # ' Single Quotation Marking SQUO, # ' Single Quotation Marking
DQUO, # " Double Quotation Marking DQUO, # " Double Quotation Marking
GRVA, # ` Grave Accent GRVA, # ` Grave Accent
HASH, # # Number Sign (Hashtag)
nlTok = object nlTok = object
tType*: nlTokType tokType*: nlTokType
lit*: string lit*: string
line*: Natural line*: Natural
startPos*: Natural startPos*: Natural
@ -34,23 +33,23 @@ type
# Generates an "empty" nlTok with only a startPos, # Generates an "empty" nlTok with only a startPos,
# all other fields are expected to be filled out later. # all other fields are expected to be filled out later.
# NOTE: tType initialised to nlTokType.NUL # NOTE: tokType initialised to nlTokType.NUL
# NOTE: lit initialised to empty string # NOTE: lit initialised to empty string
# NOTE: all other fields are uninitialised # NOTE: all other fields are uninitialised
proc emptyTok(startPos: int): nlTok = proc emptyTok(startPos: int): nlTok =
result = nlTok( result = nlTok(
tType: nlTokType.NONE, tokType: nlTokType.NONE,
lit: "", lit: "",
startPos: Natural startPos, startPos: Natural startPos,
) )
# Checks if an nlTok has nlTokType.NONE # Checks if an nlTok has nlTokType.NONE
proc isTokUntyped(tType: nlTokType): bool = proc isTokUntyped(tokType: nlTokType): bool =
result = (tType == nlTokType.NONE) result = (tokType == nlTokType.NONE)
# Checks if an nlTok has nlTokType.TERM # Checks if an nlTok has nlTokType.TERM
proc isTokTerm(tType: nlTokType): bool = proc isTokTerm(tokType: nlTokType): bool =
result = (tType == nlTokType.TERM) result = (tokType == nlTokType.TERM)
# This method is only used to convert null # This method is only used to convert null
# terminator nlToks into line-feed ones. # terminator nlToks into line-feed ones.
@ -59,7 +58,7 @@ proc isTokTerm(tType: nlTokType): bool =
# NOTE: strings in a useful but annoying way # NOTE: strings in a useful but annoying way
proc tokTermToLineFeed(tok: nlTok): nlTok = proc tokTermToLineFeed(tok: nlTok): nlTok =
result = nlTok( result = nlTok(
tType: nlTokType.LNFD, tokType: nlTokType.LNFD,
lit: tok.lit, lit: tok.lit,
line: tok.line, line: tok.line,
startPos: tok.startPos, startPos: tok.startPos,
@ -93,7 +92,5 @@ proc getTokType(c: char): nlTokType =
result = nlTokType.DQUO result = nlTokType.DQUO
of '`': of '`':
result = nlTokType.GRVA result = nlTokType.GRVA
of '#':
result = nlTokType.HASH
else: else:
result = nlTokType.WORD result = nlTokType.WORD