ALDT (Arnulf's LaTeX Documentation Tool)

Check-in [4954d337f3]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:initial version
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:4954d337f39b5b684541c89446528617f5b2321f
User & Date: arnulf 2012-08-26 18:25:13
Context
2012-08-26
19:29
fixes and new code check-in: eaea8012cb user: arnulf tags: trunk
18:25
initial version check-in: 4954d337f3 user: arnulf tags: trunk
14:48
initial version check-in: 18a41385d9 user: arnulf tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Added IntObjType.tcl.











































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
#=====================================================
# IntObjType.tcl 
# *
# * ALDT (Arnulf's Latex Documentation Tool)
# * A Tcl parser for LaTeX files for generating document output (for example html)
# *
# * Obj type for handling integers
# *
# * Released under same BSD license as Tcl.
# * (Tcl BSD license found at <http://www.tcl.tk/software/tcltk/license.html>)
# *
# * Copyright 2012 Arnulf P. Wiedemann
#=====================================================

namespace eval ::Parser {

::itcl::class IntObjType {
  private common oid 0

  public variable id

  constructor {} {}
  public method mySelf {}
  public method toString {}
  public method toDebugString {}
  public method setFromAny {obj_ptr flags}
  public method updateString {obj_ptr}
  public method newIntObj {val}
  public method getBool {obj_ptr bool_ptr}
}

  # ==================== constructor ==================================
::itcl::body IntObjType::constructor {} {
    incr oid
    set id $oid
  }

  # ==================== mySelf ==================================
::itcl::body IntObjType::mySelf {} {
    set str "IntObjType!$id!"
    return $str;
  } 
      
  # ==================== toString =====================================
::itcl::body IntObjType::toString {} {
    return "[mySelf]!"
  }

  # ==================== toDebugString ===================================== 
::itcl::body IntObjType::toDebugString {} {
    set str "[mySelf]\n"
    return $str
  }

  # ==================== setFromAny ==================================
::itcl::body IntObjType::setFromAny {obj_ptr flags} {

    if {[$obj_ptr getObjType] > 0 && [$obj_ptr getObjType] == [::Interp::string2ObjType OBJ_TYPE_COERCED_DOUBLE]} {
      # Simple switcheroo 
      $obj_ptr setObjType [::Interp::string2ObjType OBJ_TYPE_INT]
      return true
    }

    /* Get the string representation */
    str = obj_ptr.getString();
    /* Try to convert into a wide */
    if (stringToWide(str, wide_value, 0) != OK) {
      if ((flags & FUNCTION_FLAGS_LEAVE_ERR_MSG) != 0) {
        interp.setResultFormatted("expected integer but got \"%#s\"", obj_ptr);
      }
      return ERROR;
    }
    // FIXME!!! have to find out how to determine WIDE_MIN and WIDE_MAX values!!!
//    if ((wideValue == WIDE_MIN || wideValue == WIDE_MAX) && errno == ERANGE) {
//      int_obj.interp.setResultString("Integer value too big to be represented", -1);
//      return int_obj.ERROR;
//    }
    /* Free the old internal repr and set the new one. */
    obj_ptr.freeIntRep();
    obj_ptr.obj_type = OBJ_TYPE_INT;
    obj_ptr.wideValue_SetValue(wide_value.get(0));
    return OK;
  }

  # ==================== updateString =====================================
::itcl::body IntObjType::updateString {obj_ptr} {
    set str [list]
    set len [list]

    set ret_code = wideToString(obj_ptr.wideValue_GetValue(), str, len);
    if (obj_ptr.bytes == null) {
      obj_ptr.bytes = new StringBuffer();  
    }
    obj_ptr.bytes.append(str.get(0));
    obj_ptr.len = len.get(0);
    return ret_code;
  }

  # ==================== newIntObj ==================================
::itcl::body IntObjType::newIntObj {val} {
    set obj_ptr [$::Interp::default_obj newObj]
    $obj_ptr setObjType [::Interp::string2ObjType OBJ_TYPE_INT]
    $obj_ptr setLen 0
    $obj_ptr setBytes ""
    $obj_ptr wideValue_SetValue $val
    return obj_ptr;
  }

if {0} {
  /* ==================== wideToString ===================================== */
::itcl::body IntObjType::  public int wideToString(long wide_value, ArrayList<String> str_ptr, ArrayList<Integer> len_ptr) {
    String str = String.valueOf(wide_value);

    str_ptr.add(str);
    len_ptr.add(str.length());
    return OK;
  }

  /* ==================== stringToWide ================================== */
::itcl::body IntObjType::  public long stringToWide(String val, ArrayList<Long> result, int flags) {
	try {
      result.add(Long.parseLong(val));
	} catch(Exception e) {
	  return ERROR;
	}
    return checkConversion(Long.parseLong(val), result.get(0));
  }

  /* ==================== wideValue ================================== */
  public long wideValue(ApwtclObj obj_ptr) {
    return obj_ptr.wideValue_GetValue();
  }

  /* ==================== getWide ================================== */
::itcl::body IntObjType::  public int getWide(ApwtclObj obj_ptr, ArrayList<Long> wide_ptr) {
    if ((obj_ptr.obj_type != OBJ_TYPE_INT) && (setFromAny(obj_ptr, FUNCTION_FLAGS_LEAVE_ERR_MSG) == ERROR)) {
      return ERROR;
    }
    wide_ptr.add(wideValue(obj_ptr));
    return OK;
  }

  /* ==================== getWideNoErr ================================== */
::itcl::body IntObjType::  public int getWideNoErr(ApwtclObj obj_ptr, ArrayList<Long> wide_ptr) {
    if ((obj_ptr.obj_type != OBJ_TYPE_INT) && (setFromAny(obj_ptr, FUNCTION_FLAGS_NONE) == ERROR)) {
      return ERROR;
    }
    wide_ptr.add(obj_ptr.wideValue_GetValue());
    return OK;
  }

  /* ==================== isWide ================================== */
::itcl::body IntObjType::  public boolean isWide(ApwtclObj obj_ptr) {
    return obj_ptr.obj_type == OBJ_TYPE_INT;
  }
}

  # ==================== getBool ==================================
::itcl::body IntObjType::getBool {obj_ptr bool_ptr} {
    ArrayList<Long> wide_value = new ArrayList<Long>();
    ArrayList<Double> double_value = new ArrayList<Double>();
    
    if (getWideNoErr(obj_ptr, wide_value) != OK) {
      if (getDouble(obj_ptr, double_value) != OK) {
        return ERROR;
      } else {
        bool_ptr.add(double_value.get(0) != 0);
	return OK;
      }
    }
    bool_ptr.add(wide_value.get(0) != 0);
    return OK;
  }

if {0} {
  /* ==================== checkConversion ================================== */
  /*
   * After an strtol()/strtod()-like conversion,
   * check whether something was converted and that
   * the only thing left is white space.
   *
   * Returns int_obj.OK or int_obj.ERROR.
   */
::itcl::body IntObjType::  public int checkConversion(long val, long result_val) {
    // FIXME!! need check code here
    if (val != result_val) {
      return ERROR;
    }
    return OK;
  }

  /* ==================== getLong ================================== */
::itcl::body IntObjType::  public int getLong(ApwtclObj obj_ptr, ArrayList<Long> long_ptr) {
    ArrayList<Long> wide_value = new ArrayList<Long>();
    int retval;

    retval = getWide(obj_ptr, wide_value);
    if (retval == OK) {
       long_ptr.add(wide_value.get(0));
       return OK;
    }
    return ERROR;
  }

  /* ==================== setDoubleFromAny ================================== */
::itcl::body IntObjType::  public int setDoubleFromAny(ApwtclObj obj_ptr) {
    ArrayList<Double> double_value = new ArrayList<Double>();
    ArrayList<Long> wide_value = new ArrayList<Long>();
    String str;

    /* Preserve the string representation.
     * Needed so we can convert back to int without loss
     */
    str = obj_ptr.getString();

    long MIN_INT_IN_DOUBLE = -(1 << 53);
    long MAX_INT_IN_DOUBLE = -(MIN_INT_IN_DOUBLE + 1);

    if (obj_ptr.obj_type == OBJ_TYPE_INT
        && obj_ptr.wideValue_GetValue() >= MIN_INT_IN_DOUBLE
        && obj_ptr.wideValue_GetValue() <= MAX_INT_IN_DOUBLE) {
      /* Direct conversion to coerced double */
      obj_ptr.obj_type = OBJ_TYPE_COERCED_DOUBLE;
      return OK;
    } else {
      if (interp.string_obj_type.stringToWide(str, wide_value) == OK) {
        /* Managed to convert to an int, so we can use this as a cooerced double */
        obj_ptr.freeIntRep();
        obj_ptr.obj_type = OBJ_TYPE_COERCED_DOUBLE;
        obj_ptr.wideValue_SetValue(wide_value.get(0));
        return OK;
      } else {
        /* Try to convert into a double */
        if (interp.string_obj_type.stringToDouble(str, double_value) != OK) {
          interp.setResultFormatted("expected number but got \"%#s\"", obj_ptr);
          return ERROR;
        }
        /* Free the old internal repr and set the new one. */
        obj_ptr.freeIntRep();
      }
    }
    obj_ptr.obj_type = OBJ_TYPE_DOUBLE;
    obj_ptr.doubleValue_SetValue(double_value.get(0));
    return OK;
  }

  /* ==================== getDouble ================================== */
::itcl::body IntObjType::  public int getDouble(ApwtclObj obj_ptr, ArrayList<Double> double_ptr) {
    if (obj_ptr.obj_type == OBJ_TYPE_COERCED_DOUBLE) {
      double_ptr.add((double)obj_ptr.wideValue_GetValue());
      return OK;
    }
    if ((obj_ptr.obj_type != OBJ_TYPE_DOUBLE) && (setDoubleFromAny(obj_ptr) == ERROR)) { 
      return ERROR;
    }
    if (obj_ptr.obj_type == OBJ_TYPE_COERCED_DOUBLE) {
      double_ptr.add((double)obj_ptr.wideValue_GetValue());
    } else {
      double_ptr.add(obj_ptr.doubleValue_GetValue());
    }
    return OK;
  }

  /* ==================== newDouble ================================== */
::itcl::body IntObjType::  public ApwtclObj newDouble(double double_value) {
    ApwtclObj obj_ptr;

    obj_ptr = interp.default_obj.newObj();
    obj_ptr.obj_type = OBJ_TYPE_DOUBLE;
    obj_ptr.bytes = null;
    obj_ptr.doubleValue_SetValue(double_value);
    return obj_ptr;
  }
}

}