-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmydef_ext.def
125 lines (112 loc) · 3.22 KB
/
mydef_ext.def
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#- Provide MyDef::ext module to be used in perlcode
#- Example:
#- perlcode: codeprint
#- require MyDef::ext
#- my $codelist = MyDef::ext::grab_codelist()
#- ...
include: macros_ext/grab_file.def
page: ext
output_dir: lib/MyDef
package: MyDef::ext
type: pm
fncode: grab_codelist(%opt)
my $codelist = $MyDef::compileutil::named_blocks{"last_grab"}
my $do_macro = $opt{do_macro}
my $with_indent = $opt{with_indent}
$if $codelist
$call filter_SOURCE
return $codelist
subcode: filter_SOURCE
#-- remove SOURCE line ---
my (@t, $indent)
$foreach $t in @$codelist
$if $do_macro
MyDef::compileutil::expand_macro(\$t)
$if $t=~/^SOURCE:/
# skip
$elif $t=~/^NEWLINE/
push @t, "\n"
$else
$if $with_indent
push @t, $t
$else
$call filter_indent
$while $t[-1]=~/^\s*$/
pop @t
$codelist = \@t
subcode: filter_indent
$if $t=~/^SOURCE_INDENT/
$indent++
$elif $t=~/^SOURCE_DEDENT/
$indent--
$elif $indent>0
push @t, " "x$indent . $t
$else
push @t, $t
fncode: inject_sub($name, $src)
my $param
$if $name=~/(\w+)\s*(\(.*\))/
($name, $param)=($1, $2)
my $t_code=MyDef::parseutil::new_code("sub", $name, 9, $param)
$t_code->{source}=$src
$MyDef::def->{codes}->{$name}=$t_code
fncode: run_src($src)
my $t_code=MyDef::parseutil::new_code("sub", "_", 9)
$t_code->{source}=$src
$MyDef::def->{codes}->{"_"}=$t_code
MyDef::compileutil::call_sub("_")
#------------------------------------------
# item1: value
# item2: value
# item3:
# value
# Nested hash, only the top level can be a list
fncode: grab_ogdl($is_list)
my $codelist = grab_codelist("do_macro"=>1, "with_indent"=>1)
$if $codelist
my $ogdl
$if $is_list
$ogdl = []
$else
$ogdl = {}
$call parse_ogdl
return $ogdl
$else
return undef
subcode: parse_ogdl
my @stack
my $cur=$ogdl
my $last_key
$foreach $t in @$codelist
$if $t=~/^SOURCE_INDENT/
$call _push
$elif $t=~/^SOURCE_DEDENT/
$call _pop
$elif $t=~/^\s*$/
next
$elif !@stack and $is_list
push @$cur, $t
$elif $t=~/^(\w+):\s*(.*)/
$cur->{$1} = $2
$last_key = $1
$else
warn "grab_ogdl: error in [$t]\n"
return undef
subcode: _push
$if $last_key
my $t = {"_"=>$cur->{$last_key}}
$cur->{$last_key} = $t
push @stack, $cur
$cur = $t
$else
my $tmp = pop @$cur
my $t = {"_"=>$tmp}
push @$cur, $t
push @stack, $cur
$cur = $t
undef $last_key
subcode: _pop
$if @stack
$cur = pop @stack
$else
die "grab_ogdl: assert\n"