diff --git a/.gitignore b/.gitignore index fc1f0d5..22b8c39 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ TypoML +src.bin diff --git a/src/main.odin b/src/main.odin index d503afc..b21bb0c 100644 --- a/src/main.odin +++ b/src/main.odin @@ -10,11 +10,13 @@ read_stdin :: proc() -> []string { return strings.split_lines(content) } -print_token :: proc(token: Token, depth: int) { +print_token :: proc(token: Token, depth: int = 0) { indent := strings.repeat(" ", depth, context.temp_allocator) type_str := "" switch token.type { + case TokenType.Root: + type_str = "Root" case TokenType.Text: type_str = "Text" case TokenType.Italics: @@ -49,14 +51,8 @@ print_token :: proc(token: Token, depth: int) { } } -print_token_tree :: proc(tokens: [dynamic]Token) { - for token in tokens { - print_token(token, 0) - } -} - main :: proc() { lines := read_stdin() parsed := parse(lines) - print_token_tree(parsed) + print_token(parsed) } diff --git a/src/parser.odin b/src/parser.odin index c104207..ceac532 100644 --- a/src/parser.odin +++ b/src/parser.odin @@ -10,6 +10,7 @@ TokenType :: enum { BreakLine, Heading, Paragraph, + Root, } TokenValue :: union { @@ -21,10 +22,10 @@ Token :: struct { type: TokenType, value: TokenValue, children: [dynamic]Token, + parent: ^Token, } -token_tree := [dynamic]Token{} -current_token := &token_tree[0] +current_token: ^Token replace_text :: proc(text: string, start: int, len_: int, repl: string) -> string { builder := strings.builder_make(context.temp_allocator) @@ -49,20 +50,26 @@ parse_header :: proc(line: string) -> (int, string) { return lvl, line[lvl + 1:] } -parse :: proc(lines: []string, allocator := context.allocator) -> [dynamic]Token { - token_tree := [dynamic]Token{} - append(&token_tree, Token{TokenType.Paragraph, nil, nil}) - current_token := &token_tree[0] +parse :: proc(lines: []string, allocator := context.allocator) -> Token { + root := Token{TokenType.Root, nil, nil, nil} + current_token := &root + append(¤t_token.children, Token{TokenType.Paragraph, nil, nil, current_token}) + current_token = ¤t_token.children[0] - for untrimmed_line in lines { + for untrimmed_line, line_index in lines { line := strings.trim_space(untrimmed_line) - if len(line) == 0 { - append(¤t_token.children, Token{TokenType.BreakLine, nil, nil}) + if len(line) == 0 && line_index != len(lines) - 1 { + if current_token.parent != nil { + current_token = current_token.parent + } + + append(¤t_token.children, Token{TokenType.Paragraph, nil, nil, current_token}) + current_token = ¤t_token.children[len(current_token.children) - 1] continue } - append(¤t_token.children, Token{TokenType.Text, line, nil}) + append(¤t_token.children, Token{TokenType.Text, line, nil, current_token}) // lvl, text := parse_header(trimmed) // is_header := lvl > 0 @@ -79,5 +86,5 @@ parse :: proc(lines: []string, allocator := context.allocator) -> [dynamic]Token // strings.write_string(&builder, "\n") } - return token_tree + return root }