X-Git-Url: https://git.distorted.org.uk/~mdw/sod/blobdiff_plain/b5212fc74fbd59a5875143337efcfcf4d842f7e1..bfd08be5c65f696eddf48cfa48eaeab2714a3ec5:/src/method-impl.lisp diff --git a/src/method-impl.lisp b/src/method-impl.lisp index d0c7a54..7fdceb1 100644 --- a/src/method-impl.lisp +++ b/src/method-impl.lisp @@ -523,6 +523,38 @@ set "v->kw"))) (name (effective-method-keyword-parser-function-name method))) + ;; Deal with the special `kw.' keywords read via varargs. We're + ;; building the dispatch up backwards, so if we do these first, they + ;; get checked last, which priviliges the function-specific arguments + ;; over these special effects. + (codegen-push codegen) + (call "vv" "va_arg" "*ap" (c-type (* (struct "kwval" :const)))) + (call "nn" "va_arg" "*ap" c-type-size-t) + (call :void name "kw" *null-pointer* "vv" "nn") + (setf va-act (namecheck "k" "kw.tab" + (codegen-pop-block codegen) va-act)) + + (codegen-push codegen) + (call "aap" "va_arg" "*ap" (c-type (* va-list))) + (call :void name "kw" "aap" *null-pointer* 0) + (setf va-act (namecheck "k" "kw.valist" + (codegen-pop-block codegen) va-act)) + + ;; Deal with the special `kw.' keywords read from a table. + (codegen-push codegen) + (deliver-expr codegen "t" + (format nil "(~A)v->val" + (c-type (* (struct "kwtab" :const))))) + (call :void name "kw" *null-pointer* "t->v" "t->n") + (setf tab-act (namecheck "v->kw" "kw.tab" + (codegen-pop-block codegen) tab-act)) + + (codegen-push codegen) + (convert "aap" (c-type (* va-list))) + (call :void name "kw" "aap" *null-pointer* 0) + (setf tab-act (namecheck "v->kw" "kw.valist" + (codegen-pop-block codegen) tab-act)) + ;; Work through the keywords. We're going to be building up the ;; conditional dispatch from the end, so reverse the (nicely sorted) ;; list before processing it. @@ -544,20 +576,6 @@ (setf tab-act (namecheck "v->kw" key-name (codegen-pop-block codegen) tab-act)))) - ;; Deal with the special `kw.' keywords read via varargs. - (codegen-push codegen) - (call "vv" "va_arg" "*ap" (c-type (* (struct "kwval" :const)))) - (call "nn" "va_arg" "*ap" c-type-size-t) - (call :void name "kw" *null-pointer* "vv" "nn") - (setf va-act (namecheck "k" "kw.tab" - (codegen-pop-block codegen) va-act)) - - (codegen-push codegen) - (call "aap" "va_arg" "*ap" (c-type (* va-list))) - (call :void name "kw" "aap" *null-pointer* 0) - (setf va-act (namecheck "k" "kw.valist" - (codegen-pop-block codegen) va-act)) - ;; Finish up the varargs loop. (emit-banner codegen "Parse keywords from the variable-length tail.") (codegen-push codegen) @@ -568,23 +586,8 @@ (emit-inst codegen (make-if-inst "ap" (make-block-inst nil (list loop))))) - ;; Deal with the special `kw.' keywords read from a table. - (codegen-push codegen) - (deliver-expr codegen "t" - (format nil "(~A)v->val" - (c-type (* (struct "kwtab" :const))))) - (call :void name "kw" *null-pointer* "t->v" "t->n") - (setf tab-act (namecheck "v->kw" "kw.tab" - (codegen-pop-block codegen) tab-act)) - - (emit-banner codegen "Parse keywords from the argument table.") - (codegen-push codegen) - (convert "aap" (c-type (* va-list))) - (call :void name "kw" "aap" *null-pointer* 0) - (setf tab-act (namecheck "v->kw" "kw.valist" - (codegen-pop-block codegen) tab-act)) - ;; Finish off the table loop. + (emit-banner codegen "Parse keywords from the argument table.") (codegen-push codegen) (emit-inst codegen tab-act) (emit-inst codegen (make-expr-inst "v++"))