about summary refs log tree commit diff stats
Commit message (Expand)AuthorAgeFilesLines
* Allow incoming private messages from chat roomsJames Booth2012-11-122-20/+27
* Added win_type to prof_win structureJames Booth2012-11-122-16/+23
* Merge pull request #79 from pasis/devJames Booth2012-11-121-0/+3
|\
| * ignore SIGPIPEDmitry Podgorny2012-11-121-0/+3
* | Clear contact list when connection lostJames Booth2012-11-121-0/+1
* | Added log to /prefs outputJames Booth2012-11-121-0/+2
|/
* Fixed help on log commandJames Booth2012-11-121-2/+2
* Merge pull request #77 from pasis/rotateJames Booth2012-11-123-2/+82
|\
| * complete log rotation supportDmitry Podgorny2012-11-123-2/+82
|/
* Changed /who command to allow available and unavailableJames Booth2012-11-121-2/+46
* Added /help list to list all commandsJames Booth2012-11-113-7/+59
* Merge pull request #73 from pasis/rotateJames Booth2012-11-114-5/+64
|\
| * introduce initial log rotate supportDmitry Podgorny2012-11-113-4/+63
| * fix spacingDmitry Podgorny2012-11-111-1/+1
* | Added win_page_off to subscriptions to scroll windowJames Booth2012-11-111-0/+3
* | Shortened /sub "request" parameter to "req", and formatted helpJames Booth2012-11-112-12/+12
|/
* Merge pull request #63 from pasis/subscriptionJames Booth2012-11-119-23/+173
|\
| * rename _cmd_reset_who_completerDmitry Podgorny2012-11-111-3/+3
| * fix autocompletion for /sub commandDmitry Podgorny2012-11-113-27/+23
| * add subscription supportDmitry Podgorny2012-11-1110-19/+173
|/
* Added function to create room jid from room and nickJames Booth2012-11-105-9/+42
* Renamed room_chat functionJames Booth2012-11-103-3/+3
* Renamed parameter in win_join_chatJames Booth2012-11-102-4/+4
* Renamed params in jabber_joinJames Booth2012-11-103-11/+11
* Tidy room_chatJames Booth2012-11-102-52/+52
* Renamed jid->room in room_chatJames Booth2012-11-101-5/+5
* Handle /me in chat roomsJames Booth2012-11-101-5/+29
* Handle subject from roomJames Booth2012-11-108-2/+73
* Show error text if receivedJames Booth2012-11-104-15/+27
* Using vargs in cons_bad_showJames Booth2012-11-104-16/+21
* Tidy up leaving roomJames Booth2012-11-104-6/+22
* Moved ping iq creation to stanzaJames Booth2012-11-103-41/+56
* Moved roster iq creation to stanzaJames Booth2012-11-103-14/+22
* Renamed stanza creationJames Booth2012-11-103-8/+7
* Moved update presence handler creation to stanza moduleJames Booth2012-11-103-40/+59
* Moved chat room leave presence creation to stanza moduleJames Booth2012-11-093-11/+10
* Fixed leaving chat roomJames Booth2012-11-093-2/+18
* Moved room join stanza creationJames Booth2012-11-093-14/+26
* Added stanza constantsJames Booth2012-11-093-80/+124
* Use stanza module to create groupchat messagesJames Booth2012-11-082-22/+5
* Added xml escaping to stanza moduleJames Booth2012-11-082-7/+9
* Added function to create message stanzasJames Booth2012-11-083-37/+52
* Added stanza module for basic stanza handlingJames Booth2012-11-084-27/+100
* Added #define's to headersJames Booth2012-11-084-2/+17
* Continue to send chat states when no viewing chat windowJames Booth2012-11-083-30/+48
* Show delayed time on messages received whilst offlineJames Booth2012-11-088-19/+73
* Do not show chat state notifications when <delay/> presentJames Booth2012-11-081-1/+7
* Added help for chat roomsJames Booth2012-11-081-1/+4
* Using /who in chat room shows room occupantsJames Booth2012-11-082-47/+53
* Basic chat room handling of presenceJames Booth2012-11-087-12/+111
6-11-10 10:24:14 -0800 3656' href='/akkartik/mu/commit/028call_return.cc?h=hlt&id=f116818c7c6e98a5d9bfa7058096b42df85d8e1c'>f116818c ^
6c96a437 ^
1bc0bb7e ^


636837e7 ^
1bc0bb7e ^
6c96a437 ^
f116818c ^

1bc0bb7e ^
f116818c ^
9dcbec39 ^
1bc0bb7e ^

6c96a437 ^
f116818c ^
3473c63a ^
5109e78f ^
a3f420b6 ^
f116818c ^
40278ae5 ^
f116818c ^
1bc0bb7e ^

f116818c ^
1bc0bb7e ^
6c96a437 ^
f116818c ^

af023b32 ^
2b250717 ^
f116818c ^
1bc0bb7e ^
b24eb476 ^
abc70216 ^
2b250717 ^
f116818c ^
abc70216 ^
4637d58f ^
2b250717 ^
4637d58f ^
1bc0bb7e ^

f116818c ^
1bc0bb7e ^



636837e7 ^



4a943d4e ^
















d135851e ^
9a81d746 ^
87cc473c ^
f116818c ^
9a81d746 ^


4071055a ^
4a943d4e ^















87cc473c ^
4a943d4e ^












7402ce32 ^
fca0ebbe ^
8dacba82 ^

ac0e9db5 ^
4082acd2 ^
8dacba82 ^


6c96a437 ^
8dacba82 ^
4082acd2 ^
8dacba82 ^



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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
                                                                
 















                                       
 















                                       
 
                                             
       
                                        

                                                                
                                                     
                                       
              
                                                          
 
                                                
              
                 




                                                                                                                                        
   
                                     

                                                                        
                                               
                                                                                                         
                                             
                                                                                     
               
                                                             
 
 
                                                           

                      
                                                                       
       
                                                                 
                                        
                                                                                                          
                                                  


                                                               
                                                             
                                                                     
                                                    

                                                          
                                    
                                                                              
                                                                                                       

              
                                                                     
                                                            
                                                                
                                          
                                         
                                                                                                                                                                        
                                                                                                       
                                   

         
                                                                              
                                                                
                                                                     

                                                                                           
                                   
                                                                                                                                                                   
                                     
           
                                                        
                                                                         
                                                                                                                                  
                                     
           
                                                                                                                                                                                                                                       
                                                                                                                                                                                                                                                                                     
           

         
                           



     



                                     
















                                                                          
 
                                                                     
                                                                            
                                                                        


                                                                      
 















                                                                                         
 












                                                                          
 
                                            

                              
                      
                                   


                     
                                        
                           
                                   



                   
//: Calls can also generate products, using 'reply' or 'return'.

void test_return() {
  run(
      "def main [\n"
      "  1:num, 2:num <- f 34\n"
      "]\n"
      "def f [\n"
      "  12:num <- next-ingredient\n"
      "  13:num <- add 1, 12:num\n"
      "  return 12:num, 13:num\n"
      "]\n"
  );
  CHECK_TRACE_CONTENTS(
      "mem: storing 34 in location 1\n"
      "mem: storing 35 in location 2\n"
  );
}

void test_reply() {
  run(
      "def main [\n"
      "  1:num, 2:num <- f 34\n"
      "]\n"
      "def f [\n"
      "  12:num <- next-ingredient\n"
      "  13:num <- add 1, 12:num\n"
      "  reply 12:num, 13:num\n"
      "]\n"
  );
  CHECK_TRACE_CONTENTS(
      "mem: storing 34 in location 1\n"
      "mem: storing 35 in location 2\n"
  );
}

:(before "End Primitive Recipe Declarations")
RETURN,
:(before "End Primitive Recipe Numbers")
put(Recipe_ordinal, "return", RETURN);
put(Recipe_ordinal, "reply", RETURN);  // synonym while teaching
put(Recipe_ordinal, "output", RETURN);  // experiment
:(before "End Primitive Recipe Checks")
case RETURN: {
  break;  // checks will be performed by a transform below
}
:(before "End Primitive Recipe Implementations")
case RETURN: {
  // Begin Return
  trace(Callstack_depth+1, "trace") << current_instruction().name << ": decrementing callstack depth from " << Callstack_depth << end();
  --Callstack_depth;
  if (Callstack_depth < 0) {
    Current_routine->calls.clear();
    goto stop_running_current_routine;
  }
  Current_routine->calls.pop_front();
  // just in case 'main' returns a value, drop it for now
  if (Current_routine->calls.empty()) goto stop_running_current_routine;
  for (int i = 0;  i < SIZE(ingredients);  ++i)
    trace(Callstack_depth+1, "run") << "result " << i << " is " << to_string(ingredients.at(i)) << end();
  // make return products available to caller
  copy(ingredients.begin(), ingredients.end(), inserter(products, products.begin()));
  // End Return
  break;  // continue to process rest of *caller* instruction
}

//: Types in return instructions are checked ahead of time.

:(before "End Checks")
Transform.push_back(check_types_of_return_instructions);  // idempotent
:(code)
void check_types_of_return_instructions(const recipe_ordinal r) {
  const recipe& caller = get(Recipe, r);
  trace(9991, "transform") << "--- check types of return instructions in recipe " << caller.name << end();
  for (int i = 0;  i < SIZE(caller.steps);  ++i) {
    const instruction& caller_instruction = caller.steps.at(i);
    if (caller_instruction.is_label) continue;
    if (caller_instruction.products.empty()) continue;
    if (is_primitive(caller_instruction.operation)) continue;
    const recipe& callee = get(Recipe, caller_instruction.operation);
    for (int i = 0;  i < SIZE(callee.steps);  ++i) {
      const instruction& return_inst = callee.steps.at(i);
      if (return_inst.operation != RETURN) continue;
      // check types with the caller
      if (SIZE(caller_instruction.products) > SIZE(return_inst.ingredients)) {
        raise << maybe(caller.name) << "too few values returned from " << callee.name << '\n' << end();
        break;
      }
      for (int i = 0;  i < SIZE(caller_instruction.products);  ++i) {
        reagent/*copy*/ lhs = return_inst.ingredients.at(i);
        reagent/*copy*/ rhs = caller_instruction.products.at(i);
        // End Check RETURN Copy(lhs, rhs)
        if (!types_coercible(rhs, lhs)) {
          raise << maybe(callee.name) << return_inst.name << " ingredient '" << lhs.original_string << "' can't be saved in '" << rhs.original_string << "'\n" << end();
          raise << "  ['" << to_string(lhs.type) << "' vs '" << to_string(rhs.type) << "']\n" << end();
          goto finish_return_check;
        }
      }
      // check that any return ingredients with /same-as-ingredient connect up
      // the corresponding ingredient and product in the caller.
      for (int i = 0;  i < SIZE(caller_instruction.products);  ++i) {
        if (has_property(return_inst.ingredients.at(i), "same-as-ingredient")) {
          string_tree* tmp = property(return_inst.ingredients.at(i), "same-as-ingredient");
          if (!tmp || !tmp->atom) {
            raise << maybe(caller.name) << "'same-as-ingredient' metadata should take exactly one value in '" << to_original_string(return_inst) << "'\n" << end();
            goto finish_return_check;
          }
          int ingredient_index = to_integer(tmp->value);
          if (ingredient_index >= SIZE(caller_instruction.ingredients)) {
            raise << maybe(caller.name) << "too few ingredients in '" << to_original_string(caller_instruction) << "'\n" << end();
            goto finish_return_check;
          }
          if (!is_dummy(caller_instruction.products.at(i)) && !is_literal(caller_instruction.ingredients.at(ingredient_index)) && caller_instruction.products.at(i).name != caller_instruction.ingredients.at(ingredient_index).name) {
            raise << maybe(caller.name) << "'" << to_original_string(caller_instruction) << "' should write to '" << caller_instruction.ingredients.at(ingredient_index).original_string << "' rather than '" << caller_instruction.products.at(i).original_string << "'\n" << end();
          }
        }
      }
      finish_return_check:;
    }
  }
}

bool is_primitive(recipe_ordinal r) {
  return r < MAX_PRIMITIVE_RECIPES;
}

void test_return_type_mismatch() {
  Hide_errors = true;
  run(
      "def main [\n"
      "  3:num <- f 2\n"
      "]\n"
      "def f [\n"
      "  12:num <- next-ingredient\n"
      "  13:num <- copy 35\n"
      "  14:point <- copy 12:point/raw\n"
      "  return 14:point\n"
      "]\n"
  );
  CHECK_TRACE_CONTENTS(
      "error: f: return ingredient '14:point' can't be saved in '3:num'\n"
  );
}

//: In Mu we'd like to assume that any instruction doesn't modify its
//: ingredients unless they're also products. The /same-as-ingredient inside
//: the recipe's 'return' indicates that an ingredient is intended to be
//: modified in place, and will help catch accidental misuse of such
//: 'ingredient-products' (sometimes called in-out parameters in other
//: languages).

void test_return_same_as_ingredient() {
  Hide_errors = true;
  run(
      "def main [\n"
      "  1:num <- copy 0\n"
      "  2:num <- test1 1:num  # call with different ingredient and product\n"
      "]\n"
      "def test1 [\n"
      "  10:num <- next-ingredient\n"
      "  return 10:num/same-as-ingredient:0\n"
      "]\n"
  );
  CHECK_TRACE_CONTENTS(
      "error: main: '2:num <- test1 1:num' should write to '1:num' rather than '2:num'\n"
  );
}

void test_return_same_as_ingredient_dummy() {
  run(
      "def main [\n"
      "  1:num <- copy 0\n"
      "  _ <- test1 1:num  # call with different ingredient and product\n"
      "]\n"
      "def test1 [\n"
      "  10:num <- next-ingredient\n"
      "  return 10:num/same-as-ingredient:0\n"
      "]\n"
  );
  CHECK_TRACE_COUNT("error", 0);
}

string to_string(const vector<double>& in) {
  if (in.empty()) return "[]";
  ostringstream out;
  if (SIZE(in) == 1) {
    out << no_scientific(in.at(0));
    return out.str();
  }
  out << "[";
  for (int i = 0;  i < SIZE(in);  ++i) {
    if (i > 0) out << ", ";
    out << no_scientific(in.at(i));
  }
  out << "]";
  return out.str();
}