Skip to content

Commit 8aa9db3

Browse files
authored
INT32 and FLOAT32 (#226)
* Add Int32 and Float32 types * Be explicit about i32 literals
1 parent a1f3461 commit 8aa9db3

43 files changed

Lines changed: 12418 additions & 11492 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

meta/src/meta/codegen_go.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,9 @@ def none_generator(
194194
# Map terminal names to Go types for type assertion
195195
terminal_field_map = {
196196
"INT": "i64",
197+
"INT32": "i32",
197198
"FLOAT": "f64",
199+
"FLOAT32": "f32",
198200
"STRING": "str",
199201
"SYMBOL": "str",
200202
"DECIMAL": "decimal",
@@ -936,7 +938,9 @@ def format_literal_token_spec(self, escaped_literal: str) -> str:
936938
"SYMBOL": ("scanSymbol", "kindString", "str"),
937939
"STRING": ("scanString", "kindString", "str"),
938940
"INT": ("scanInt", "kindInt64", "i64"),
941+
"INT32": ("scanInt32", "kindInt32", "i32"),
939942
"FLOAT": ("scanFloat", "kindFloat64", "f64"),
943+
"FLOAT32": ("scanFloat32", "kindFloat32", "f32"),
940944
"UINT128": ("scanUint128", "kindUint128", "uint128"),
941945
"INT128": ("scanInt128", "kindInt128", "int128"),
942946
"DECIMAL": ("scanDecimal", "kindDecimal", "decimal"),

meta/src/meta/codegen_templates.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ class BuiltinTemplate:
4343
"length": BuiltinTemplate("len({0})"),
4444
"unwrap_option_or": BuiltinTemplate("({0} if {0} is not None else {1})"),
4545
"int64_to_int32": BuiltinTemplate("int({0})"),
46+
"float64_to_float32": BuiltinTemplate("float({0})"),
4647
"to_ptr_int64": BuiltinTemplate("{0}"), # Python doesn't need pointers
4748
"to_ptr_string": BuiltinTemplate("{0}"),
4849
"to_ptr_bool": BuiltinTemplate("{0}"),
@@ -83,7 +84,8 @@ class BuiltinTemplate:
8384
"dedent_io": BuiltinTemplate("None", ["self.dedent()"]),
8485
"try_flat_io": BuiltinTemplate("self._try_flat({0}, {1})"),
8586
"format_int64": BuiltinTemplate("str({0})"),
86-
"format_int32": BuiltinTemplate("str({0})"),
87+
"format_int32": BuiltinTemplate("(str({0}) + 'i32')"),
88+
"format_float32": BuiltinTemplate("(self.format_float32_value({0}) + 'f32')"),
8789
"format_float64": BuiltinTemplate("str({0})"),
8890
"format_string": BuiltinTemplate("self.format_string_value({0})"),
8991
"format_symbol": BuiltinTemplate("{0}"),
@@ -95,6 +97,7 @@ class BuiltinTemplate:
9597
"to_string": BuiltinTemplate("str({0})"),
9698
# Type conversions used by pretty printer
9799
"int32_to_int64": BuiltinTemplate("int({0})"),
100+
"float32_to_float64": BuiltinTemplate("float({0})"),
98101
"is_empty": BuiltinTemplate("len({0}) == 0"),
99102
"decode_string": BuiltinTemplate("{0}.decode('utf-8')"),
100103
"fragment_id_to_string": BuiltinTemplate("self.fragment_id_to_string({0})"),
@@ -137,6 +140,7 @@ class BuiltinTemplate:
137140
"length": BuiltinTemplate("length({0})"),
138141
"unwrap_option_or": BuiltinTemplate("(!isnothing({0}) ? {0} : {1})"),
139142
"int64_to_int32": BuiltinTemplate("Int32({0})"),
143+
"float64_to_float32": BuiltinTemplate("Float32({0})"),
140144
"to_ptr_int64": BuiltinTemplate("{0}"), # Julia doesn't need pointers
141145
"to_ptr_string": BuiltinTemplate("{0}"),
142146
"to_ptr_bool": BuiltinTemplate("{0}"),
@@ -173,7 +177,8 @@ class BuiltinTemplate:
173177
"dedent_io": BuiltinTemplate("nothing", ["dedent!(pp)"]),
174178
"try_flat_io": BuiltinTemplate("try_flat(pp, {0}, {1})"),
175179
"format_int64": BuiltinTemplate("format_int(pp, {0})"),
176-
"format_int32": BuiltinTemplate("format_int(pp, Int64({0}))"),
180+
"format_int32": BuiltinTemplate('(string(Int64({0})) * "i32")'),
181+
"format_float32": BuiltinTemplate('(lowercase(string({0})) * "f32")'),
177182
"format_float64": BuiltinTemplate("format_float(pp, {0})"),
178183
"format_string": BuiltinTemplate("format_string(pp, {0})"),
179184
"format_symbol": BuiltinTemplate("{0}"),
@@ -185,6 +190,7 @@ class BuiltinTemplate:
185190
"to_string": BuiltinTemplate("string({0})"),
186191
# Type conversions used by pretty printer
187192
"int32_to_int64": BuiltinTemplate("Int64({0})"),
193+
"float32_to_float64": BuiltinTemplate("Float64({0})"),
188194
"is_empty": BuiltinTemplate("isempty({0})"),
189195
"decode_string": BuiltinTemplate("String(copy({0}))"),
190196
"fragment_id_to_string": BuiltinTemplate("fragment_id_to_string(pp, {0})"),
@@ -230,6 +236,7 @@ class BuiltinTemplate:
230236
# unwrap_option_or is handled specially in codegen_go.py due to Go's lack of ternary
231237
"unwrap_option_or": BuiltinTemplate("{0}"), # Placeholder - overridden in codegen
232238
"int64_to_int32": BuiltinTemplate("int32({0})"),
239+
"float64_to_float32": BuiltinTemplate("float32({0})"),
233240
"to_ptr_int64": BuiltinTemplate("ptrInt64({0})"),
234241
"to_ptr_string": BuiltinTemplate("ptrString({0})"),
235242
"to_ptr_bool": BuiltinTemplate("ptrBool({0})"),
@@ -265,7 +272,10 @@ class BuiltinTemplate:
265272
"dedent_io": BuiltinTemplate("nil", ["p.dedent()"]),
266273
"try_flat_io": BuiltinTemplate("p.tryFlat({0}, func() {{ {1}({0}) }})"),
267274
"format_int64": BuiltinTemplate('fmt.Sprintf("%d", {0})'),
268-
"format_int32": BuiltinTemplate('fmt.Sprintf("%d", {0})'),
275+
"format_int32": BuiltinTemplate('fmt.Sprintf("%di32", {0})'),
276+
"format_float32": BuiltinTemplate(
277+
"fmt.Sprintf(\"%sf32\", strconv.FormatFloat(float64({0}), 'g', -1, 32))"
278+
),
269279
"format_float64": BuiltinTemplate("formatFloat64({0})"),
270280
"format_string": BuiltinTemplate("p.formatStringValue({0})"),
271281
"format_symbol": BuiltinTemplate("{0}"),
@@ -277,6 +287,7 @@ class BuiltinTemplate:
277287
"to_string": BuiltinTemplate('fmt.Sprintf("%v", {0})'),
278288
# Type conversions used by pretty printer
279289
"int32_to_int64": BuiltinTemplate("int64({0})"),
290+
"float32_to_float64": BuiltinTemplate("float64({0})"),
280291
"is_empty": BuiltinTemplate("len({0}) == 0"),
281292
"decode_string": BuiltinTemplate("string({0})"),
282293
"fragment_id_to_string": BuiltinTemplate("p.fragmentIdToString({0})"),

meta/src/meta/extra_pretty_gen.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
"uint32": BaseType("UInt32"),
4747
"uint64": BaseType("UInt64"),
4848
"fixed64": BaseType("UInt64"),
49-
"float": BaseType("Float64"),
49+
"float": BaseType("Float32"),
5050
"double": BaseType("Float64"),
5151
"bool": BaseType("Boolean"),
5252
"bytes": BaseType("Bytes"),
@@ -60,7 +60,7 @@
6060
"uint32": "format_int64",
6161
"uint64": "format_int64",
6262
"fixed64": "format_int64",
63-
"float": "format_float64",
63+
"float": "format_float32",
6464
"double": "format_float64",
6565
"bool": "format_bool",
6666
"bytes": "format_bytes",

meta/src/meta/grammar.y

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,9 @@
3737
# PATTERN can be r'...' for regex or '...' for fixed string
3838
%token DECIMAL logic.DecimalValue r'[-]?\d+\.\d+d\d+'
3939
%token FLOAT Float64 r'([-]?\d+\.\d+|inf|nan)'
40+
%token FLOAT32 Float32 r'[-]?\d+\.\d+f32'
4041
%token INT Int64 r'[-]?\d+'
42+
%token INT32 Int32 r'[-]?\d+i32'
4143
%token INT128 logic.Int128Value r'[-]?\d+i128'
4244
%token STRING String r'"(?:[^"\\]|\\.)*"'
4345
%token SYMBOL String r'[a-zA-Z_][a-zA-Z0-9_./#-]*'
@@ -107,6 +109,7 @@
107109
%nonterm ffi logic.FFI
108110
%nonterm ffi_args Sequence[logic.Abstraction]
109111
%nonterm float_type logic.FloatType
112+
%nonterm float32_type logic.Float32Type
110113
%nonterm formula logic.Formula
111114
%nonterm fragment fragments.Fragment
112115
%nonterm fragment_id fragments.FragmentId
@@ -117,6 +120,7 @@
117120
%nonterm init Sequence[logic.Instruction]
118121
%nonterm instruction logic.Instruction
119122
%nonterm int_type logic.IntType
123+
%nonterm int32_type logic.Int32Type
120124
%nonterm int128_type logic.Int128Type
121125
%nonterm loop logic.Loop
122126
%nonterm lt logic.Primitive
@@ -245,6 +249,14 @@ value
245249
construct: $$ = logic.Value(boolean_value=$1)
246250
deconstruct if builtin.has_proto_field($$, 'boolean_value'):
247251
$1: Boolean = $$.boolean_value
252+
| INT32
253+
construct: $$ = logic.Value(int32_value=$1)
254+
deconstruct if builtin.has_proto_field($$, 'int32_value'):
255+
$1: Int32 = $$.int32_value
256+
| FLOAT32
257+
construct: $$ = logic.Value(float32_value=$1)
258+
deconstruct if builtin.has_proto_field($$, 'float32_value'):
259+
$1: Float32 = $$.float32_value
248260

249261
date
250262
: "(" "date" INT INT INT ")"
@@ -435,6 +447,14 @@ type
435447
construct: $$ = logic.Type(boolean_type=$1)
436448
deconstruct if builtin.has_proto_field($$, 'boolean_type'):
437449
$1: logic.BooleanType = $$.boolean_type
450+
| int32_type
451+
construct: $$ = logic.Type(int32_type=$1)
452+
deconstruct if builtin.has_proto_field($$, 'int32_type'):
453+
$1: logic.Int32Type = $$.int32_type
454+
| float32_type
455+
construct: $$ = logic.Type(float32_type=$1)
456+
deconstruct if builtin.has_proto_field($$, 'float32_type'):
457+
$1: logic.Float32Type = $$.float32_type
438458

439459
unspecified_type
440460
: "UNKNOWN"
@@ -479,6 +499,14 @@ decimal_type
479499
$3: Int64 = builtin.int32_to_int64($$.precision)
480500
$4: Int64 = builtin.int32_to_int64($$.scale)
481501

502+
int32_type
503+
: "INT32"
504+
construct: $$ = logic.Int32Type()
505+
506+
float32_type
507+
: "FLOAT32"
508+
construct: $$ = logic.Float32Type()
509+
482510
boolean_type
483511
: "BOOLEAN"
484512
construct: $$ = logic.BooleanType()
@@ -1122,8 +1150,8 @@ export_csv_source
11221150

11231151

11241152
def _extract_value_int32(value: Optional[logic.Value], default: int) -> Int32:
1125-
if value is not None and builtin.has_proto_field(builtin.unwrap_option(value), 'int_value'):
1126-
return builtin.int64_to_int32(builtin.unwrap_option(value).int_value)
1153+
if value is not None and builtin.has_proto_field(builtin.unwrap_option(value), 'int32_value'):
1154+
return builtin.unwrap_option(value).int32_value
11271155
return builtin.int64_to_int32(default)
11281156

11291157

@@ -1333,7 +1361,7 @@ def construct_export_csv_config_with_source(
13331361

13341362

13351363
def _make_value_int32(v: Int32) -> logic.Value:
1336-
return logic.Value(int_value=builtin.int32_to_int64(v))
1364+
return logic.Value(int32_value=v)
13371365

13381366

13391367
def _make_value_int64(v: int) -> logic.Value:

meta/src/meta/pretty_gen.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -675,10 +675,14 @@ def _format_terminal(terminal: NamedTerminal, value_var: Var) -> TargetExpr:
675675
return Call(make_builtin("format_string"), [value_var])
676676
elif terminal.name in ["INT", "NUMBER"]:
677677
return Call(make_builtin("format_int64"), [value_var])
678+
elif terminal.name == "INT32":
679+
return Call(make_builtin("format_int32"), [value_var])
678680
elif terminal.name == "INT128":
679681
return Call(make_builtin("format_int128"), [value_var])
680682
elif terminal.name == "FLOAT":
681683
return Call(make_builtin("format_float64"), [value_var])
684+
elif terminal.name == "FLOAT32":
685+
return Call(make_builtin("format_float32"), [value_var])
682686
elif terminal.name == "DECIMAL":
683687
return Call(make_builtin("format_decimal"), [value_var])
684688
elif terminal.name == "BOOL":

meta/src/meta/target_builtins.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
ANY = VarType("Any")
3131
INT32 = BaseType("Int32")
3232
INT64 = BaseType("Int64")
33+
FLOAT32 = BaseType("Float32")
3334
FLOAT64 = BaseType("Float64")
3435
STRING = BaseType("String")
3536
BOOLEAN = BaseType("Boolean")
@@ -158,6 +159,8 @@ def is_builtin(name: str) -> bool:
158159
# === Type conversions ===
159160
register_builtin("int64_to_int32", [INT64], INT32)
160161
register_builtin("int32_to_int64", [INT32], INT64)
162+
register_builtin("float64_to_float32", [FLOAT64], FLOAT32)
163+
register_builtin("float32_to_float64", [FLOAT32], FLOAT64)
161164
register_builtin("decode_string", [BYTES], STRING)
162165
register_builtin("to_ptr_int64", [INT64], OptionType(INT64))
163166
register_builtin("to_ptr_string", [STRING], OptionType(STRING))
@@ -234,6 +237,7 @@ def is_builtin(name: str) -> bool:
234237
# === Formatting for terminal types ===
235238
register_builtin("format_int64", [INT64], STRING)
236239
register_builtin("format_int32", [INT32], STRING)
240+
register_builtin("format_float32", [FLOAT32], STRING)
237241
register_builtin("format_float64", [FLOAT64], STRING)
238242
register_builtin("format_string", [STRING], STRING)
239243
register_builtin("format_symbol", [STRING], STRING)
@@ -329,6 +333,7 @@ def make_builtin_with_type(name: str, func_type: FunctionType) -> Builtin:
329333
"ANY",
330334
"INT64",
331335
"INT32",
336+
"FLOAT32",
332337
"FLOAT64",
333338
"STRING",
334339
"BOOLEAN",

meta/src/meta/templates/parser.go.template

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,9 @@ type tokenKind int
6161
const (
6262
kindString tokenKind = iota
6363
kindInt64
64+
kindInt32
6465
kindFloat64
66+
kindFloat32
6567
kindUint128
6668
kindInt128
6769
kindDecimal
@@ -72,7 +74,9 @@ type TokenValue struct {{
7274
kind tokenKind
7375
str string
7476
i64 int64
77+
i32 int32
7578
f64 float64
79+
f32 float32
7680
uint128 *pb.UInt128Value
7781
int128 *pb.Int128Value
7882
decimal *pb.DecimalValue
@@ -82,8 +86,12 @@ func (tv TokenValue) String() string {{
8286
switch tv.kind {{
8387
case kindInt64:
8488
return strconv.FormatInt(tv.i64, 10)
89+
case kindInt32:
90+
return fmt.Sprintf("%di32", tv.i32)
8591
case kindFloat64:
8692
return strconv.FormatFloat(tv.f64, 'g', -1, 64)
93+
case kindFloat32:
94+
return fmt.Sprintf("%sf32", strconv.FormatFloat(float64(tv.f32), 'g', -1, 32))
8795
case kindUint128:
8896
return fmt.Sprintf("0x%016x%016x", tv.uint128.High, tv.uint128.Low)
8997
case kindInt128:
@@ -225,6 +233,24 @@ func scanInt(s string) int64 {{
225233
return n
226234
}}
227235

236+
func scanInt32(s string) int32 {{
237+
numStr := s[:len(s)-3] // Remove "i32" suffix
238+
n, err := strconv.ParseInt(numStr, 10, 32)
239+
if err != nil {{
240+
panic(ParseError{{msg: fmt.Sprintf("Invalid int32: %s", s)}})
241+
}}
242+
return int32(n)
243+
}}
244+
245+
func scanFloat32(s string) float32 {{
246+
numStr := s[:len(s)-3] // Remove "f32" suffix
247+
f, err := strconv.ParseFloat(numStr, 32)
248+
if err != nil {{
249+
panic(ParseError{{msg: fmt.Sprintf("Invalid float32: %s", s)}})
250+
}}
251+
return float32(f)
252+
}}
253+
228254
func scanFloat(s string) float64 {{
229255
if s == "inf" {{
230256
return math.Inf(1)

meta/src/meta/templates/parser.jl.template

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,10 @@ end
8181

8282
scan_int(n::String) = Base.parse(Int64, n)
8383

84+
scan_int32(n::String) = Base.parse(Int32, n[1:end-3]) # Remove "i32" suffix
85+
86+
scan_float32(f::String) = Base.parse(Float32, f[1:end-3]) # Remove "f32" suffix
87+
8488
function scan_float(f::String)
8589
if f == "inf"
8690
return Inf
@@ -372,7 +376,7 @@ end
372376
# Export main parse functions and error type
373377
export parse, parse_transaction, parse_fragment, ParseError
374378
# Export scanner functions for testing
375-
export scan_string, scan_int, scan_float, scan_int128, scan_uint128, scan_decimal
379+
export scan_string, scan_int, scan_int32, scan_float, scan_float32, scan_int128, scan_uint128, scan_decimal
376380
# Export Lexer and provenance types for testing
377381
export Lexer, Location, Span
378382

meta/src/meta/templates/parser.py.template

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,21 @@ class Lexer:
151151
raise ParseError(f"Integer literal out of 64-bit range: {{n}}")
152152
return val
153153

154+
@staticmethod
155+
def scan_int32(n: str) -> int:
156+
"""Parse INT32 token."""
157+
n = n[:-3] # Remove "i32" suffix
158+
val = int(n)
159+
if val < -(1 << 31) or val >= (1 << 31):
160+
raise ParseError(f"Int32 literal out of range: {{n}}")
161+
return val
162+
163+
@staticmethod
164+
def scan_float32(f: str) -> float:
165+
"""Parse FLOAT32 token."""
166+
f = f[:-3] # Remove "f32" suffix
167+
return float(f)
168+
154169
@staticmethod
155170
def scan_float(f: str) -> float:
156171
"""Parse FLOAT token."""

meta/src/meta/templates/pretty_printer.go.template

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"math/big"
1515
"reflect"
1616
"sort"
17+
"strconv"
1718
"strings"
1819

1920
pb "github.com/RelationalAI/logical-query-protocol/sdks/go/src/lqp/v1"

0 commit comments

Comments
 (0)