diff --git a/analyze/aps-dnc.c b/analyze/aps-dnc.c index e3582770..9f99359f 100644 --- a/analyze/aps-dnc.c +++ b/analyze/aps-dnc.c @@ -455,10 +455,20 @@ static void *count_if_rules(void *pint, void *node) { ++*count; break; case KEYcase_stmt: + { for (m = first_Match(case_stmt_matchers(decl)); m; m=MATCH_NEXT(m)) { Match_info(m)->if_index = *count; ++*count; } + } + break; + case KEYfor_stmt: + { + for (m = first_Match(for_stmt_matchers(decl)); m; m=MATCH_NEXT(m)) { + Match_info(m)->if_index = *count; + ++*count; + } + } break; default: break; } @@ -477,7 +487,12 @@ static void *get_if_rules(void *varray, void *node) { array[Declaration_info(decl)->if_index] = decl; break; case KEYcase_stmt: - for (m = first_Match(case_stmt_matchers(decl)); m; m=MATCH_NEXT(m)) { + for (m = first_Match(case_stmt_matchers(decl)); m; m=MATCH_NEXT(m)) { + array[Match_info(m)->if_index] = m; + } + break; + case KEYfor_stmt: + for (m = first_Match(for_stmt_matchers(decl)); m; m=MATCH_NEXT(m)) { array[Match_info(m)->if_index] = m; } break; diff --git a/aps2scala/dump-scala.cc b/aps2scala/dump-scala.cc index d2030b55..4654b484 100644 --- a/aps2scala/dump-scala.cc +++ b/aps2scala/dump-scala.cc @@ -270,7 +270,9 @@ void dump_debug_end(ostream& os) // Output Scala pattern for APS pattern int formal_count = 0; -static void dump_pattern_call(Pattern p, Pattern result, const char* resultS, ostream& os) +static void dump_Pattern_impl(Pattern p, ostream& os, std::vector *conditions); + +static void dump_pattern_call(Pattern p, Pattern result, const char* resultS, ostream& os, std::vector *conditions = 0) { Pattern pf = pattern_call_func(p); PatternActuals pactuals = pattern_call_actuals(p); @@ -286,20 +288,44 @@ static void dump_pattern_call(Pattern p, Pattern result, const char* resultS, os dump_Use(pfuse,"p_",os); os << "("; if (result) { - dump_Pattern(result,os); + dump_Pattern_impl(result,os,conditions); } else { os << resultS; } formal_count = 0; for (Pattern pa = first_PatternActual(pactuals); pa ; pa = PAT_NEXT(pa)) { os << ","; - dump_Pattern(pa,os); + dump_Pattern_impl(pa,os,conditions); formal_count++; } os << ")"; } -void dump_Pattern(Pattern p, ostream& os) +void dump_sequence_element_pattern(Pattern p, ostream& os) +{ + std::vector conditions; + dump_Pattern_impl(p,os,&conditions); + if (!conditions.empty()) { + os << " if "; + bool started = false; + for (Expression condition : conditions) { + if (started) os << " && "; + else started = true; + dump_Expression(condition,os); + } + } +} + +void dump_sequence_elements(Pattern p, Expression value, ostream& os) +{ + Pattern pf = pattern_call_func(p); + dump_Use(pattern_use_use(pf),"p_",os); + os << ".unapplySeq("; + dump_Expression(value,os); + os << ").get._2"; +} + +static void dump_Pattern_impl(Pattern p, ostream& os, std::vector *conditions) { switch (Pattern_KEY(p)) { default: @@ -313,14 +339,14 @@ void dump_Pattern(Pattern p, ostream& os) break; case KEYpattern_var: break; } - dump_Pattern(match_pattern_pat(p),os); + dump_Pattern_impl(match_pattern_pat(p),os,conditions); os << ":"; dump_Type(match_pattern_type(p),os); break; case KEYpattern_call: { - dump_pattern_call(p,((Pattern)0),"_",os); + dump_pattern_call(p,((Pattern)0),"_",os,conditions); } break; @@ -342,18 +368,22 @@ void dump_Pattern(Pattern p, ostream& os) switch (Pattern_KEY(and_pattern_p2(p))) { default: break; case KEYcondition: - dump_Pattern(and_pattern_p1(p),os); - os << " if "; - dump_Expression(condition_e(and_pattern_p2(p)),os); + dump_Pattern_impl(and_pattern_p1(p),os,conditions); + if (conditions) { + conditions->push_back(condition_e(and_pattern_p2(p))); + } else { + os << " if "; + dump_Expression(condition_e(and_pattern_p2(p)),os); + } return; case KEYpattern_call: - dump_pattern_call(and_pattern_p2(p),and_pattern_p1(p),"",os); + dump_pattern_call(and_pattern_p2(p),and_pattern_p1(p),"",os,conditions); return; } os << "P_AND("; - dump_Pattern(and_pattern_p1(p),os); + dump_Pattern_impl(and_pattern_p1(p),os,conditions); os << ","; - dump_Pattern(and_pattern_p2(p),os); + dump_Pattern_impl(and_pattern_p2(p),os,conditions); os << ")"; break; @@ -379,6 +409,11 @@ void dump_Pattern(Pattern p, ostream& os) } } +void dump_Pattern(Pattern p, ostream& os) +{ + dump_Pattern_impl(p,os,0); +} + bool type_is_syntax(Type t) { @@ -1989,11 +2024,11 @@ void dump_scala_Declaration(Declaration decl,ostream& oss) case KEYattribute_decl: break; // handled by module - case KEYfunction_decl: + case KEYsome_function_decl: { - Type fty = function_decl_type(decl); + Type fty = some_function_decl_type(decl); Declaration rdecl = first_Declaration(function_type_return_values(fty)); - Block b = function_decl_body(decl); + Block b = some_function_decl_body(decl); Declaration mdecl = get_enclosing_some_class_decl(decl); bool override_needed = false; if (mdecl != NULL) { diff --git a/aps2scala/dump-scala.h b/aps2scala/dump-scala.h index 5a17eb3c..d5f040ea 100644 --- a/aps2scala/dump-scala.h +++ b/aps2scala/dump-scala.h @@ -53,6 +53,8 @@ void dump_debug_end(ostream& os); // these two must always be called in pairs: the first // leaves information around for the second: void dump_Pattern(Pattern p, ostream&); +void dump_sequence_element_pattern(Pattern p, ostream&); +void dump_sequence_elements(Pattern p, Expression value, ostream&); // override << ostream& operator<<(ostream&o,Symbol s); diff --git a/aps2scala/dyn-impl.cc b/aps2scala/dyn-impl.cc index 3dbddc88..37006832 100644 --- a/aps2scala/dyn-impl.cc +++ b/aps2scala/dyn-impl.cc @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -296,8 +297,7 @@ void dump_local_decl(void *, Declaration local, ostream& o) dump_Expression(simple_value(init),o); break; default: - aps_error(local,"Can only handle initialized locals"); - o << "0"; + o << "null.asInstanceOf[" << value_decl_type(local) << "]"; } o << ";\n"; } @@ -313,6 +313,60 @@ void dump_Matches(Matches ms, bool exclusive, ASSIGNFUNC f, void*arg, ostream&os ); } +static void dump_sequence_case(Declaration d, Match match, Pattern middle, + ASSIGNFUNC f, void *arg, ostream& os) +{ + unsigned sequence_number = (unsigned)(uintptr_t)match; + activate_attr_context(os); + os << indent() << "{\n"; + ++nesting_level; + os << indent() << "val sequenceMatch" << sequence_number << " = "; + dump_sequence_elements(matcher_pat(match),case_stmt_expr(d),os); + os << ".collectFirst {\n"; + ++nesting_level; + os << indent() << "case "; + dump_sequence_element_pattern(middle,os); + os << " => {\n"; + ++nesting_level; + dump_Block(matcher_body(match),f,arg,os); + os << indent() << "()\n"; + --nesting_level; + os << indent() << "}\n"; + --nesting_level; + os << indent() << "}\n"; + os << indent() << "if (sequenceMatch" << sequence_number << ".isEmpty) {\n"; + ++nesting_level; + dump_Block(case_stmt_default(d),f,arg,os); + --nesting_level; + os << indent() << "}\n"; + --nesting_level; + os << indent() << "}\n"; +} + +static void dump_sequence_for(Declaration d, Match match, Pattern middle, + ASSIGNFUNC f, void *arg, ostream& os) +{ + activate_attr_context(os); + os << indent(); + dump_sequence_elements(matcher_pat(match),for_stmt_expr(d),os); + os << ".foreach { v_sequence_element =>\n"; + ++nesting_level; + os << indent() << "v_sequence_element match {\n"; + ++nesting_level; + os << indent() << "case "; + dump_sequence_element_pattern(middle,os); + os << " => {\n"; + ++nesting_level; + dump_Block(matcher_body(match),f,arg,os); + --nesting_level; + os << indent() << "}\n"; + os << indent() << "case _ => {}\n"; + --nesting_level; + os << indent() << "}\n"; + --nesting_level; + os << indent() << "}\n"; +} + void dump_Block(Block b,ASSIGNFUNC f,void*arg,ostream&os) { FOR_SEQUENCE @@ -335,18 +389,37 @@ void dump_Block(Block b,ASSIGNFUNC f,void*arg,ostream&os) pop_attr_context(os); break; case KEYcase_stmt: - push_attr_context(d); - //!! we implement case and for!! - dump_Matches(case_stmt_matchers(d),true,f,arg,os); - push_attr_context(case_stmt_default(d)); - dump_Block(case_stmt_default(d),f,arg,os); - pop_attr_context(os); - pop_attr_context(os); + { + Match match; + Pattern middle; + if (sequence_search_matcher(d,&match,&middle) && + (block_assigns_to(matcher_body(match),arg) || + block_assigns_to(case_stmt_default(d),arg))) { + dump_sequence_case(d,match,middle,f,arg,os); + } else { + push_attr_context(d); + //!! we implement case and for!! + dump_Matches(case_stmt_matchers(d),true,f,arg,os); + push_attr_context(case_stmt_default(d)); + dump_Block(case_stmt_default(d),f,arg,os); + pop_attr_context(os); + pop_attr_context(os); + } + } break; case KEYfor_stmt: - push_attr_context(d); - dump_Matches(for_stmt_matchers(d),false,f,arg,os); - pop_attr_context(os); + { + Match match; + Pattern middle; + if (sequence_search_matcher(d,&match,&middle) && + block_assigns_to(matcher_body(match),arg)) { + dump_sequence_for(d,match,middle,f,arg,os); + } else { + push_attr_context(d); + dump_Matches(for_stmt_matchers(d),false,f,arg,os); + pop_attr_context(os); + } + } break; case KEYvalue_decl: if (!(Declaration_info(d)->decl_flags & LOCAL_ATTRIBUTE_FLAG) && @@ -720,9 +793,9 @@ class Dynamic : public Implementation } void implement_function_body(Declaration f, ostream& os) { - Type fty = function_decl_type(f); + Type fty = some_function_decl_type(f); Declaration rdecl = first_Declaration(function_type_return_values(fty)); - Block b = function_decl_body(f); + Block b = some_function_decl_body(f); bool is_col = direction_is_collection(value_decl_direction(rdecl)); const char *name = decl_name(f); diff --git a/codegen/implement.cc b/codegen/implement.cc index 1347cd86..e2d8739d 100644 --- a/codegen/implement.cc +++ b/codegen/implement.cc @@ -45,3 +45,89 @@ void clear_implementation_marks(Declaration d) { int nothing; traverse_Declaration(clear_impl_marks,¬hing,d); } + +bool sequence_search_pattern(Pattern p, Pattern *middle) +{ + Symbol sequence_symbol = intern_symbol("{}"); + if (Pattern_KEY(p) != KEYpattern_call) return false; + + Pattern pf = pattern_call_func(p); + if (Pattern_KEY(pf) != KEYpattern_use) return false; + Declaration pfdecl = USE_DECL(pattern_use_use(pf)); + if (!pfdecl || def_name(declaration_def(pfdecl)) != sequence_symbol) return false; + + Pattern leading = first_PatternActual(pattern_call_actuals(p)); + Pattern element = leading ? PAT_NEXT(leading) : 0; + Pattern trailing = element ? PAT_NEXT(element) : 0; + if (!leading || Pattern_KEY(leading) != KEYrest_pattern || + Pattern_KEY(rest_pattern_constraint(leading)) != KEYno_pattern || + !element || !trailing || Pattern_KEY(trailing) != KEYrest_pattern || + Pattern_KEY(rest_pattern_constraint(trailing)) != KEYno_pattern || + PAT_NEXT(trailing)) { + return false; + } + + *middle = element; + return true; +} + +bool sequence_search_matcher(Declaration decl, Match *match, Pattern *middle) +{ + Matches matchers; + switch (Declaration_KEY(decl)) { + case KEYcase_stmt: + matchers = case_stmt_matchers(decl); + break; + case KEYfor_stmt: + matchers = for_stmt_matchers(decl); + break; + default: + return false; + } + Match first = first_Match(matchers); + if (!first || MATCH_NEXT(first)) return false; + if (!sequence_search_pattern(matcher_pat(first),middle)) return false; + if (match) *match = first; + return true; +} + +bool block_assigns_to(Block b, void *vdecl) +{ + for (Declaration d = first_Declaration(block_body(b)); d; d = DECL_NEXT(d)) { + switch (Declaration_KEY(d)) { + case KEYassign: + { + Expression lhs = assign_lhs(d); + if (Expression_KEY(lhs) == KEYvalue_use && + USE_DECL(value_use_use(lhs)) == vdecl) return true; + if (Expression_KEY(lhs) == KEYfuncall && + USE_DECL(value_use_use(funcall_f(lhs))) == vdecl) return true; + } + break; + case KEYblock_stmt: + if (block_assigns_to(block_stmt_body(d),vdecl)) return true; + break; + case KEYif_stmt: + if (block_assigns_to(if_stmt_if_true(d),vdecl) || + block_assigns_to(if_stmt_if_false(d),vdecl)) return true; + break; + case KEYcase_stmt: + for (Match m = first_Match(case_stmt_matchers(d)); m; m = MATCH_NEXT(m)) { + if (block_assigns_to(matcher_body(m),vdecl)) return true; + } + if (block_assigns_to(case_stmt_default(d),vdecl)) return true; + break; + case KEYfor_stmt: + for (Match m = first_Match(for_stmt_matchers(d)); m; m = MATCH_NEXT(m)) { + if (block_assigns_to(matcher_body(m),vdecl)) return true; + } + break; + case KEYfor_in_stmt: + if (block_assigns_to(for_in_stmt_body(d),vdecl)) return true; + break; + default: + break; + } + } + return false; +} diff --git a/codegen/implement.h b/codegen/implement.h index 45ca03e8..9deaad59 100644 --- a/codegen/implement.h +++ b/codegen/implement.h @@ -93,4 +93,8 @@ extern Implementation *synth_impl; void clear_implementation_marks(Declaration d); +bool sequence_search_pattern(Pattern p, Pattern *middle); +bool sequence_search_matcher(Declaration decl, Match *match, Pattern *middle); +bool block_assigns_to(Block b, void *vdecl); + #endif diff --git a/codegen/static-scc-impl.cc b/codegen/static-scc-impl.cc index 74fa6f61..cde26fdb 100644 --- a/codegen/static-scc-impl.cc +++ b/codegen/static-scc-impl.cc @@ -1,4 +1,5 @@ #include +#include #include #include extern "C" { @@ -13,6 +14,12 @@ extern "C" { #include "dump.h" #include "implement.h" +#ifdef APS2SCALA +bool sequence_search_pattern(Pattern, Pattern*); +void dump_sequence_element_pattern(Pattern, ostream&); +void dump_sequence_elements(Pattern, Expression, ostream&); +#endif + #define LOCAL_VALUE_FLAG (1 << 28) #ifdef APS2SCALA @@ -551,6 +558,87 @@ static bool implement_visit_function( Match m = (Match)ad; Pattern p = matcher_pat(m); Declaration header = Match_info(m)->header; +#ifdef APS2SCALA + Pattern middle; + if (sequence_search_pattern(p, &middle)) { + bool is_for = Declaration_KEY(header) == KEYfor_stmt; + unsigned sequence_number = (unsigned)(uintptr_t)m; + Expression e = is_for ? for_stmt_expr(header) : case_stmt_expr(header); + if (is_for) { + ow->get_outstream() << indent(); + dump_sequence_elements(p, e, ow->get_outstream()); + ow->get_outstream() << ".foreach { v_sequence_element =>\n"; + ++nesting_level; + ow->get_outstream() << indent() << "v_sequence_element match {\n"; + ++nesting_level; + ow->get_outstream() << indent() << "case "; + dump_sequence_element_pattern(middle, ow->get_outstream()); + ow->get_outstream() << " => {\n"; + ++nesting_level; + } else { + ow->get_outstream() << indent() << "{\n"; + ++nesting_level; + ow->get_outstream() << indent() << "val sequenceMatch" + << sequence_number << " = "; + dump_sequence_elements(p, e, ow->get_outstream()); + ow->get_outstream() << ".collectFirst {\n"; + ++nesting_level; + ow->get_outstream() << indent() << "case "; + dump_sequence_element_pattern(middle, ow->get_outstream()); + ow->get_outstream() << " => {\n"; + ++nesting_level; + } + + Block true_block = matcher_body(m); + vector > true_assignment = + make_instance_assignment(aug_graph, true_block, + instance_assignment, false); + int cmask = 1 << if_rule_index(ad); + cond->positive |= cmask; + bool true_cont = implement_visit_function( + aug_graph, phase, cto->cto_if_true, true_assignment, nch, cond, + cto->chunk_index, loop_allowed, loop_id, + skip_previous_visit_code, ow); + cond->positive &= ~cmask; + --nesting_level; + ow->get_outstream() << indent() << "}\n"; + + if (is_for) { + ow->get_outstream() << indent() << "case _ => {}\n"; + --nesting_level; + ow->get_outstream() << indent() << "}\n"; + --nesting_level; + ow->get_outstream() << indent() << "}\n"; + } else { + --nesting_level; + ow->get_outstream() << indent() << "}\n"; + ow->get_outstream() << indent() << "if (sequenceMatch" + << sequence_number << ".isEmpty) {\n"; + ++nesting_level; + } + + Block false_block = is_for || MATCH_NEXT(m) + ? 0 : case_stmt_default(header); + vector > false_assignment = false_block + ? make_instance_assignment(aug_graph, false_block, + instance_assignment, false) + : instance_assignment; + cond->negative |= cmask; + bool false_cont = implement_visit_function( + aug_graph, phase, cto->cto_if_false, false_assignment, nch, cond, + cto->chunk_index, loop_allowed, loop_id, + skip_previous_visit_code, ow); + cond->negative &= ~cmask; + if (!is_for) { + --nesting_level; + ow->get_outstream() << indent() << "}\n"; + --nesting_level; + ow->get_outstream() << indent() << "}\n"; + } + loop_allowed = prev_loop_allowed; + return true_cont || false_cont; + } +#endif /* APS2SCALA */ // if first match in case, we evaluate variable: if (m == first_Match(case_stmt_matchers(header))) { Expression e = case_stmt_expr(header); @@ -818,7 +906,8 @@ static bool implement_visit_function( << "." << decl_name(ad) << " implicit.\n"; } } else if (rhs) { - if (Declaration_KEY(in->node) == KEYfunction_decl) { + if (Declaration_KEY(in->node) == KEYfunction_decl || + Declaration_KEY(in->node) == KEYprocedure_decl) { if (direction_is_collection(value_decl_direction(ad))) { std::cout << "Not expecting collection here!\n"; ow->get_outstream() @@ -1251,7 +1340,7 @@ static void* dump_scheduled_local(void* pbs, void* node) { static void dump_scheduled_function_body(Declaration fd, STATE* s, ostream& bs) { const char* name = decl_name(fd); - Type ft = function_decl_type(fd); + Type ft = some_function_decl_type(fd); // dump any local values: traverse_Declaration(dump_scheduled_local, &bs, fd); @@ -1278,7 +1367,7 @@ static void dump_scheduled_function_body(Declaration fd, STATE* s, ostream& bs) vector > default_instance_assignments( aug_graph->instances.length, std::set()); vector > instance_assignment = make_instance_assignment( - aug_graph, function_decl_body(fd), default_instance_assignments, true /* include defaults */); + aug_graph, some_function_decl_body(fd), default_instance_assignments, true /* include defaults */); CONDITION cond; cond.positive = 0; diff --git a/examples/scala/Makefile b/examples/scala/Makefile index e3ac97f3..206aa7e8 100644 --- a/examples/scala/Makefile +++ b/examples/scala/Makefile @@ -32,7 +32,8 @@ AST_TREE_SCALAGEN = simple.scala tiny.scala grammar.scala \ EVALUATOR_EXAMPLES = classic-binding first follow nullable test-coll \ test-use-coll test-cycle test-fields use-global broad-fiber-cycle \ below-fiber-cycle below-single-fiber-cycle local-fiber-cycle nested-cycles \ - farrow-lv farrow-ubd farrow-ubd-fiber nested-ubd nested-ubd-fiber simple-snc + farrow-lv farrow-ubd farrow-ubd-fiber nested-ubd nested-ubd-fiber simple-snc \ + simple-binding simple-binding1 simple-binding2 simple-binding3 test-for SCALAGEN = ${AST_TREE_SCALAGEN} \ $(foreach example,${EVALUATOR_EXAMPLES},$(example).scala $(example).static.scala) @@ -67,6 +68,9 @@ all : ${OUT}/below_single_fiber_cycle_implicit.class ${OUT}/BelowSingleFiberCycl all : ${OUT}/local_fiber_cycle_implicit.class ${OUT}/LocalFiberCycleDriver.class all : ${OUT}/test_fields_implicit.class ${OUT}/TestFieldsDriver.class all : ${OUT}/simple_snc_implicit.class ${OUT}/SimpleSncDriver.class +all : ${OUT}/simple_binding_implicit.class ${OUT}/SimpleBindingDriver.class +all : SimpleBinding1Driver.class SimpleBinding2Driver.class SimpleBinding3Driver.class +all : ${OUT}/test_for_implicit.class ${OUT}/TestForDriver.class .PHONY: run @@ -372,6 +376,57 @@ ${OUT}/simple_snc_implicit.class : ${OUT}/simple-snc.class ${OUT}/simple_implici ${OUT}/SimpleSncDriver.class: ${OUT}/simple_snc_implicit.class ${OUT}/SimpleParser.class ${SCALAC} ${SCALACFLAGS} simple-snc-driver.scala +${OUT}/simple_binding_implicit.class : simple-binding${IMPL_SUFFIX} ${OUT}/simple_implicit.class + ${SCALAC} ${SCALACFLAGS} $< + @touch $@ + +${OUT}/SimpleBindingDriver.class : ${OUT}/simple_binding_implicit.class ${OUT}/SimpleParser.class simple-binding-driver.scala + ${SCALAC} -cp ${OUT}:.:${APSLIB} -d ${OUT} simple-binding-driver.scala + +.PHONY: SimpleBinding1Driver.class SimpleBinding2Driver.class SimpleBinding3Driver.class + +SimpleBinding1Driver.class : ${OUT}/simple-binding1/SimpleBindingDriver.class ; + +${OUT}/simple-binding1/SimpleBindingDriver.class : simple.scala simple-binding1${IMPL_SUFFIX} simple-binding-driver.scala ${OUT}/SimpleParser.class + rm -rf ${OUT}/simple-binding1 + mkdir -p ${OUT}/simple-binding1 + ${SCALAC} -cp ${OUT}/simple-binding1:${OUT}:.:${APSLIB} -d ${OUT}/simple-binding1 simple.scala simple-binding1${IMPL_SUFFIX} simple-binding-driver.scala + +SimpleBinding2Driver.class : ${OUT}/simple-binding2/SimpleBindingDriver.class ; + +${OUT}/simple-binding2/SimpleBindingDriver.class : simple.scala simple-binding2${IMPL_SUFFIX} simple-binding-driver.scala ${OUT}/SimpleParser.class + rm -rf ${OUT}/simple-binding2 + mkdir -p ${OUT}/simple-binding2 + ${SCALAC} -cp ${OUT}/simple-binding2:${OUT}:.:${APSLIB} -d ${OUT}/simple-binding2 simple.scala simple-binding2${IMPL_SUFFIX} simple-binding-driver.scala + +SimpleBinding3Driver.class : ${OUT}/simple-binding3/SimpleBindingDriver.class ; + +${OUT}/simple-binding3/SimpleBindingDriver.class : simple.scala simple-binding3${IMPL_SUFFIX} simple-binding-driver.scala ${OUT}/SimpleParser.class + rm -rf ${OUT}/simple-binding3 + mkdir -p ${OUT}/simple-binding3 + ${SCALAC} -cp ${OUT}/simple-binding3:${OUT}:.:${APSLIB} -d ${OUT}/simple-binding3 simple.scala simple-binding3${IMPL_SUFFIX} simple-binding-driver.scala + +${OUT}/test_for_implicit.class : test-for${IMPL_SUFFIX} ${OUT}/tiny_implicit.class + ${SCALAC} ${SCALACFLAGS} $< + @touch $@ + +${OUT}/TestForDriver.class : ${OUT}/test_for_implicit.class ${OUT}/TinyParser.class test-for-driver.scala + ${SCALAC} ${SCALACFLAGS} test-for-driver.scala + +.PHONY: SimpleBinding1Driver.run SimpleBinding2Driver.run SimpleBinding3Driver.run + +SimpleBindingDriver.run : ${OUT}/SimpleBindingDriver.class + ${SCALA} ${JVMFLAGS} -cp ${OUT}:.:${APSLIB} SimpleBindingDriver ${ARGS} + +SimpleBinding1Driver.run : ${OUT}/simple-binding1/SimpleBindingDriver.class + ${SCALA} ${JVMFLAGS} -cp ${OUT}/simple-binding1:${OUT}:.:${APSLIB} SimpleBindingDriver ${ARGS} + +SimpleBinding2Driver.run : ${OUT}/simple-binding2/SimpleBindingDriver.class + ${SCALA} ${JVMFLAGS} -cp ${OUT}/simple-binding2:${OUT}:.:${APSLIB} SimpleBindingDriver ${ARGS} + +SimpleBinding3Driver.run : ${OUT}/simple-binding3/SimpleBindingDriver.class + ${SCALA} ${JVMFLAGS} -cp ${OUT}/simple-binding3:${OUT}:.:${APSLIB} SimpleBindingDriver ${ARGS} + .PHONY: %.run %.run : ${OUT}/%.class diff --git a/examples/scala/compare-evaluators.sh b/examples/scala/compare-evaluators.sh index 580b6e9d..4df62af9 100755 --- a/examples/scala/compare-evaluators.sh +++ b/examples/scala/compare-evaluators.sh @@ -115,6 +115,11 @@ TESTS=( "FirstDriver|grammar.cfg|$DEFAULT_EVALUATORS" "FollowDriver|grammar.cfg|$DEFAULT_EVALUATORS" "NullableDriver|grammar.cfg|$DEFAULT_EVALUATORS" + "SimpleBindingDriver|simple.program|$DEFAULT_EVALUATORS" + "SimpleBinding1Driver|simple.program|$DEFAULT_EVALUATORS" + "SimpleBinding2Driver|simple.program|$DEFAULT_EVALUATORS" + "SimpleBinding3Driver|simple.program|$DEFAULT_EVALUATORS" + "TestForDriver|tiny.program|$DEFAULT_EVALUATORS" "SimpleSncDriver|simple.program|$DYNAMIC_EVALUATOR,$ORIGINAL_FARROW_EVALUATOR" ) diff --git a/examples/scala/simple-binding-driver.scala b/examples/scala/simple-binding-driver.scala new file mode 100644 index 00000000..b2ef87ee --- /dev/null +++ b/examples/scala/simple-binding-driver.scala @@ -0,0 +1,33 @@ +object SimpleBindingDriver extends App { + var tree: M_SIMPLE = null + if (args.length == 0) { + tree = new M_SIMPLE("Simple") + val simple = tree.t_Result + val declarations = simple.v_xcons_decls( + simple.v_no_decls(), + simple.v_decl("x", simple.v_integer_type())) + val statement = simple.v_assign_stmt( + simple.v_variable("x"), + simple.v_variable("y")) + val statements = simple.v_xcons_stmts(simple.v_no_stmts(), statement) + simple.v_program(simple.v_block(declarations, statements)) + } else { + val scanner = new SimpleScanner(new java.io.FileReader(args(0))) + val parser = new SimpleParser() + parser.reset(scanner, args(0)) + if (!parser.yyparse()) { + println("Errors found.") + System.exit(1) + } + tree = parser.getTree() + } + + val simpleTree = tree + val binding = new M_NAME_RESOLUTION[simpleTree.T_Result]("Binding", simpleTree.t_Result) + + simpleTree.finish() + binding.finish() + + println("Results:") + binding.v_msgs.toSeq.sorted.foreach(println) +} \ No newline at end of file diff --git a/examples/scala/test-for-driver.scala b/examples/scala/test-for-driver.scala new file mode 100644 index 00000000..0edf7282 --- /dev/null +++ b/examples/scala/test-for-driver.scala @@ -0,0 +1,16 @@ +object TestForDriver extends App { + val tree = new M_TINY("Tiny") + val parser = new TinyParser(tree) + val root = if (args.length > 0) { + parser.parseFile(args(0)) + } else { + tree.v_root(tree.v_branch(tree.v_leaf(3), tree.v_leaf(9))) + } + val test = new M_TEST_FOR[tree.T_Result]("Test For", tree) + + tree.finish() + test.finish() + + println("Results:") + println(test.v_answer(root.asInstanceOf[test.T_Root])) +} \ No newline at end of file