~ubuntu-branches/ubuntu/hardy/texmacs/hardy

« back to all changes in this revision

Viewing changes to src/Resource/Languages/math_language.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Ralf Treinen
  • Date: 2004-04-19 20:34:00 UTC
  • Revision ID: james.westby@ubuntu.com-20040419203400-g4e34ih0315wcn8v
Tags: upstream-1.0.3-R2
ImportĀ upstreamĀ versionĀ 1.0.3-R2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
/******************************************************************************
 
3
* MODULE     : math_language.cpp
 
4
* DESCRIPTION: mathematical languages
 
5
* COPYRIGHT  : (C) 1999  Joris van der Hoeven
 
6
*******************************************************************************
 
7
* This software falls under the GNU general public license and comes WITHOUT
 
8
* ANY WARRANTY WHATSOEVER. See the file $TEXMACS_PATH/LICENSE for more details.
 
9
* If you don't have this file, write to the Free Software Foundation, Inc.,
 
10
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
11
******************************************************************************/
 
12
 
 
13
#include "language.hpp"
 
14
#include "analyze.hpp"
 
15
#include "Languages/hyphenate.hpp"
 
16
#include "Languages/impl_language.hpp"
 
17
#include "file.hpp"
 
18
 
 
19
/******************************************************************************
 
20
* Mathematical languages
 
21
******************************************************************************/
 
22
 
 
23
struct math_language_rep: language_rep {
 
24
  hashmap<string,text_property_rep> tpr_class;
 
25
  hashmap<string,text_property_rep> tpr_member;
 
26
  string class_name;            // current type name
 
27
  bool   class_def;             // in class definition phase
 
28
 
 
29
  math_language_rep (string name, string s);
 
30
  string get_string (string s, int& i);
 
31
  void get_class (string s, int& i);
 
32
  void get_members (string s, int& i);
 
33
  void get_type (string s, int& i);
 
34
  void get_precedence (string s, int& i);
 
35
  void get_lpenalty (string s, int& i);
 
36
  void get_rpenalty (string s, int& i);
 
37
  void get_spacing (string s, int& i);
 
38
  void get_limits (string s, int& i);
 
39
 
 
40
  void skip_spaces (string s, int& pos, space fn_spc, space& spc);
 
41
  string next_word (string s, int& pos);
 
42
  text_property advance (string s, int& pos);
 
43
  array<int> get_hyphens (string s);
 
44
  void hyphenate (string s, int after, string& left, string& right);
 
45
};
 
46
 
 
47
/******************************************************************************
 
48
* Load a mathematical language
 
49
******************************************************************************/
 
50
 
 
51
string
 
52
math_language_rep::get_string (string s, int& i) {
 
53
  while ((i<N(s)) && (s[i]!=' ') && (s[i]!='\t') && (s[i]!='\n')) i++;
 
54
  while ((i<N(s)) && ((s[i]==' ') || (s[i]=='\t') || (s[i]=='='))) i++;
 
55
  int start= i;
 
56
  while ((i<N(s)) && (s[i]!='\n')) i++;
 
57
  int end= i;
 
58
  while ((end>start) && ((s[end-1]==' ') || (s[end-1]=='\t'))) end--;
 
59
  // cout << "String= " << s (start, end) << "\n";
 
60
  return s (start, end);
 
61
}
 
62
 
 
63
void
 
64
math_language_rep::get_class (string s, int& i) {
 
65
  class_name= get_string (s, i);
 
66
  class_def = true;
 
67
}
 
68
 
 
69
void
 
70
math_language_rep::get_members (string s, int& i) {
 
71
  class_name= get_string (s, i);
 
72
  class_def = false;
 
73
  // cout << "Members " << class_name << "\n";
 
74
}
 
75
 
 
76
void
 
77
math_language_rep::get_type (string s, int& i) {
 
78
  if (class_def) {
 
79
    string r= get_string (s, i);
 
80
    int &ot= tpr_class(class_name).op_type;
 
81
    if (r == "Symbol") ot= OP_SYMBOL;
 
82
    else if (r == "Prefix") ot= OP_PREFIX;
 
83
    else if (r == "Postfix") ot= OP_POSTFIX;
 
84
    else if (r == "Infix") ot= OP_INFIX;
 
85
    else if (r == "Left Associative Infix") ot= OP_LEFT_ASS_INFIX;
 
86
    else if (r == "Right Associative Infix") ot= OP_RIGHT_ASS_INFIX;
 
87
    else if (r == "Associative Infix") ot= OP_ASS_INFIX;
 
88
    else if (r == "Opening Bracket") ot= OP_OPENING_BRACKET;
 
89
    else if (r == "Separator") ot= OP_SEPARATOR;
 
90
    else if (r == "Closing Bracket") ot= OP_CLOSING_BRACKET;
 
91
    else {
 
92
      cerr << "Attempt to associate type " << r
 
93
           << " to " << class_name << "\n";
 
94
      fatal_error ("Unknown type", "math_language_rep::get_type");
 
95
    }
 
96
  }
 
97
  else fatal_error ("Type declaration outside class definition",
 
98
                    "math_language_rep::get_type");
 
99
}
 
100
 
 
101
void
 
102
math_language_rep::get_precedence (string s, int& i) {
 
103
  if (class_def) tpr_class(class_name).priority= as_int (get_string (s, i));
 
104
  else fatal_error ("Precedence declaration outside class definition",
 
105
                    "math_language_rep::get_precedence");
 
106
}
 
107
 
 
108
void
 
109
math_language_rep::get_lpenalty (string s, int& i) {
 
110
  if (class_def) {
 
111
    string r= get_string (s, i);
 
112
    if (r == "Panic")   tpr_class(class_name).pen_before= HYPH_PANIC;
 
113
    if (r == "Invalid") tpr_class(class_name).pen_before= HYPH_INVALID;
 
114
    else tpr_class(class_name).pen_before= as_int (r);
 
115
  }
 
116
  else fatal_error ("Left Penalty declaration outside class definition",
 
117
                    "math_language_rep::get_lpenalty");
 
118
}
 
119
 
 
120
void
 
121
math_language_rep::get_rpenalty (string s, int& i) {
 
122
  if (class_def) {
 
123
    string r= get_string (s, i);
 
124
    if (r == "Panic") tpr_class(class_name).pen_after= HYPH_PANIC;
 
125
    if (r == "Invalid") tpr_class(class_name).pen_after= HYPH_INVALID;
 
126
    else tpr_class(class_name).pen_after= as_int (r);
 
127
  }
 
128
  else fatal_error ("Right Penalty declaration outside class definition",
 
129
                    "math_language_rep::get_rpenalty");
 
130
}
 
131
 
 
132
void
 
133
math_language_rep::get_spacing (string s, int& i) {
 
134
  if (class_def) {
 
135
    int j;
 
136
    string both= get_string (s, i);
 
137
    for (j=0; j<N(both); j++)
 
138
      if (both[j]==',') {
 
139
        string l= both (0, j);
 
140
        string r= both (j+1, N(both));
 
141
        while ((N(l)>0) && ((l[N(l)-1] == ' ') || (l[N(l)-1] == '\t')))
 
142
          l= l(0, N(l)-1);
 
143
        while ((N(r)>0) && ((r[0]==' ') || (r[0]=='\t'))) r= r(1, N(r));
 
144
        if (l == "None")
 
145
          tpr_class(class_name).spc_before= SPC_NONE;
 
146
        else if (l == "Default")
 
147
          tpr_class(class_name).spc_before= SPC_OPERATOR;
 
148
        else if (l == "Big")
 
149
          tpr_class(class_name).spc_before= SPC_BIGOP;
 
150
        else {
 
151
          cerr << "Attempt to associate space " << l
 
152
               << " to " << class_name << "\n";
 
153
          fatal_error ("Unknown space", "math_language_rep::get_type");
 
154
        }
 
155
        if (r == "None")
 
156
          tpr_class(class_name).spc_after= SPC_NONE;
 
157
        else if (r == "Default")
 
158
          tpr_class(class_name).spc_after= SPC_OPERATOR;
 
159
        else if (r == "Big")
 
160
          tpr_class(class_name).spc_after= SPC_BIGOP;
 
161
        else {
 
162
          cerr << "Attempt to associate space " << r
 
163
               << " to " << class_name << "\n";
 
164
          fatal_error ("Unknown space", "math_language_rep::get_type");
 
165
        }
 
166
        return;
 
167
      }
 
168
    fatal_error ("Missing comma in Spacing declaration",
 
169
                 "math_language_rep::get_spacing");
 
170
  }
 
171
  else fatal_error ("Spacing declaration outside class definition",
 
172
                    "math_language_rep::get_spacing");
 
173
}
 
174
 
 
175
void
 
176
math_language_rep::get_limits (string s, int& i) {
 
177
  if (class_def) {
 
178
    string l= get_string (s, i);
 
179
    if (l == "Display") tpr_class(class_name).limits= LIMITS_DISPLAY;
 
180
    else if (l == "Always") tpr_class(class_name).limits= LIMITS_ALWAYS;
 
181
    else tpr_class(class_name).limits= LIMITS_NONE;
 
182
  }
 
183
  else fatal_error ("Limits declaration outside class definition",
 
184
                    "math_language_rep::get_limits");
 
185
}
 
186
 
 
187
math_language_rep::math_language_rep (string name, string s):
 
188
  language_rep (name, math_enc),
 
189
  tpr_class (text_property_rep ()),
 
190
  tpr_member (text_property_rep ()),
 
191
  class_name ("symbol"), class_def (true)
 
192
{
 
193
  language::instances (name)= (pointer) this;
 
194
  tpr_class("symbol").op_type = OP_SYMBOL;
 
195
  tpr_class("symbol").priority= 1000;
 
196
 
 
197
  int i;
 
198
  for (i=0; i<N(s); i++) {
 
199
    while ((i<N(s)) && ((s[i]==' ') || (s[i]=='\t'))) i++;
 
200
    if ((i+5<N(s)) && (s(i,i+5)=="Class")) get_class (s, i);
 
201
    else if ((i+7<N(s)) && (s(i,i+7)=="Members")) get_members (s, i);
 
202
    else if ((i+4<N(s)) && (s(i,i+4)=="Type")) get_type (s, i);
 
203
    else if ((i+10<N(s)) && (s(i,i+10)=="Precedence")) get_precedence (s, i);
 
204
    else if ((i+12<N(s)) && (s(i,i+12)=="Left-Penalty")) get_lpenalty (s, i);
 
205
    else if ((i+7<N(s)) && (s(i,i+7)=="Penalty")) get_rpenalty (s, i);
 
206
    else if ((i+13<N(s)) && (s(i,i+13)=="Right-Penalty")) get_rpenalty (s, i);
 
207
    else if ((i+7<N(s)) && (s(i,i+7)=="Spacing")) get_spacing (s, i);
 
208
    else if ((i+6<N(s)) && (s(i,i+6)=="Limits")) get_limits (s, i);
 
209
    else if ((i+2<N(s)) && (s(i,i+2)=="##")) (void) get_string (s, i);
 
210
    else {
 
211
      while ((i<N(s)) && (s[i]!='\n')) {
 
212
        while ((i<N(s)) && ((s[i]==' ') || (s[i]=='\t'))) i++;
 
213
        int start= i;
 
214
        while ((i<N(s)) && (s[i]!=' ') && (s[i]!='\t') && (s[i]!='\n')) i++;
 
215
        string symbol= s (start, i);
 
216
        if ((N(symbol)>1) &&
 
217
            (class_def || (class_name != "operator-with-limits")))
 
218
          symbol= "<" * symbol * ">";
 
219
        // cout << "  Member: " << symbol << "\n";
 
220
        if ((!class_def) && (tpr_class->contains (class_name)))
 
221
          tpr_member (symbol)= tpr_class [class_name];
 
222
        else {
 
223
          cerr << "Attempt to insert " << symbol
 
224
               << " to class " << class_name << "\n";
 
225
          if (class_def)
 
226
            fatal_error ("Member declaration inside class definition",
 
227
                         "math_language_rep::get_members");
 
228
          else
 
229
            fatal_error ("Unknown class",
 
230
                         "math_language_rep::get_members");
 
231
        }
 
232
      }
 
233
    }
 
234
  }
 
235
}
 
236
 
 
237
/******************************************************************************
 
238
* Advancing a word
 
239
******************************************************************************/
 
240
 
 
241
string
 
242
math_language_rep::next_word (string s, int& pos) {
 
243
  int start= pos;
 
244
 
 
245
  if (pos>=N(s)) return string ("");
 
246
 
 
247
  if ((s[pos]>='0') && (s[pos]<='9')) {
 
248
    while ((pos<N(s)) && is_numeric (s[pos])) pos++;
 
249
    while (s[pos-1]=='.') pos--;
 
250
    return s (start, pos);
 
251
  }
 
252
 
 
253
  if (is_alpha (s[pos])) {
 
254
    while ((pos<N(s)) && (is_alpha (s[pos]))) pos++;
 
255
    return s (start, pos);
 
256
  }
 
257
 
 
258
  if (s[pos]=='<') {
 
259
    while ((pos<N(s)) && (s[pos]!='>')) pos++;
 
260
    if (pos<N(s)) pos++;
 
261
    return s (start, pos);
 
262
  }
 
263
 
 
264
  pos++;
 
265
  return s (start, pos);
 
266
}
 
267
 
 
268
text_property
 
269
math_language_rep::advance (string s, int& pos) {
 
270
  bool op_flag1=
 
271
    (pos==0) ||
 
272
    ((pos>=2) && is_alpha (s[pos-2]) && is_alpha (s[pos-1]));
 
273
  string r= next_word (s, pos);
 
274
  if (r == " ") {
 
275
    bool op_flag2=
 
276
      (pos==N(s)) ||
 
277
      (((pos+2)<N(s)) && is_alpha (s[pos]) && is_alpha (s[pos+1]));
 
278
    if (op_flag1 || op_flag2) return &tp_operator_rep;
 
279
    else return &tp_shortop_rep;
 
280
  }
 
281
  return &tpr_member(r);
 
282
 
 
283
  /****************************** variant *******************************
 
284
  string r= next_word (s, pos);
 
285
  if (r == " ") return &tp_operator_rep;
 
286
  else return &tpr_member(r);
 
287
  **********************************************************************/
 
288
}
 
289
 
 
290
/******************************************************************************
 
291
* Hyphenation
 
292
******************************************************************************/
 
293
 
 
294
array<int>
 
295
math_language_rep::get_hyphens (string s) {
 
296
  if (N(s)==0)
 
297
    fatal_error ("hyphenation of empty string",
 
298
                 "math_language_rep::get_hyphens");
 
299
 
 
300
  int i, n= N(s)-1;
 
301
  bool flag= is_numeric (s);
 
302
  array<int> penalty (n);
 
303
  for (i=0; i<n; i++) penalty[i]= (flag? HYPH_PANIC: HYPH_INVALID);
 
304
  if (n>0) penalty[0]= penalty[n-1]= HYPH_INVALID;
 
305
  if (n>2) penalty[1]= penalty[n-2]= HYPH_INVALID;
 
306
  if (n>4) penalty[2]= penalty[n-3]= HYPH_INVALID;
 
307
  return penalty;
 
308
}
 
309
 
 
310
void
 
311
math_language_rep::hyphenate (string s, int after, string& left, string& right)
 
312
{
 
313
  left = s (0, after+1) * string ("\\");
 
314
  right= s (after+1, N(s));
 
315
}
 
316
 
 
317
/******************************************************************************
 
318
* Interface
 
319
******************************************************************************/
 
320
 
 
321
language
 
322
math_language (string name) {
 
323
  if (language::instances -> contains (name)) return language (name);
 
324
  string s, fname= name * ".syx";
 
325
  if (DEBUG_AUTO) cout << "TeXmacs] Loading " << fname << "\n";
 
326
  load_string (url ("$TEXMACS_SYNTAX_PATH", fname), s, true);
 
327
  return new math_language_rep (name, s);
 
328
}