Skip to content

Commit

Permalink
Merge pull request #5 from Cirru/translating
Browse files Browse the repository at this point in the history
run the demo
  • Loading branch information
NoEgAm authored Sep 15, 2024
2 parents 4f3cef2 + b146881 commit c913ab8
Show file tree
Hide file tree
Showing 43 changed files with 1,246 additions and 99 deletions.
19 changes: 9 additions & 10 deletions .github/workflows/check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,19 @@ on:
pull_request:

jobs:

build:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4

- name: install
if: ${{ matrix.os != 'windows-latest' }}
run: |
/bin/bash -c "$(curl -fsSL https://cli.moonbitlang.com/ubuntu_x86_64_moon_setup.sh)"
echo "/home/runner/.moon/bin" >> $GITHUB_PATH
curl -fsSL https://cli.moonbitlang.com/install/unix.sh | bash
echo "$HOME/.moon/bin" >> $GITHUB_PATH
- name: moon check
run: moon check
# - name: moon check
# run: moon check

# - name: moon info
# run: |
Expand All @@ -28,7 +28,6 @@ jobs:

- name: moon test
run: |
moon test
moon test --target js
# - name: moon bundle
Expand All @@ -37,7 +36,7 @@ jobs:
# - name: check core size
# run: ls -alh `find ./target/bundle -name *.core`

- name: format diff
run: |
moon fmt
git diff
# - name: format diff
# run: |
# moon fmt
# git diff
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
target/
.mooncakes/

trace.json
20 changes: 18 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
# tiye/cirru-parser
# Cirru Parser in Moonbit

_TODO_
Docs: https://mooncakes.io/docs/#/tiye/cirru-parser/lib/members

```bash
moon add tiye/cirru-parser
```

```moon
// parse Cirru code
@cirru_parser.parse(code: String) : Array[Cirru]!CirruParseError
// format Cirru code
@cirru_parser.format(cirru: Array[Cirru], {use_inline: false}) : String!FormatCirruError
```

### License

Apache-2.0
131 changes: 52 additions & 79 deletions lib/parser.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ fn build_exprs(tokens : Array[CirruLexItem]) -> Array[Cirru]!CirruParseError {
let acc : Array[Cirru] = Array::new()
let mut idx = 0
let pull_token = fn() -> CirruLexItem? {
// println("pulling token at \{idx}")
if idx >= tokens.length() {
return None
}
Expand All @@ -27,8 +28,10 @@ fn build_exprs(tokens : Array[CirruLexItem]) -> Array[Cirru]!CirruParseError {
match c {
CirruLexItem::Close =>
match pointer_stack.pop() {
None => acc.push(Cirru::List(pointer))
// break;
None => {
acc.push(Cirru::List(pointer))
break
}
Some(v) => {
let prev_p = pointer
pointer = v
Expand All @@ -53,78 +56,71 @@ fn build_exprs(tokens : Array[CirruLexItem]) -> Array[Cirru]!CirruParseError {
}
}

pub fn parse(content : String) -> Cirru!CirruParseError {
// @seq::Seq::from_string(content)
let ss = content.to_array()
let mut i = 0
while i < ss.length() {
let c = ss[i]
println(c)
i += 1
}
println(ss)
// let bs = content.to_bytes()
Cirru::Leaf("TODO")
/// main function to parse Cirru code into syntax tree
pub fn parse(code : String) -> Array[Cirru]!CirruParseError {
let tokens = resolve_indentations(lex!(code))
// println("tokens: \{tokens}")
let tree = build_exprs!(tokens)
// println("tree: \{tree}")
resolve_comma(resolve_dollar(tree))
}

type! CirruParseError String

/// display Cirru parse error
pub fn to_string(self : CirruParseError) -> String {
match self {
CirruParseError(s) => s
}
}

fn parse_indentation(size : Int) -> CirruLexItem!CirruParseError {
if size % 2 == 0 {
CirruLexItem::Indent(size % 2)
CirruLexItem::Indent(size >> 1)
} else {
raise CirruParseError("odd indentation size: \{size}")
}
}

/// lexer is a simpler state machine to tokenize Cirru code
fn lex(initial_code : String) -> Array[CirruLexItem]!CirruParseError {
let acc = []
let mut state = CirruLexState::Indent
let mut buffer = ""
let code = initial_code.to_array()
let mut idx = 0
while idx < code.length() {
let c = code[idx]
for idx, c in code {
// println("acc: \{acc}")
// println(
// "lexing \{c.to_string().escape()} in \{state} and \{buffer.escape()}",
// )
match state {
CirruLexState::Space =>
match c {
' ' => {
state = CirruLexState::Space
buffer = ""
idx += 1
continue
}
'\n' => {
state = CirruLexState::Indent
buffer = ""
idx += 1
continue
}
'(' => {
acc.push(CirruLexItem::Open)
state = CirruLexState::Space
buffer = ""
idx += 1
continue
}
')' => {
acc.push(CirruLexItem::Close)
state = CirruLexState::Space
buffer = ""
idx += 1
continue
}
'"' => {
state = CirruLexState::Str
buffer = ""
idx += 1
continue
}
_ => {
state = CirruLexState::Token
buffer = c.to_string()
idx += 1
continue
}
}
CirruLexState::Token =>
Expand All @@ -133,43 +129,32 @@ fn lex(initial_code : String) -> Array[CirruLexItem]!CirruParseError {
acc.push(CirruLexItem::Str(buffer))
state = CirruLexState::Space
buffer = ""
idx += 1
continue
}
'"' => {
acc.push(CirruLexItem::Str(buffer))
state = CirruLexState::Str
buffer = ""
idx += 1
continue
}
'\n' => {
acc.push(CirruLexItem::Str(buffer))
state = CirruLexState::Indent
buffer = ""
idx += 1
continue
}
'(' => {
acc.push(CirruLexItem::Str(buffer))
acc.push(CirruLexItem::Open)
state = CirruLexState::Space
buffer = ""
idx += 1
continue
}
')' => {
acc.push(CirruLexItem::Str(buffer))
acc.push(CirruLexItem::Close)
state = CirruLexState::Space
buffer = ""
idx += 1
continue
}
_ => {
state = CirruLexState::Token
buffer += c.to_string()
idx += 1
continue
}
}
CirruLexState::Str =>
Expand All @@ -178,67 +163,55 @@ fn lex(initial_code : String) -> Array[CirruLexItem]!CirruParseError {
acc.push(CirruLexItem::Str(buffer))
state = CirruLexState::Space
buffer = ""
idx += 1
continue
}
'\\' => {
state = CirruLexState::Escape
buffer = ""
idx += 1
continue
}
'\\' => state = CirruLexState::Escape
'\n' => raise CirruParseError("unexpected newline in string")
_ => {
state = CirruLexState::Str
buffer += c.to_string()
idx += 1
continue
}
}
CirruLexState::Escape =>
match c {
'"' => {
state = CirruLexState::Str
buffer += "\""
idx += 1
continue
}
'\'' => {
state = CirruLexState::Str
buffer += "'"
idx += 1
continue
}
't' => {
state = CirruLexState::Str
buffer += "\t"
idx += 1
continue
}
'n' => {
state = CirruLexState::Str
buffer += "\n"
idx += 1
continue
}
'r' => {
state = CirruLexState::Str
buffer += "\r"
idx += 1
continue
}
'u' => {
// TODO handle some unicode
let end = idx + 10
// TODO
let peek = if end >= code.length() {
code[idx:]
} else {
code[idx:end]
}
let mut preview = ""
for c in peek {
preview += c.to_string()
}
println("Unicode escaping is not supported yet: \{preview} ...")
buffer += "\\u"
state = CirruLexState::Str
idx += 1
continue
}
'\\' => {
state = CirruLexState::Str
buffer += "\\"
idx += 1
continue
}
_ =>
raise CirruParseError(
Expand All @@ -250,45 +223,45 @@ fn lex(initial_code : String) -> Array[CirruLexItem]!CirruParseError {
' ' => {
state = CirruLexState::Indent
buffer += c.to_string()
idx += 1
continue
}
'\n' => {
state = CirruLexState::Indent
buffer += ""
idx += 1
continue
buffer = ""
}
'"' => {
let level = parse_indentation!(buffer.length())
acc.push(level)
state = CirruLexState::Str
buffer = ""
idx += 1
continue
}
'(' => {
let level = parse_indentation!(buffer.length())
acc.push(level)
acc.push(CirruLexItem::Open)
state = CirruLexState::Space
buffer = ""
idx += 1
continue
}
')' => raise CirruParseError("unexpected ) at line start")
_ => {
let level = parse_indentation!(buffer.length())
acc.push(level)
state = CirruLexState::Token
buffer = c.to_string()
idx += 1
continue
}
}
}
}
acc
// println("end of file in lex \{acc}")
match state {
CirruLexState::Space => acc
CirruLexState::Token => {
acc.push(CirruLexItem::Str(buffer))
acc
}
CirruLexState::Escape => raise CirruParseError("unknown escape")
CirruLexState::Indent => acc
CirruLexState::Str => raise CirruParseError("finished at string")
}
}

/// internal function for figuring out indentations after lexing
Expand Down
Loading

0 comments on commit c913ab8

Please sign in to comment.