From bc1eac46b8e2d8e4640bc3dc9078a59a90685110 Mon Sep 17 00:00:00 2001 From: Scott Richmond Date: Tue, 4 Jun 2024 11:50:17 -0400 Subject: [PATCH] validate forward declarations --- janet/validate.janet | 56 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 44 insertions(+), 12 deletions(-) diff --git a/janet/validate.janet b/janet/validate.janet index 12b0a05..9cf6215 100644 --- a/janet/validate.janet +++ b/janet/validate.janet @@ -90,6 +90,9 @@ Deferred until a later iteration of Ludus: (set (validator :ctx) parent) validator) +(defn- resolve-local [ctx name] + (get ctx name)) + (defn- resolve-name [ctx name] (when (nil? ctx) (break nil)) (def node (get ctx name)) @@ -272,6 +275,24 @@ Deferred until a later iteration of Ludus: (match-clauses validator clauses) validator) +(defn- declare [validator fnn] + (def status (validator :status)) + (def declared (get status :declared @{})) + (set (declared fnn) true) + (set (status :declared) declared) + (print "declared function " (fnn :name)) + (pp declared) + validator) + +(defn- define [validator fnn] + (def status (validator :status)) + (def declared (get status :declared @{})) + (set (declared fnn) nil) + (set (status :declared) declared) + (print "defined function " (fnn :name)) + (pp declared) + validator) + (defn- fnn [validator] (def ast (validator :ast)) (def name (ast :name)) @@ -281,18 +302,22 @@ Deferred until a later iteration of Ludus: (set (status :tail) true) (when name (def ctx (validator :ctx)) - (def resolved (resolve-name ctx name)) - (when resolved + (def resolved (ctx name)) + (when (and resolved (not= :nothing (resolved :data))) (def {:line line :input input} (get-in ctx [name :token])) (array/push (validator :errors) {:node ast :msg (string "name is already bound on line " line " of " input)})) + (when (and resolved (= :nothing (resolved :data))) + (define validator resolved)) (set (ctx name) ast)) - (match-clauses validator (ast :data)) + (def data (ast :data)) + (when (= data :nothing) + (break (declare validator ast))) + (match-clauses validator data) (set (status :tail) tail?) - (def clauses (ast :data)) (def rest-arities @{}) (def arities @{:rest rest-arities}) - (each clause clauses + (each clause data (print "CLAUSE:") (pp clause) (def patt (first clause)) @@ -314,7 +339,7 @@ Deferred until a later iteration of Ludus: (set (validator :ast) expr) (validate validator) (def name (ast :name)) - (def resolved (resolve-name ctx name)) + (def resolved (ctx name)) (when resolved (def {:line line :input input} (get-in ctx [name :token])) (array/push (validator :errors) @@ -726,26 +751,33 @@ Deferred until a later iteration of Ludus: (set validate validate*) +(defn- cleanup [validator] + (def declared (get-in validator [:status :declared] {})) + (when (any? declared) + (each declaration declared + (array/push (validator :errors) {:node declaration :msg "declared fn, but not defined"}))) + validator) + (defn valid [ast &opt ctx] (default ctx @{}) (def validator (new-validator ast)) (def base-ctx @{:^parent ctx}) (set (validator :ctx) base-ctx) - (validate validator)) + (validate validator) + (cleanup validator)) (import ./base :as b) (do # (comment (def source ` -fn foo { - () -> foo (:foo) -} - -foo () +fn foo +fn bar () -> foo () +fn foo () -> bar () `) (def scanned (s/scan source)) (def parsed (p/parse scanned)) (def validated (valid parsed)) +# (get-in validated [:status :declared]) # (validated :ctx) )