From 0196e08aff0a33a64c295fb20e82824855541133 Mon Sep 17 00:00:00 2001 From: Tan Kian-ting Date: Wed, 29 Jan 2025 01:30:58 +0800 Subject: [PATCH] add interp basic function (not yet) --- Project.toml | 1 + docs/grammar.md | 4 +++ example/ex1.ug | 6 +++- src/hyphenating.jl | 5 ---- src/interp.jl | 68 ++++++++++++++++++++++++++++++++++++++++++++++ src/parsing.jl | 18 +++++++----- src/uahgi.jl | 63 +++++++++++++++++++++++++++++++++++++++++- 7 files changed, 151 insertions(+), 14 deletions(-) create mode 100644 src/interp.jl diff --git a/Project.toml b/Project.toml index 3f5ca43..8f731f8 100644 --- a/Project.toml +++ b/Project.toml @@ -5,6 +5,7 @@ version = "1.0.0-DEV" [deps] ArgParse = "c7e460c6-2fb9-53a9-8c5b-16f535851c63" +Fontconfig = "186bb1d3-e1f7-5a2c-a377-96d770f13627" FreeType = "b38be410-82b0-50bf-ab77-7b57e271db43" Match = "7eb4fadd-790c-5f42-8a69-bfa0b872bfbf" ParserCombinator = "fae87a5f-d1ad-5cf0-8f61-c941e1580b46" diff --git a/docs/grammar.md b/docs/grammar.md index a1757c9..069d2b7 100644 --- a/docs/grammar.md +++ b/docs/grammar.md @@ -10,6 +10,10 @@ `{@foo|bar}` +輸入陣列 + +`{@quote|a|b}` + 指定斷字語言: `{@lang|en}`等,要輸入於第一行才有效。 \ No newline at end of file diff --git a/example/ex1.ug b/example/ex1.ug index 99fe11d..3e279d9 100644 --- a/example/ex1.ug +++ b/example/ex1.ug @@ -1,4 +1,8 @@ {@lang|en} +{@def|@font|{@quote|FreeSans|AR PL Kaiti M}} +{@def|@fontsize|12} therapy of communication and pronounciation123%comment -anotherline% processing \ No newline at end of file +anotherline%{@set|@fontsize|10} processing + +of the problem \ No newline at end of file diff --git a/src/hyphenating.jl b/src/hyphenating.jl index beebe0b..e928dfe 100644 --- a/src/hyphenating.jl +++ b/src/hyphenating.jl @@ -41,7 +41,6 @@ end function hyphenate_aux(chars, patterns) level_of_chars = fill(0, length(chars)) - println(level_of_chars) y = filter(x -> (match(Regex(x[1]), chars) !== nothing),patterns) z = map(x -> (x[1], x[2], @@ -112,7 +111,6 @@ function hyphenate(ast) pattern_with_orig = map(x->(remove_num_from_pattern(x), x), patterns) - println("AST=====", ast) new_ast_val = map(x -> match_char(x, pattern_with_orig), ast.val) @@ -137,9 +135,6 @@ function hyphenate(ast) _ => push!(new_ast_val3, i) end end - - println(new_ast_val3) - return c.PROG(new_ast_val3) else return ast diff --git a/src/interp.jl b/src/interp.jl new file mode 100644 index 0000000..a092d9c --- /dev/null +++ b/src/interp.jl @@ -0,0 +1,68 @@ +module Interp +using Match +u = Main.uahgi +c = Main.uahgi.Parsing.Passes.Classes + +function interp_main(ast, env, res_box) + ast_inner = ast.val + val = nothing + for e in ast_inner + (val, env, res_box) = interp(e, env, res_box) + end + return (val, env, res_box) +end +""" +interp: the intepreter of the uahgi. + +- ast: element or part of the ast +- env: the variable storaging environment +- res_box: the generated result box containing the content +""" +function interp(ast, env, res_box, put_char=true) + #println("INTERP", ast) + @match ast begin + c.SEQ([c.ELE([c.ID("def")]), + c.ELE([c.ID(id)]),val]) => + begin + (val_evaled, env, res_box) = interp(val, env, res_box) + println("ID~~~", id, " VAL~~~", val_evaled) + env[id] = val_evaled + return (val_evaled, env, res_box) + end + c.SEQ([c.ELE([c.ID("quote")]), + y...]) => begin + list = map(x -> x[1], + map(x -> interp(x, env, res_box), y)) + println("QUOTE", list) + return (list, env, res_box) + end + + c.ELE([v...]) => begin + ele = reduce( (x, y) -> x*""*y, + map(i -> interp(i, env, res_box, false)[1], v)) + return (ele, env, res_box) + + end + c.CHAR(ch) => begin + ret = ch + if put_char == true + push!(res_box.eles[end].eles, + #=TODO: check single-char size + env[""] + =# + u.ChBox(ch, "foo", 20, 1, 2, 3)) + end + return (ret, env, res_box) + end + c.NL(nl) => return (nl, env, res_box) + c.SPACE(sp) => return (sp, env, res_box) + + _ => begin + println("不知道") + val_evaled = "不知道" + return (val_evaled, env, res_box) + end + end +end + +end \ No newline at end of file diff --git a/src/parsing.jl b/src/parsing.jl index 369d669..b523639 100644 --- a/src/parsing.jl +++ b/src/parsing.jl @@ -7,6 +7,8 @@ include("hyphenating.jl") using .Passes using .Hyphenating + + #= grammar rules of uahgi =# @@ -21,7 +23,7 @@ id = E"@" + id_name empty_char = P"" # empty char #make alphabet series a group for hyphenating -char = p"([a-zA-Z]+|[^ a-zA-Z\n\r\t\\])" > Passes.Classes.CHAR #[1:2,:?] +char = p"([a-zA-Z]+|[^ \|\{\}\@\%a-zA-Z\n\r\t\\])" > Passes.Classes.CHAR #[1:2,:?] # chars should be preceded by "\" are \, {, }, |, @, % esc_char = p"[\{\|\}\@\%]" > Passes.Classes.ESC_CHAR @@ -30,11 +32,13 @@ esc_combined = E"\\" + esc_char seq = (foo x1 x2 " ") => {@foo|x1|x2| } =# -char_and_combined = char | esc_combined -seq_item = id | Repeat(char_and_combined) | empty_char |> Passes.Classes.ELE +seq = Delayed() # recursively used later. +char_and_combined = char | esc_combined | space | newline +seq_atom_item = id | Repeat(char_and_combined) | empty_char |> Passes.Classes.ELE +seq_item = seq | seq_atom_item seq_item_rest = E"|" + seq_item seq_inner = seq_item + (seq_item_rest)[0:end] |> Passes.Classes.SEQ -seq = E"{" + seq_inner + E"}" +seq.matcher = E"{" + seq_inner + E"}" part = seq | comment | space | newline | id | char @@ -60,7 +64,7 @@ function parse(input) new_ast = Passes.Classes.PROG(ast_val) print(ast_to_string(new_ast)) - return ast + return new_ast end @@ -93,7 +97,7 @@ function use_pass(ast_val, pass) else ast_head = ast_val[1:pass_pattern_length] - if ast_pattern_matched(pass_pattern, ast_head) + if ast_pattern_matched(pass_pattern, ast_head) ast_head = pass.func(ast_head) raw_remained = [ast_head[2:end];ast_val[pass_pattern_length+1:end]] remained = use_pass(raw_remained, pass) @@ -125,7 +129,7 @@ function ast_to_string(ast) return "[ELE : (" * prog_inner * ")]" end Passes.Classes.ESC_CHAR(ch) => "[ESC:\"" * ch[1] * "\"]" - Passes.Classes.CHAR(ch) => "\"" * ch[1] * "\"" + Passes.Classes.CHAR(ch) => "\"" * ch * "\"" Passes.Classes.NL(_) => "NL" Passes.Classes.SPACE(_) => "SPACE" diff --git a/src/uahgi.jl b/src/uahgi.jl index 07a29b5..1a22e3b 100644 --- a/src/uahgi.jl +++ b/src/uahgi.jl @@ -1,8 +1,60 @@ module uahgi include("parsing.jl") +include("interp.jl") +using .Interp using .Parsing using ArgParse +abstract type Box end +""" +Horizonal Box + +- eles = array in the Hbox +- ht = height +- dp = depth +- wd = width +""" +mutable struct HBox<:Box + eles + ht + dp + wd +end + +""" +Vertical Box + +- eles = array in the Hbox +- ht = height +- dp = depth +- wd = width +""" +mutable struct VBox<:Box + eles + ht + dp + wd +end + +""" +Character Box + +- char: character +- font_path: font path for the char +- size: font sizein pt +- ht = height +- dp = depth +- wd = width +""" +mutable struct ChBox<:Box + char + font_path + size + ht + dp + wd +end + function parse_commandline() #= please see: https://carlobaldassi.github.io/ArgParse.jl/stable/ @@ -29,7 +81,16 @@ function main() # file_path = parsed_args["FILE"] #end file_content = open(f->read(f, String), file_path) - Parsing.parse(file_content) + ast = Parsing.parse(file_content) + + + default_env = Dict() # the default environment for the intepreter + output_box_orig = VBox([HBox([], nothing, nothing, nothing)], + nothing, nothing, nothing) + output_box_result = Interp.interp_main(ast, default_env, output_box_orig) + print("Env", output_box_result[2]) + print("OutPutBox", output_box_result[3]) + end main()