//: Advanced notation for the common/easy case where a recipe takes some fixed //: number of ingredients and yields some fixed number of products. void test_recipe_with_header() { run( "def main [\n" " 1:num/raw <- add2 3, 5\n" "]\n" "def add2 x:num, y:num -> z:num [\n" " local-scope\n" " load-ingredients\n" " z:num <- add x, y\n" " return z\n" "]\n" ); CHECK_TRACE_CONTENTS( "mem: storing 8 in location 1\n" ); } //: When loading recipes save any header. :(before "End recipe Fields") bool has_header; vector ingredients; vector products; :(before "End recipe Constructor") has_header = false; :(before "End Recipe Refinements") if (in.peek() != '[') { trace(101, "parse") << "recipe has a header; parsing" << end(); load_recipe_header(in, result); } :(code) void load_recipe_header(istream& in, recipe& result) { result.has_header = true; while (has_data(in) && in.peek() != '[' && in.peek() != '\n') { string s = next_word(in); if (s.empty()) { assert(!has_data(in)); raise << "incomplete recipe header at end of file (0)\n" << end(); return; } if (s == "<-") raise << "recipe " << result.name << " should say '->' and not '<-'\n" << end(); if (s == "->") break; result.ingredients.push_back(reagent(s)); trace(101, "parse") << "header ingredient: " << result.ingredients.back().original_string << end(); skip_whitespace_but_not_newline(in); } while (has_data(in) && in.peek() != '[' && in.peek() != '\n') { string s = next_word(in); if (s.empty()) { assert(!has_data(in)); raise << "incomplete recipe header at end of file (1)\n" << end(); return; } result.products.push_back(reagent(s)); trace(101, "parse") << "header product: " << result.products.back().original_string << end(); skip_whitespace_but_not_newline(in); } // End Load Recipe Header(result) } void test_recipe_handles_stray_comma() { run( "def main [\n" " 1:num/raw <- add2 3, 5\n" "]\n" "def add2 x:num, y:num -> z:num, [\n" " local-scope\n" " load-ingredients\n" " z:num <- add x, y\n" " return z\n" "]\n" ); CHECK_TRACE_CONTENTS( "mem: storing 8 in location 1\n" ); } void test_recipe_handles_stray_comma_2() { run( "def main [\n" " foo\n" "]\n" "def foo, [\n" " 1:num/raw <- add 2, 2\n" "]\n" "def bar [\n" " 1:num/raw <- add 2, 3\n" "]\n" ); CHECK_TRACE_CONTENTS( "mem: storing 4 in location 1\n" ); } void test_recipe_handles_wrong_arrow() { Hide_errors = true; run( "def foo a:num <- b:num [\n" "]\n" ); CHECK_TRACE_CONTENTS( "error: recipe foo should say '->' and not '<-'\n" ); } void test_recipe_handles_missing_bracket() { Hide_errors = true; run( "def main\n" "]\n" ); CHECK_TRACE_CONTENTS( "error: main: recipe body must begin with '['\n" ); } void test_recipe_handles_missing_bracket_2() { Hide_errors = true; run( "def main\n" " local-scope\n" " {\n" " }\n" "]\n" ); // doesn't overflow line when reading header CHECK_TRACE_DOESNT_CONTAIN("parse: header ingredient: local-scope"); CHECK_TRACE_CONTENTS( "error: main: recipe body must begin with '['\n" ); } void test_recipe_handles_missing_bracket_3() { Hide_errors = true; run( "def main # comment\n" " local-scope\n" " {\n" " }\n" "]\n" ); // doesn't overflow line when reading header CHECK_TRACE_DOESNT_CONTAIN("parse: header ingredient: local-scope"); CHECK_TRACE_CONTENTS( "error: main: recipe body must begin with '['\n" ); } :(after "Begin debug_string(recipe x)") out << "ingredients:\n"; for (int i = 0; i < SIZE(x.ingredients); ++i) out << " " << debug_string(x.ingredients.at(i)) << '\n'; out << "products:\n"; for (int i = 0; i < SIZE(x.products); ++i) out << " " << debug_string(x.products.at(i)) << '\n'; //: If a recipe never mentions any ingredients or products, assume it has a header. :(code) void test_recipe_without_ingredients_or_products_has_header() { run( "def test [\n" " 1:num <- copy 34\n" "]\n" ); CHECK_TRACE_CONTENTS( "parse: recipe test has a header\n" ); } :(before "End Recipe Body(result)") if (!result.has_header) { result.has_header = true; for (int i = 0; i < SIZE(result.steps); ++i) { const instruction& inst = result.steps.at(i); if ((inst.name == "reply" && !inst.ingredients.empty()) || (inst.name == "return" && !inst.ingredients.empty()) || inst.name == "next-ingredient" || inst.name == "ingredient" || inst.name == "rewind-ingredients") { result.has_header = false; break; } } } if (result.has_header) { trace(101, "parse") << "recipe " << result.name << " has a header" << end(); } //: Support type abbreviations in headers. :(code) void test_type_abbreviations_in_recipe_headers() { run( "def main [\n" " local-scope\n" " a:text <- foo\n" " 1:char/raw <- index *a, 0\n" "]\n" "def foo -> a:text [ # 'text' is an abbreviation\n" " local-scope\n" " load-ingredients\n" " a <- new [abc]\n"
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html><head><title>Python: module ranger.ext.openstruct</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head><body bgcolor="#f0f0f8">

<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
<tr bgcolor="#7799ee">
<td valign=bottom>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="ranger.html"><font color="#ffffff">ranger</font></a>.<a href="ranger.ext.html"><font color="#ffffff">ext</font></a>.openstruct</strong></big></big></font></td
><td align=right valign=bottom
><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:/home/hut/work/ranger/ranger/ext/openstruct.py">/home/hut/work/ranger/ranger/ext/openstruct.py</a></font></td></tr></table>
    <p><tt>#&nbsp;Copyright&nbsp;(c)&nbsp;2009,&nbsp;2010&nbsp;hut&nbsp;&lt;hut@lavabit.com&gt;<br>
#<br>
#&nbsp;Permission&nbsp;to&nbsp;use,&nbsp;copy,&nbsp;modify,&nbsp;and/or&nbsp;distribute&nbsp;this&nbsp;software&nbsp;for&nbsp;any<br>
#&nbsp;purpose&nbsp;with&nbsp;or&nbsp;without&nbsp;fee&nbsp;is&nbsp;hereby&nbsp;granted,&nbsp;provided&nbsp;that&nbsp;the&nbsp;above<br>
#&nbsp;copyright&nbsp;notice&nbsp;and&nbsp;this&nbsp;permission&nbsp;notice&nbsp;appear&nbsp;in&nbsp;all&nbsp;copies.<br>
#<br>
#&nbsp;THE&nbsp;SOFTWARE&nbsp;IS&nbsp;PROVIDED&nbsp;"AS&nbsp;IS"&nbsp;AND&nbsp;THE&nbsp;AUTHOR&nbsp;DISCLAIMS&nbsp;ALL&nbsp;WARRANTIES<br>
#&nbsp;WITH&nbsp;REGARD&nbsp;TO&nbsp;THIS&nbsp;SOFTWARE&nbsp;INCLUDING&nbsp;ALL&nbsp;IMPLIED&nbsp;WARRANTIES&nbsp;OF<br>
#&nbsp;MERCHANTABILITY&nbsp;AND&nbsp;FITNESS.&nbsp;IN&nbsp;NO&nbsp;EVENT&nbsp;SHALL&nbsp;THE&nbsp;AUTHOR&nbsp;BE&nbsp;LIABLE&nbsp;FOR<br>
#&nbsp;ANY&nbsp;SPECIAL,&nbsp;DIRECT,&nbsp;INDIRECT,&nbsp;OR&nbsp;CONSEQUENTIAL&nbsp;DAMAGES&nbsp;OR&nbsp;ANY&nbsp;DAMAGES<br>
#&nbsp;WHATSOEVER&nbsp;RESULTING&nbsp;FROM&nbsp;LOSS&nbsp;OF&nbsp;USE,&nbsp;DATA&nbsp;OR&nbsp;PROFITS,&nbsp;WHETHER&nbsp;IN&nbsp;AN<br>
#&nbsp;ACTION&nbsp;OF&nbsp;CONTRACT,&nbsp;NEGLIGENCE&nbsp;OR&nbsp;OTHER&nbsp;TORTIOUS&nbsp;ACTION,&nbsp;ARISING&nbsp;OUT&nbsp;OF<br>
#&nbsp;OR&nbsp;IN&nbsp;CONNECTION&nbsp;WITH&nbsp;THE&nbsp;USE&nbsp;OR&nbsp;PERFORMANCE&nbsp;OF&nbsp;THIS&nbsp;SOFTWARE.</tt></p>
<p>
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
<tr bgcolor="#ee77aa">
<td colspan=3 valign=bottom>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
    
<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
<td width="100%"><dl>
<dt><font face="helvetica, arial"><a href="builtins.html#object">builtins.object</a>
</font></dt