-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.rl
More file actions
126 lines (108 loc) · 3.97 KB
/
main.rl
File metadata and controls
126 lines (108 loc) · 3.97 KB
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
%%{
machine format;
}%%
#include "vm/config.h"
#include "vm.hpp"
#include "object_utils.hpp"
#include "on_stack.hpp"
#include "builtin/array.hpp"
#include "builtin/exception.hpp"
#include "builtin/float.hpp"
#include "builtin/module.hpp"
#include "builtin/object.hpp"
#include "builtin/string.hpp"
#include <sstream>
namespace rubinius {
#define SPACE_FLAG 1
#define POSITION_FLAG 2
#define ALTERNATIVE_FLAG 4
#define PLUS_FLAG 8
#define MINUS_FLAG 16
#define ZERO_FLAG 32
#define STAR_FLAG 64
#define WIDTH_FLAG 128
#define WIDTH_ARG_FLAG 256
#define PRECISION_FLAG 512
#define PRECISION_ARG_FLAG 1024
#define PRECISION_STAR_FLAG 2048
#define WIDTH_EXISTS_FLAG (WIDTH_FLAG | WIDTH_ARG_FLAG | STAR_FLAG)
#define PRECISION_EXISTS_FLAG (PRECISION_ARG_FLAG | PRECISION_STAR_FLAG | PRECISION_FLAG)
#define BITS_LONG (RBX_SIZEOF_LONG * 8)
#define CONVERT_INTEGER(T, v, m, b, n) \
if((n)->fixnum_p()) { \
v = (T)STRIP_FIXNUM_TAG(n); \
} else { \
Bignum* big = as<Bignum>(n); \
big->verify_size(state, b); \
v = big->m(); \
}
#define CONVERT_TO_INT(n) CONVERT_INTEGER(int, int_value, to_int, BITS_LONG, n)
#define retrieve_arg(var) \
if (arg_position >= args->size()) { \
Exception::argument_error(state, "you ran out of arguments"); \
} else { \
var = args->get(state, arg_position++); \
} \
#define retrieve_width(var) \
flag = true; \
if (flags & WIDTH_FLAG) { \
int_value = width; \
flag = false; \
} else { \
if (flags & WIDTH_ARG_FLAG) { \
var = args->get(state, position); \
} else { \
retrieve_arg(var); \
} \
} \
if(flag) { \
CONVERT_TO_INT(var); \
if(int_value < 0) { \
int_value = -int_value; \
flags |= MINUS_FLAG; \
} \
} \
#define retrieve_precision(var) \
flag = (flags & PRECISION_FLAG) == 0; \
if(flags & PRECISION_ARG_FLAG) { \
var = args->get(state, precision); \
} else { \
if (flag) { \
retrieve_arg(var); \
} else { \
int_value = precision; \
} \
} \
if(flag) { \
CONVERT_TO_INT(var); \
} \
String* String::format(STATE, Array* args) {
bool flag = false;
bool width_present = false;
bool precision_present = false;
int flags = 0;
int width = 0;
int prec = 0;
int type = 0;
int star_num = 0;
int position = 0;
int precision = 0;
int int_value = 0;
unsigned arg_position = 0;
Object* arg, *tmp = NULL;
std::stringstream ss;
std::string str("");
// Ragel-specific variables
const char *p = c_str();
const char *pe = p + size();
const char *eof = pe;
int cs;
%%{
include "format.rl";
}%%
if(format_first_final && format_error && format_en_main){// && format_en_main_fmt_spec_precision) {
// do nothing
}
return force_as<String>(Primitives::failure());
}
}