@@ -29,6 +29,26 @@ fn (mut c Checker) comptime_call(mut node ast.ComptimeCall) ast.Type {
29
29
node.env_value = env_value
30
30
return ast.string_type
31
31
}
32
+ if node.is_compile_value {
33
+ arg := node.args[0 ] or {
34
+ c.error ('\$ d() takes two arguments, a string and a primitive literal' , node.pos)
35
+ return ast.void_type
36
+ }
37
+ if ! arg.expr.is_pure_literal () {
38
+ c.error ('-d values can only be pure literals' , node.pos)
39
+ return ast.void_type
40
+ }
41
+ typ := arg.expr.get_pure_type ()
42
+ arg_as_string := arg.str ().trim ('`"\' ' )
43
+ value := c.pref.compile_values[node.args_var] or { arg_as_string }
44
+ validate_type_string_is_pure_literal (typ, value) or {
45
+ c.error (err.msg (), node.pos)
46
+ return ast.void_type
47
+ }
48
+ node.compile_value = value
49
+ node.result_type = typ
50
+ return typ
51
+ }
32
52
if node.is_embed {
33
53
if node.args.len == 1 {
34
54
embed_arg := node.args[0 ]
@@ -569,6 +589,42 @@ fn (mut c Checker) eval_comptime_const_expr(expr ast.Expr, nlevel int) ?ast.Comp
569
589
return none
570
590
}
571
591
592
+ fn validate_type_string_is_pure_literal (typ ast.Type, str string ) ! {
593
+ if typ == ast.bool_type {
594
+ if ! (str == 'true' || str == 'false' ) {
595
+ return error ('bool literal `true` or `false` expected, found "${str} "' )
596
+ }
597
+ } else if typ == ast.char_type {
598
+ if str.starts_with ('\\ ' ) {
599
+ if str.len < = 1 {
600
+ return error ('empty escape sequence found' )
601
+ }
602
+ if ! is_escape_sequence (str[1 ]) {
603
+ return error ('char literal escape sequence expected, found "${str} "' )
604
+ }
605
+ } else if str.len != 1 {
606
+ return error ('char literal expected, found "${str} "' )
607
+ }
608
+ } else if typ == ast.f64_ type {
609
+ if str.count ('.' ) != 1 {
610
+ return error ('f64 literal expected, found "${str} "' )
611
+ }
612
+ } else if typ == ast.string_type {
613
+ } else if typ == ast.i64_ type {
614
+ if ! str.is_int () {
615
+ return error ('i64 literal expected, found "${str} "' )
616
+ }
617
+ } else {
618
+ return error ('expected pure literal, found "${str} "' )
619
+ }
620
+ }
621
+
622
+ @[inline]
623
+ fn is_escape_sequence (c u8 ) bool {
624
+ return c in [`x` , `u` , `e` , `n` , `r` , `t` , `v` , `a` , `f` , `b` , `\\ ` , `\` ` , `$` , `@` , `?` , `{` ,
625
+ `}` , `'` , `"` , `U` ]
626
+ }
627
+
572
628
fn (mut c Checker) verify_vweb_params_for_method (node ast.Fn) (bool , int , int ) {
573
629
margs := node.params.len - 1 // first arg is the receiver/this
574
630
// if node.attrs.len == 0 || (node.attrs.len == 1 && node.attrs[0].name == 'post') {
@@ -969,6 +1025,16 @@ fn (mut c Checker) comptime_if_branch(mut cond ast.Expr, pos token.Pos) Comptime
969
1025
return .skip
970
1026
}
971
1027
m.run () or { return .skip }
1028
+ return .eval
1029
+ }
1030
+ if cond.is_compile_value {
1031
+ t := c.expr (mut cond)
1032
+ if t != ast.bool_type {
1033
+ c.error ('inside \$ if, only \$ d() expressions that return bool are allowed' ,
1034
+ cond.pos)
1035
+ return .skip
1036
+ }
1037
+ return .unknown // always fully generate the code for that branch
972
1038
}
973
1039
return .eval
974
1040
}
0 commit comments