Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- module sum_example ;
- import std.stdio ;
- import std.conv ;
- import ast_parser ;
- string indent (int n)
- {
- string indent_str = " " ;
- string result = "" ;
- foreach (i ; 0 .. n)
- result ~= indent_str ;
- return result ;
- }
- string sumImpl (string astStr)
- {
- string AST_ERROR_STR = "Sum AST error : incorrect sum syntax" ;
- string loop_var [] ;
- string loop_start [] ;
- string loop_end [] ;
- string loop_inc [] ;
- string loop_cond [] ;
- string loop_body ;
- auto ast = TokenList.parseD (astStr) ;
- assert (ast.length >= 3, AST_ERROR_STR) ;
- assert (ast.getStringItem (0) == ";", "Sum AST error : sum must be separeted by semicolons") ;
- foreach (i ; 1 .. ast.length - 1)
- {
- auto arg = ast.getItem (i) ;
- TokenList ast_cycle ;
- if (arg.getStringItem (0) == ",")
- {
- ast_cycle = arg.getItem (1) ;
- loop_cond ~= arg.getItem (2).toD_String () ;
- }
- else
- {
- loop_cond ~= null ;
- ast_cycle = arg ;
- }
- assert (ast_cycle.getStringItem (0) == "=", AST_ERROR_STR) ;
- loop_var ~= ast_cycle.getStringItem (1) ;
- // (: 1 1 10)
- // (: 1 10)
- ast_cycle = ast_cycle.getItem (2) ;
- assert (ast_cycle.getStringItem (0) == ":", AST_ERROR_STR) ;
- loop_start ~= ast_cycle.getItem (1).toD_String () ;
- if (ast_cycle.length == 4)
- {
- loop_inc ~= ast_cycle.getItem (2).toD_String () ;
- loop_end ~= ast_cycle.getItem (3).toD_String () ;
- }
- else
- if (ast_cycle.length == 3)
- {
- loop_inc ~= null ;
- loop_end ~= ast_cycle.getItem (2).toD_String () ;
- }
- else
- assert (0, AST_ERROR_STR) ;
- }
- loop_body = ast.getItem (ast.length - 1).toD_String () ;
- auto sum_i = new string [ast.length - 2] ;
- string result = "function int () {\n" ;
- int idt = 1 ;
- foreach (i ; 0 .. ast.length - 2)
- {
- sum_i [i] = "sum_" ~ to!string (i) ;
- result ~=
- indent (idt) ~ "int " ~ sum_i [i] ~ " ;\n" ~
- indent (idt) ~ "for (int " ~ loop_var [i] ~ " = " ~ loop_start [i] ~ " ; " ~ loop_var [i] ~ " < " ~ loop_end [i] ~ " ; " ;
- if (loop_inc [i] is null)
- result ~= "++" ~ loop_var [i] ;
- else
- result ~= loop_var [i] ~ " += " ~ loop_inc [i] ;
- result ~= " )\n" ~
- indent (idt) ~ "{\n" ;
- if (loop_cond [i] !is null)
- {
- ++ idt ;
- result ~= indent (idt) ~ loop_cond [i] ~ "\n"
- ~ indent (idt) ~ "{\n";
- }
- if (i == ast.length - 3)
- {
- result ~= indent (idt + 1) ~ sum_i [i] ~ " += " ~ loop_body ~ " ;\n" ;
- if (loop_cond [i] !is null)
- {
- result ~= indent (idt) ~ "}\n" ;
- -- idt ;
- }
- result ~= indent (idt) ~ "}\n" ;
- }
- else
- ++ idt ;
- }
- foreach_reverse (i ; 0 .. ast.length - 3)
- {
- string res = indent (idt) ~ sum_i [i] ~ " += " ~ sum_i [i+1] ~ " ;\n" ;
- if (loop_cond [i] !is null)
- {
- result ~= res ;
- -- idt ;
- result ~= indent (idt) ~ "}\n" ;
- }
- else
- result ~= res ;
- -- idt ;
- result ~= indent (idt) ~ "}\n" ;
- }
- result ~= indent (1) ~ "return sum_0 ;\n"
- ~ "} ()" ;
- return result ;
- }
- string sumImpl2 (string loop_var, string loop_start, string loop_end, string loop_body)
- {
- return
- "function int () {\n" ~
- "int sum_ ;\n" ~
- "foreach ( " ~ loop_var ~ " ; " ~ loop_start ~ " .. " ~ loop_end ~ " )\n" ~
- "{\n" ~
- " sum_ += " ~ loop_body ~ " ;\n" ~
- "}\n" ~
- "return sum_ ;\n" ~
- "} ()" ;
- }
- template sum (string loop_var, string loop_start, string loop_end, string loop_body)
- {
- mixin ("enum sum = " ~ sumImpl2 (loop_var, loop_start, loop_end, loop_body) ~ " ;") ;
- }
- template sum2 (string s)
- {
- mixin ("enum sum2 = " ~ s ~ ";") ;
- }
- void main ()
- {
- int x = sum2 !(q{1 + sum2!("2")}) ;
- writeln (x) ;
- x = 1 + sum! ("i", "1", "10", q{i * sum!("j", "0", "9", "1+j")}) ;
- writeln (x) ;
- writeln (sumImpl ("i = 1:10 ; j = 1:2:n+1, if (j != i) ; k = i:j, if (k != 3) ; i*i/(k+j^3) + 2")) ;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement