compiler-construction,common-lisp , How are `tagbody` and `go` implemented under the hood in Common Lisp?


How are `tagbody` and `go` implemented under the hood in Common Lisp?

Question:

Tag: compiler-construction,common-lisp

How are tagbody and go implemented in Common Lisp? Is it some form of setjmp/longjmp or is there a more elegant way of handling this?

I'm writing a lispy language implemented in C and would like to have something like this.


Answer:

Simplifying Common Lisp's go to other languages goto is, well, too much simplification.

In Common Lisp, go can unwind the stack. For instance:

(tagbody
    (mapc #'(lambda (el1 el2)
              (format t "el1: ~a, el2: ~a~%" el1 el2)
              (when (or (null el1) (null el2))
                (go stop)))
          list1
          list2)
  stop)

If you're implementing Common Lisp in terms of C, then a non-unwinding go may be a regular goto, but an unwinding go requires setjmp/longjmp or equivalent functionality, with proper stack unwinding, followed by a regular goto if needed, i.e. in case the tagged Lisp form is not the C statement or expression after setjmp.

You'll probably want to use the operating system's exception handling, if you can afford the time abstracting it. It may payoff better if you later want to integrate with other languages' features, such as C++ exceptions, and the platform might already have a stack of handlers, thus running unwind-protect clean-up forms automatically up to a certain stack frame.

If you want to keep it portable with minimum effort, you can manage a thread-local stack of setjmp contexts where you longjmp to the most recent context with enough information to keep longjmping up to the right context, running unwind-protect clean-up forms throughout. This way, you may still want to use the platform's exception handling capabilities, but only to setup unwinding frames from/to foreign calls.


Related:


What is a common-lisp analogue of python's argparse?


python,common-lisp,argparse
What is a common-lisp analogue of python's argparse library for parsing command-line arguments?

Antlr4 token existence messing up parsing


parsing,logging,compiler-construction,antlr,antlr4
first time poster so my greatest apologies if I break the rules. I'm using Antlr4 to create a log parser and I'm running into some issues that I don't understand. I'm trying to parse the following input log sequence: USA1-RR-SRX240-EDGE-01 created 10.20.30.40/50985->11.12.13.14/443 With the following grammar: grammar Juniper; WS :...

memory layout of a multiple-inherited object in C++


c++,compiler-construction,multiple-inheritance
class B1 { virtual void f1(); int int_in_b1; }; class B2 { virtual void f2(); int int_in_b2; }; class D: B1, B2 { int int_in_d; void f1(); void f2(); }; class D1: B1, B2 { int int_in_d; virtual void f1(); virtual void f2(); }; Based on this article, the memory...

Creating A Process Queue in Common Lisp


common-lisp
I have a server running Hunchentoot (CentOS and SBCL). When a user submits a specific type of post request, a subprocess is launched (run-program) which can take up to four minutes to complete. If five people perform that specific type of request at the same time, the server runs out...

Macro that defines functions whose names are based on the macro's arguments


macros,common-lisp,symbols,sbcl
*Note: Despite having frequented StackOverflow for a long time, this is the first question that I have posted myself. Apologies if it's a bit verbose. Constructive criticism appreciated. When I define a struct in Common Lisp using defstruct, a predicate function is automatically generated that tests whether its argument is...

write parsed tokens and YYTEXT of flex lexical analyser to a file


compiler-construction,flex-lexer,lexical-analysis
I need to write the token and the text parsed of that token in a file with flex analyser. Basically I want to store each parsed token in an output file. Someone has some idea?...

Common Lisp Object System method execution order


lisp,common-lisp,clos
I have the following two classes: (defclass person () ()) (defmethod speak ((s person) string) (format t "-A" string)) (defmethod speak :before ((s person) string) (print "Hello! ")) (defmethod speak :after ((s person) string) (print "Have a nice day!")) (defclass speaker (person) ()) (defmethod speak ((i speaker) string) (print "Bonjour!"))...

sbcl run-program hang when there is large amount of output from program


common-lisp,hang,sbcl
Recently I find a run-program hang issue of sbcl 1.2.7 (32bits, linux). The code as following (progn (with-open-file (s "test.out" :direction :output :if-exists :supersede) (loop repeat 900 do (write-line (make-string 76 :initial-element #\x) s))) (run-program "/bin/bash" (list "-c" "cat test.out") :output :stream)) That is when the "cat test.out" produce many...

SBCL: Gather output of run-program process while running


subprocess,common-lisp,sbcl
Dear StackExchange members, I recently began toying around with Common Lisp and want to create a web interface for administrating a modded Minecraft server. I already tried out this solution but in this case the function just hangs and never returns. My code looks like this: (defvar *proc*) (defun create-minecraft-proc...

Running compiled lisp program with clisp-2.49 on OS X


common-lisp,clisp
I have just started out programming in Common Lisp using GNU clisp-2.49 (compiled from source) as my implementation on OS X 10.10 Yosemite. I've written a simple "Hello World" program as follows: (EXT:SAVEINITMEM "test" :INIT-FUNCTION 'main :EXECUTABLE t) (defun main () (format t "Hello World!") (EXT:EXIT)) When I run: $...

How are `tagbody` and `go` implemented under the hood in Common Lisp?


compiler-construction,common-lisp
How are tagbody and go implemented in Common Lisp? Is it some form of setjmp/longjmp or is there a more elegant way of handling this? I'm writing a lispy language implemented in C and would like to have something like this....

How to use a parameter in a macro call?


macros,lisp,common-lisp,sbcl
I have defined the following simple macro: (defmacro define-class (class-name) `(defclass ,class-name ()())) And now I want to use it in the following function: (defun create-data (mode) (define-class mode)) After compiling the last function I get the following message, the variable MODE is defined but never used. And when I...

Is there a way to insert raw javascript in parenscript code?


common-lisp,parenscript
The following code inserts third-party generated javascript as a string which will need to be eval'ed. (ps (let ((x (lisp (json:encode-json-alist-to-string '((:a . 1) (:b . 2)))))))) "(function () { var x = '{\"a\":1,\"b\":2}'; return null; })();" Is there a way to tell parenscript to insert a string unquoted?...

Can a C implementation use length-prefixed-strings “under the hood”?


c,compiler-construction,compiler-optimization,c-strings,null-terminated
After reading this question: What are the problems of a zero-terminated string that length-prefixed strings overcome? I started to wonder, what exactly is stopping a C implementation from allocating a few extra bytes for any char or wchar_t array allocated on the stack or heap and using them as a...

Local dynamic binding in common lisp


closures,common-lisp,dynamic-binding
Honnestly, I'm not sure I fully understand what it means for a binding to be "dynamic" versus "lexical". But I understand that when I use defvar or defparameterto define a binding, 1. it declares a global variable 2. the binding is declared "special", so that it can be shadowed by...

Why is a defined token not recognized during syntax analysis in C using Bison?


c,syntax,compiler-construction,token,lexical
I'm currently working on a simple infix-to-postfix compiler for a given grammar. I'm currently at the stage of syntax analysis. I have already written a lexical analyzer, using Flex library, however I'm stuck on a seemingly simple problem. The information below might seem like a lot to process, but I...

How do I properly register a Rust compiler plugin?


plugins,compiler-construction,loading,rust
I've been pulling my hair out over trying to get a Rust compiler plugin to register properly. I have a separate crate called rust_to_glsl that is in a subdirectory of my main code. Inside the rust_to_glsl/src/lib.rs file I have the following #![feature(plugin_registrar)] #![feature(rustc_private)] #![crate_type="dylib"] extern crate rustc; extern crate syntax;...

Modify list and return it inside a function in lisp


lisp,elisp,common-lisp
(defun testthis (node index newvalue) (set-nth node index newvalue) node ) I would like to modify the nth element of a list in a function and then returns this list to save the modification performed. How can I do a such function in lisp?...

Char Comparison in Common Lisp


sorting,char,comparison,lisp,common-lisp
How can i compare characters with Common Lisp? I have google it and found out that there are some functions to do the comparison, like char=, char/=, char<, char>, char<=, and char>=. But, i can't use all of the functions just like: (char= 'a 'a) (char< 'a 'b) If i...

Read input into string in Lisp reader macro


macros,common-lisp,reader-macro
I am trying to make a reader macro that would convert @this into "this". This is what I currently have: (defun string-reader (stream char) (declare (ignore char)) (format nil "\"~a\"" (read-line stream t nil t)) ) (set-macro-character #\@ #'string-reader ) The problem is that this requires that I put a...

Weird non-lisp errors with capturing labels with a lambda and `reduce`


lambda,crash,closures,common-lisp,allegro-cl
I stumbled across a very weird bug (?) while I was developing an application in Allegro Common Lisp, v9.0 for Windows. I do not get the regular lisp errors, instead I get system errors encapsulated in a lisp condition. I managed to create a simple test-case to reproduce the error...

No-argument (and) returns t


clojure,scheme,lisp,common-lisp
Both CL and Scheme define (and) to return t (or #t) with no arguments. I'm trying to understand the rationale for this. My naive assumption is that an empty set is false, and passing in zero arguments feels like passing in nothing that can be true. Edit: clojure follows the...

SBCL: Deploying Hunchentoot application as executable


common-lisp,executable,sbcl,hunchentoot
Dear StackOverflow community, I started playing with SBCL Common Lisp and want to develop a small web application using Hunchentoot. For easy deployment I planned to save everything in a binary using sb-ext:save-lisp-and-die as I can live with the big output size. For the executable you need to supply a...

lisp: dynamic scope vs explicit parameter passing


design-patterns,coding-style,common-lisp,anti-patterns,dynamic-scope
I see two different patterns for "output" functions in (common) lisp: (defun implicit () (format t "Life? Don't talk to me about life!")) (defun explicit (stream) (format stream "This will all end in tears.")) (defun test-im-vs-ex-plicit () (values (with-output-to-string (stream) (let ((*standard-output* stream)) (implicit))) (with-output-to-string (stream) (explicit stream)))) Is using...

How do compilers store hundreds of variables in only a few registers?


compiler-construction,vm-implementation
Say you have a virtual machine that only has 4 registers, A, B, C, and D. How do compilers store so many variables with only a limited amount of space? Are there multiple ways of doing this, or is there a single solid way that this is accomplished? What's the...

How to use FFI:def-call-in in clisp


lisp,common-lisp,ffi,clisp
I have figured out how to make use of shared objects created from C code into Clisp using FFI:def-call-out but I am not able to figure out how to use FFI:Def-call-in. I don't know the process and actually I am confused if clisp will also create some .so file that...

Invalid specialized parameter in method lambda list


lisp,common-lisp
I am trying to write a simple coin flip program in Common Lisp. This is the code I have (defun yn (let ht (random 1) (if (eq ht 1) (princ heads) (princ tails)) ) ) It seems simple enough, but I keep getting the error: "Invalid specialized parameter in method...

Register Allocation in Compilers


compiler-construction,code-generation,cpu-registers
What is meant by spilling of registers or spill code which appears in Register allocation phase of Code generation where compiler backend must allocate variables to memory or registers?.

Get element from list of list in lisp


lisp,elisp,common-lisp
I am a beginner with lisp. I manipulate list of list: ((name1, second) (name2, second2)) The goal of my function is to get the second element of the list that have name as it first node. For example: my list is: ((name1, second1) (name2, second2)) getelement list name1 should return...

Left recursion parsing


parsing,recursion,compiler-construction,recursive-descent,left-recursion
Description: While reading Compiler Design in C book I came across the following rules to describe a context-free grammar: a grammar that recognizes a list of one or more statements, each of which is an arithmetic expression followed by a semicolon. Statements are made up of a series of semicolon-delimited...

EVAL/APPLY: too many arguments given to F


lisp,common-lisp,clisp
Hello why do i get *** - EVAL/APPLY: too many arguments given to F on function call with nested lists parameter. I cannot figure it out, since I passed a simple nested list. (defun f (L) (cond ((NULL l) nil) ((listp (car L)) (append (F(car L))) (F(cdr L) (car (F...

How to move a file in Lisp using rename-file


lisp,common-lisp,pathname
What's the best way to move a file in Lisp in an implementation-independent way? For example I have an image file: (setq oldpath #P"SERVER:PICTURES;TEMP;PHOTO.PNG") and I want to move it out of the TEMP directory into the PICTURES directory. This seems to work: (setq newpath (make-pathname :host (pathname-host oldpath) :directory...

where is the text printed by C printf


io,common-lisp,cffi
I happened encounter a trouble with calling C printf function from SBCL via cffi. The problem is when I call printf function, I can't find the output text, just the return value of printf function show on the REPL. But when I quit SBCL, the output text appears on the...

Dynamic 2d array in lisp


common-lisp,clisp
I want to have a 2D array in Lisp . But each row can have different number of elements(At max 5). So I thought of maintaining another single list to store the current sizes of each row, and update them whenever required. So, my code goes like this : (setq...

Structuring large Lisp applications


lisp,common-lisp,quicklisp,asdf
I am currently trying to wrap my head around packages, systems & co. I now have read Packages, systems, modules, libraries - WTF? a few times, and I think I'm still having difficulties to get it right. If I simply want to split a Lisp source file into two files,...

What does the non-terminating-p argument of set-macro-character do?


macros,common-lisp
Set-macro-character has an optional argument called non-terminating-p. It seems to be used to indicate whether another character should be read after reading the macro character, but the reader algorithm seems to ignore this argument. Is there a difference whether I set it to true or false?

Backquote String Interpolation


macros,lisp,common-lisp
Is it possible to use lisp's macro to do string interpolation? For instance, can I make a macro like this: (defmacro test (a) `",a") So that (test abc) returns "abc" as a string? I could probably cheat by quoting it and turning that quote into a string, but that doesn't...

Java “The blank final field may not have been initialized” Anonymous Interface vs Lambda Expression


java,constructor,lambda,compiler-construction,java-8
I've recently been encountering the error message "The blank final field obj may not have been initialized". Usually this is the case if you try to refer to a field that is possibly not assigned to a value yet. Example class: public class Foo { private final Object obj; public...

EMACS-Live + Slime error at startup


emacs,common-lisp,slime,kubuntu
Ok, I must be missing something obvious. I'm getting stuck since yesterday to launch Emacs-live + slime. I'm using EMACS 24.3.1, installed Emacs-live and it worked well (if I start emacs-live without Slime it works), downloaded Slime-Pack from git and added this line to .emacs-live.el (live-append-packs '(~/.live-packs/slime-pack/)) I'm on a...

JavaCC and Unicode issue. Why \u696d cannot be managed in JavaCC although it belong to the range “\u4e00”-“\u9fff”


java,unicode,compiler-construction,antlr,javacc
We're trying to use JavaCC as a parser to parse source code which is in UTF-8( the language is Japanese). In JavaCC, we have a declaration like: < #LETTER: [ "\u0024", "\u0041"-"\u005a", "\u005f", "\u0061"-"\u007a", "\u00c0"-"\u00d6", "\u00d8"-"\u00f6", "\u00f8"-"\u00ff", "\u0100"-"\u1fff", "\u3040"-"\u318f", "\u3300"-"\u337f", "\u3400"-"\u3d2d", "\u4e00"-"\u9fff", "\uf900"-"\ufaff" ] > If it meets a string...

How do I best save/read data structures?


common-lisp,clos
I want to write some data structures pointed to by FOO and BAR to a file, and to read the data structures back into the symbols FOO and BAR when I start a new session of Common Lisp. It would appear *PRINT-READABLY* allows objects to be printed in a fashion...

If strings are vectors, why are they immutable?


lisp,common-lisp
if strings are vectors of characters, and a vector's elements can be accessed using elt, and elt is setf-able - then why are strings immutable?

Three address code (example)


compiler-construction,compiler-optimization
How can I describe suitable codes to implement: Sum :=0; for i from 1 to n do sum+= i endfor; ...

Delegate caching behavior changes in Roslyn


c#,.net,compiler-construction,roslyn,c#-6.0
Given the following code: public class C { public void M() { var x = 5; Action<int> action = y => Console.WriteLine(y); } } Using VS2013, .NET 4.5. When looking at the decompiled code, we can see that the compiler is caching the delegate at the call site: public class...

Semantics of SSA and multiple assignment


compiler-construction,ssa
In SSA form, a variable assigned from a phi ends up with the appropriate value depending on which path it was reached by. But what happens if, perhaps via some unusual path, both inputs to the phi have been assigned? e.g. a = 1 ... b = 2 ... c...

Updating the window in response to CLIM frame commands


common-lisp,clim,mcclim
While trying to figure out CLIM, I ran into this example program. It's a simple maze game. The author claims to have tested it in LispWorks (and even has #+Genera in there, implying that this program would work on a real Lisp Machine), but I'm trying to get it working...

Three-address code and symbol tables


compiler-construction,ocaml,abstract-syntax-tree,intermediate-language,symbol-table
I am working on a hobby retargetable C compiler in OCaml and I'm building it bottom up. So far I have an annotated AST type, abridged: type 'e expr = | Int of 'e * int | Var of 'e * var | Neg of 'e * 'e expr |...

Trying to multiply all elements in a list of sublists with elements in another list in lisp


list,common-lisp
I'm trying to multiply a list with n sublists with a list with n scalars. It's supposed to work like this: (kmult-matrix '((3 4 2 4) (2 5 6 9) (1 -2 8 10)) '(2 3 5)) => ((6 8 4 8) (6 15 18 27) (5 -10 40 50))...

Insertion into a list doesn't reflect outside function whereas deletion does?


list,lisp,common-lisp
I am new to Lisp. Deletion of an item in a list by a function gets reflected outside the function but insertion doesn't. How can I do the same for insertion? For example (defun test (a b) (delete 1 a) (delete 5 b) (append '(5) b) (member '5 b)) (setq...