Sheerpower Logo
H.6  Macros and Blueprints in Sheerpower

Macros and Blueprints in Sheerpower

Developers often repeat similar code, leading to redundancy, inconsistencies, and potential bugs. Macros and Blueprints in Sheerpower help reduce this by creating reusable code blocks, improving maintenance and efficiency.

In this tutorial, we will explore two powerful facilities in Sheerpower: Macros and Blueprints. These tools allow developers to generate reusable code structures, making programming more efficient and reducing redundancy.

What are Macros and Blueprints?

Macros are ideal for dynamic expansions where parameters need to be substituted into small, reusable code snippets.

Blueprints are suited for generating larger, structured blocks of code. For example, handling similar logic for customers, clients, and employees with minor variations can be efficiently handled using blueprints.

Key Differences Between Macros and Blueprints

  • Blueprints generate a separate copy of the code for each argument provided in the %generate directive. So, if there are 5 arguments, the blueprint code will be duplicated 5 times, each tailored to one of the arguments.
  • Macros produce only one copy of the macro code, expanding it wherever @macro is used. The number of arguments doesn't affect the number of code copies; it just influences how the macro expands at each occurrence of @macro.

Collaborative Advantage: Standardizing Code with Macros and Blueprints

In collaborative projects, maintaining consistency is crucial when multiple people contribute to the same codebase. Macros and Blueprints play a key role in standardizing repetitive tasks and logic.

By defining critical code blocks with macros or blueprints, teams can ensure:

  • Consistency: Everyone uses the same logic and structure, preventing errors and inconsistencies throughout the codebase.
  • Reusability: By reusing common code patterns, duplication is minimized, making it easier to implement changes across the project.
  • Optimization: Macros and blueprints streamline the process of adding new features or updates, allowing for smoother and quicker integration.
  • Error Reduction: Standardized code is easier to test, making bugs less likely to go unnoticed.
  • Savings: Overall, faster development and reduced maintenance costs in the long run.

Example: Using Blueprints for Standardized Data Validation

blueprint validator   validate_[[placeholder]]   store_[[placeholder]] end blueprint

To generate code:

%generate validator with customer

This approach ensures that all developers follow the same procedure, reducing miscommunication and errors, while improving overall maintainability.

Extending Blueprints

Blueprints can be extended to reuse and add new functionality. When extending a blueprint, new content is appended to or prepended before the base blueprint’s content when generating the final code.

Example of Extending and Prepending Blueprints

Let’s define three blueprints:

  1. A base blueprint
  2. An extended blueprint (appends content)
  3. A prepended blueprint (inserts content before the base)
blueprint base_handler print "init_{placeholder}" end blueprint blueprint extended_handler extends base_handler print "last_{placeholder}" end blueprint blueprint prepended_handler prepends base_handler   print "first_{placeholder}" end blueprint

Generating Code from an Extended Blueprint

When you generate code using extended_handler with a specific argument, both the base blueprint and the extended content are included:

%generate extended_handler with customer

Generated output:

init_customer last_customer

Generating Code from a Prepended Blueprint

Similarly, generating code with prepended_handler positions the new content before the base blueprint’s content:

%generate prepended_handler with customer

Generated output:

first_customer init_customer

Benefits of Extending Blueprints

  • Code Reuse: Common logic in the base blueprint is reused while extending functionality where needed.
  • Modular Structure: Encourages a modular approach, making code easier to maintain and expand.
  • Reduced Redundancy: By extending base blueprints, code duplication is avoided, keeping blueprints DRY (Don't Repeat Yourself).

Blueprint Placeholders with Formatting Functions

In addition to the standard [[placeholder]], Sheerpower Blueprints support [[placeholder.function]], allowing developers to manipulate the replacement text using specific formatting functions. These functions can adjust the case of the replacement text as follows:

  1. .lcase – Replaces the placeholder with the lowercase version of the replacement text.
  2. .ucase – Replaces the placeholder with the uppercase version of the replacement text.
  3. .ccase – Replaces the placeholder with the capitalized version (first letter capitalized, the rest in lowercase) of the replacement text.

Example Usage

blueprint handler print "processing_[[placeholder.lcase]]" print "validating_[[placeholder.ucase]]" print "completed_[[placeholder.ccase]]" end blueprint %generate handler with CUSTOMER

Generated Output

processing_customer validating_CUSTOMER completed_Customer

This new functionality allows more flexible handling of placeholder values, helping tailor output to specific formatting requirements.

Key Benefits:

  1. Automatic Formatting: Adjust case formatting without manually changing input data.
  2. Increased Flexibility: Provides more control over how placeholders are replaced in generated code.

Sequence Placeholder Feature for %generate

Overview

The %generate statement in Sheerpower Blueprints supports sequence placeholders, which allows for automatic generation of sequence numbers in blueprint parameters. This feature simplifies handling repetitive elements with distinct names.

How it Works

When a parameter in the %generate statement ends with one or more underscores (_), each underscore acts as a placeholder for a sequence number. The sequence number starts at 1 and increments with each repeated use of the same parameter name.

Example

blueprint handler   got$ = got$ + "[[placeholder]], " end blueprint blueprint handlerxx extends handler   got$ = got$ + " (extended)" end blueprint got$ = '' %generate handler with age, city, ID %generate handlerxx with ID__, ID__ print got$

Generated output:

AGE, CITY, ID, ID01, ID02, AGEX, (extended)

Key Benefits of Sequence Placeholders

  • Automatic Sequence Generation: No need to manually manage sequence numbers for parameters.
  • Consistency: Ensures consistent, sequential names without redundancy or manual tracking.
  • Extended Usability: Works seamlessly with extended blueprints, ensuring appended or inherited logic still applies.

Macros in SheerPower

Macros in SheerPower enable text substitution at compile time, allowing developers to create concise and reusable code snippets. Macros are expanded dynamically using the @macroname syntax. Placeholders in macro definitions are marked with [[placeholder]] and can have default values set using the equal sign (=). If a value isn’t provided during expansion, the default value will be used.

Defining Macros

Macros can be defined in two ways: as single-line or multi-line macros.

Single-Line Macros:
macro maxsize = 500 print 'The maximum size is: '; @maxsize
Multi-Line Macros:
macro macroname print "[[shortname=sysboot]]" print "[[event]] occurred." end macro

Expanding Macros

To expand a macro with placeholders, use the @macroname syntax followed by a list of placeholder=value pairs in parentheses.

Example:
macro log_event print "[[shortname=sysboot]] - [[event=an event]] occurred." end macro @log_event (shortname=Emergency, event="System Boot") @log_event (event="System Boot") @log_event

Nested Macros

Macros in SheerPower can be nested, allowing one macro to reference another. A macro must be defined before it can be referenced.

Example:
macro two print 'in two' end macro macro one print 'in one' @two end macro @one

When @one is called, it prints "in one" and immediately calls @two, which prints "in two". This ensures efficient code reuse and clean structuring.

Example with Placeholders:

macro age_is = "Your age is [[age=21]] for this project" print @age_is (age=30)

Macro with Character Substitution:

macro myname = "Sally Sue" + chr$(ascii("!")) print "This is "; @myname

This prints:

This is Sally Sue!

Blueprints in Sheerpower

Blueprints are similar to macros but focus on generating reusable templates for larger code blocks. You use the %generate directive to dynamically replace placeholders in blueprints.

Example of Blueprint Definition

blueprint handler print "do_read_[[placeholder]]" print "do_validate_[[placeholder]]" print "do_store_[[placeholder]]" end blueprint

To generate the code:

%generate handler with customer, client, employee

Generated code for customer:

do_read_customer do_validate_customer do_store_customer

Macros vs. Blueprints: A Comparison

Feature Macros Blueprints Best Use
Use Case Dynamic code generation Structured code generation Macros: Small, repeatable code snippets
Blueprints: Larger, structured logic
Flexibility Small, flexible code blocks Large, predefined code templates Macros: Frequent substitutions
Blueprints: Organizing larger repetitive structures
Shortcut Macro Definition macro macroname = value Not applicable Macros: Simple constants or values
Macro Expansion @macroname Not applicable Macros: Concisely expands to a single line or entire block of code.
Macro Expansion with placeholder substitutions @macroname (placeholder1=value1, placeholder2=value2, etc.) Not applicable Macros: Concise expansions with placeholder substitutions
Code Reusability Dynamic placeholders Customizable placeholders Macros: Best for repetitive patterns
Blueprints: Best for modular templates

Viewing Expanded Macros and Blueprints for Debugging

To assist in debugging macros and blueprints you can view the expanded versions of these code constructs. This feature is particularly useful when you need to verify the correctness of the expansions.

How It Works

Toggling Expansion Views: To view the expanded versions of any macros or blueprints, you can toggle the view using the %expand on and %expand off commands.

Syntax:

Surround the @macro or %generate statement with %expand on and %expand off to see the expansion.

%expand on @macroname %generate blueprintname %expand off

This will display the expanded content of the macro and blueprint during validation.

Usage:

  1. This feature is enabled when you are validating your code using the Validate option in SPDEV or Visual Studio Code.
  2. The expanded code will be displayed between %expand on and %expand off, helping you ensure that the macros or blueprints are correctly expanding as expected.

When to Use It

Use this feature when:

  1. Debugging or validating your macros and blueprints.
  2. You need to confirm that complex expansions are working as intended.
  3. You want a better understanding of how your code is being generated.

This feature simplifies debugging by providing a clear view of the generated code, making it easier to troubleshoot and validate expansions in your projects.

Source: C:\Sheerpower\sptests\test_macros.spsrc, Line: 139 Blueprint: %generate HANDLERPP o got$ = got$ + "(prepended) " o got$ = got$ + "AGEP, " ---------- Source: C:\Sheerpower\sptests\test_macros.spsrc, Line: 141 Macro: @test_it () o if expected$ <> got$ then o print '?? Macros: Expected '; expected$ o print ' Got '; got$ o delay o end if ----------
Hide Description

    

       


      

Enter or modify the code below, and then click on RUN

Looking for the full power of Sheerpower?
Check out the Sheerpower website. Free to download. Free to use.
Wide screen