Module: deuce-internals Synopsis: The Deuce editor Author: Scott McKay Copyright: Original Code is Copyright (c) 1995-2004 Functional Objects, Inc. All rights reserved. License: Functional Objects Library Public License Version 1.0 Dual-license: GNU Lesser General Public License Warranty: Distributed WITHOUT WARRANTY OF ANY KIND /// Generally useful macros define macro inc! { inc! (?place:expression, ?dx:expression) } => { ?place := ?place + ?dx; } { inc! (?place:expression) } => { ?place := ?place + 1; } end macro inc!; define macro dec! { dec! (?place:expression, ?dx:expression) } => { ?place := ?place - ?dx; } { dec! (?place:expression) } => { ?place := ?place - 1; } end macro dec!; define macro max! { max! (?place:expression, ?others:*) } => { ?place := max(?place, ?others) } end macro max!; define macro min! { min! (?place:expression, ?others:*) } => { ?place := min(?place, ?others) } end macro min!; define macro swap! { swap! (?place1:expression, ?place2:expression) } => { begin let _value = ?place1; ?place1 := ?place2; ?place2 := _value end } end macro swap!; // 'push!' and 'pop!' are intended to be called only on lists define macro push! { push! (?list:expression, ?item:expression) } => { ?list := add!(?list, ?item) } end macro push!; // NB: this returns #() -- not #f -- when the list is empty! define macro pop! { pop! (?list:expression) } => { begin let _result = head(?list); ?list := tail(?list); _result end } end macro pop!; /// Protocols define macro protocol-definer //--- We don't use the name or supers yet... { define protocol ?:name (?supers:*) ?slots-and-generics:* end } => { ?slots-and-generics } slots-and-generics: { } => { } { ?slot-or-generic:*; ... } => { ?slot-or-generic; ... } slot-or-generic: { getter ?getter-name:name ?getter-arglist:* => ?values:* } => { define open generic ?getter-name ?getter-arglist => ?values } { getter ?getter-name:name ?getter-arglist:* } => { define open generic ?getter-name ?getter-arglist } { setter ?setter-name:name ?setter-arglist:* => ?values:* } => { define open generic ?setter-name ?setter-arglist => ?values } { setter ?setter-name:name ?setter-arglist:* } => { define open generic ?setter-name ?setter-arglist } { function ?function-name:name ?function-arglist:* => ?values:* } => { define open generic ?function-name ?function-arglist => ?values } { function ?function-name:name ?function-arglist:* } => { define open generic ?function-name ?function-arglist } end macro protocol-definer; /// Node locking define macro with-node-locked { with-node-locked (?node:expression) ?:body end } => { with-thing-locked (?node, node-lock) ?body end } end macro with-node-locked; define macro with-buffer-locked { with-buffer-locked (?buffer:expression) ?:body end } => { with-thing-locked (?buffer, buffer-lock) ?body end } end macro with-buffer-locked; define macro with-editor-locked { with-editor-locked (?editor:expression) ?:body end } => { with-thing-locked (?editor, editor-lock) ?body end } end macro with-editor-locked; define macro with-thing-locked { with-thing-locked (?thing:expression, ?accessor:name) ?:body end } => { begin let _thing = ?thing; let _lock = _thing & ?accessor(_thing); block () when (_lock) wait-for(_lock) end; ?body cleanup when (_lock) release-all(_lock) end; end end } end macro with-thing-locked; /// Editor state binding define macro with-editor-state-bound { with-editor-state-bound (?buffer:variable = ?window:expression) ?:body end } => { begin let _frame = window-frame(?window); let ?buffer = frame-buffer(_frame); dynamic-bind (*editor-frame* = _frame, *buffer* = ?buffer) ?body end end } { with-editor-state-bound (?window:expression) ?:body end } => { begin let _frame = window-frame(?window); let _buffer = frame-buffer(_frame); dynamic-bind (*editor-frame* = _frame, *buffer* = _buffer) ?body end end } end macro with-editor-state-bound; // Iterate over the windows associated with the given frame's editor. // If the frame is #f, this does nothing. define macro do-associated-windows { do-associated-windows (?window:variable = ?frame:expression) ?:body end } => { begin let _frame = ?frame; when (_frame) for (?window in editor-windows(frame-editor(_frame))) ?body end end end } end macro do-associated-windows; // Iterate over the buffers associated with the given frame's editor. // If the frame is #f, this does nothing. define macro do-associated-buffers { do-associated-buffers (?buffer:variable = ?frame:expression) ?:body end } => { begin let _frame = ?frame; when (_frame) for (?buffer in editor-buffers(frame-editor(_frame))) ?body end end end } end macro do-associated-buffers;