aboutsummaryrefslogtreecommitdiff
path: root/src/server/when.odin
diff options
context:
space:
mode:
authorDanielGavin <danielgavin5@hotmail.com>2025-06-20 18:38:28 +0200
committerDanielGavin <danielgavin5@hotmail.com>2025-06-20 18:38:28 +0200
commitfa626ad544a171313ac1679e0865d9d7d822c63b (patch)
tree4d8755ee42984d69a71a26003745c9c11ce648ab /src/server/when.odin
parent5caff349cf9dad7c697eb49250ac4c1e75e259fb (diff)
Move ast.odin to server + add resolve_when_condition
Diffstat (limited to 'src/server/when.odin')
-rw-r--r--src/server/when.odin118
1 files changed, 116 insertions, 2 deletions
diff --git a/src/server/when.odin b/src/server/when.odin
index f1407fe..dc06c4f 100644
--- a/src/server/when.odin
+++ b/src/server/when.odin
@@ -1,7 +1,121 @@
package server
+import "core:fmt"
+import "core:log"
import "core:odin/ast"
+import "core:strconv"
-resolve_when_stmt :: proc(ast_context: ^AstContext, when_stmt: ^ast.When_Stmt) -> bool {
- return false
+import "src:common"
+
+When_Expr :: union {
+ int, //Integers types
+ bool, //Boolean types
+ string, //Enum types - those are the hardcoded options from i.e. ODIN_OS
+ ^ast.Expr,
+}
+
+resolve_when_ident :: proc(when_expr_map: map[string]When_Expr, ident: string) -> (When_Expr, bool) {
+ switch ident {
+ case "ODIN_OS":
+ if common.config.profile.os != "" {
+ return common.config.profile.os, true
+ } else {
+ return fmt.tprint(ODIN_OS), true
+ }
+ case "ODIN_ARCH":
+ if common.config.profile.arch != "" {
+ return common.config.profile.arch, true
+ } else {
+ return fmt.tprint(ODIN_ARCH), true
+ }
+ }
+
+ if ident in when_expr_map {
+ value := when_expr_map[ident]
+ return value, true
+ }
+
+ if v, ok := strconv.parse_int(ident); ok {
+ return v, true
+ } else if v, ok := strconv.parse_bool(ident); ok {
+ return v, true
+ }
+
+ return ident, true
+}
+
+resolve_when_expr :: proc(
+ when_expr_map: map[string]When_Expr,
+ when_expr: When_Expr,
+) -> (
+ _when_expr: When_Expr,
+ ok: bool,
+) {
+
+ switch expr in when_expr {
+ case int:
+ return expr, true
+ case bool:
+ return expr, true
+ case string:
+ return expr, true
+ case ^ast.Expr:
+ #partial switch odin_expr in expr.derived {
+ case ^ast.Ident:
+ return resolve_when_ident(when_expr_map, odin_expr.name)
+ case ^ast.Basic_Lit:
+ return resolve_when_ident(when_expr_map, odin_expr.tok.text)
+ case ^ast.Implicit_Selector_Expr:
+ return odin_expr.field.name, true
+ case ^ast.Binary_Expr:
+ lhs := resolve_when_expr(when_expr_map, odin_expr.left) or_return
+ rhs := resolve_when_expr(when_expr_map, odin_expr.right) or_return
+
+ lhs_bool, lhs_is_bool := lhs.(bool)
+ rhs_bool, rhs_is_bool := rhs.(bool)
+
+ lhs_int, lhs_is_int := lhs.(int)
+ rhs_int, rhs_is_int := rhs.(int)
+
+ lhs_string, lhs_is_string := lhs.(string)
+ rhs_string, rhs_is_string := rhs.(string)
+
+ if lhs_is_string && rhs_is_string {
+ #partial switch odin_expr.op.kind {
+ case .Cmp_Eq:
+ return lhs_string == rhs_string, true
+ case .Not_Eq:
+ return lhs_string != rhs_string, true
+ }
+ } else if lhs_is_bool && rhs_is_bool {
+ #partial switch odin_expr.op.kind {
+ case .Cmp_And:
+ return lhs_bool && rhs_bool, true
+ case .Cmp_Or:
+ return lhs_bool || rhs_bool, true
+ }
+ }
+
+ return {}, false
+ }
+ }
+
+
+ return {}, false
+}
+
+
+resolve_when_condition :: proc(condition: ^ast.Expr) -> bool {
+ when_expr_map := make(map[string]When_Expr, context.temp_allocator)
+
+ for key, value in common.config.profile.defines {
+ when_expr_map[key] = resolve_when_ident(when_expr_map, value) or_continue
+ }
+
+ if when_expr, ok := resolve_when_expr(when_expr_map, condition); ok {
+ b, is_bool := when_expr.(bool)
+ return is_bool && b
+ }
+
+ return false
}