Add algebraics, the base class for algebraic operations

All the to-be-created-shortly operations like addition, etc, are not just
commands, but algebraic operations in RPL, so prepare for that

Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
This commit is contained in:
Christophe de Dinechin 2022-10-17 19:55:21 +02:00
parent 89a774ba5f
commit bdf017e40f
5 changed files with 154 additions and 1 deletions

View file

@ -84,7 +84,8 @@ CXX_SOURCES += \
src/decimal128.cc \
$(DECIMAL_SOURCES) \
src/rplstring.cc \
src/symbol.cc
src/symbol.cc \
src/algebraic.cc
# Generate the sized variants of decimal128
src/decimal-%.cc: src/decimal128.cc src/decimal-%.h

View file

@ -48,6 +48,7 @@ SOURCES += \
../src/runtime.cc \
../src/rplstring.cc \
../src/symbol.cc \
../src/algebraic.cc \
HEADERS += \
sim-window.h \

62
src/algebraic.cc Normal file
View file

@ -0,0 +1,62 @@
// ****************************************************************************
// algebraic.cc DB48X project
// ****************************************************************************
//
// File Description:
//
// Shared code for all algebraic commands
//
//
//
//
//
//
//
//
// ****************************************************************************
// (C) 2022 Christophe de Dinechin <christophe@dinechin.org>
// This software is licensed under the terms outlined in LICENSE.txt
// ****************************************************************************
// This file is part of DB48X.
//
// DB48X is free software: you can redistribute it and/or modify
// it under the terms outlined in the LICENSE.txt file
//
// DB48X is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// ****************************************************************************
#include "algebraic.h"
#include "parser.h"
#include "renderer.h"
#include "runtime.h"
#include "settings.h"
#include <ctype.h>
#include <stdio.h>
RECORDER(algebraic, 16, "RPL Algebraics");
RECORDER(algebraic_error, 16, "Errors processing a algebraic");
OBJECT_HANDLER_BODY(algebraic)
// ----------------------------------------------------------------------------
// RPL handler for algebraics
// ----------------------------------------------------------------------------
{
record(algebraic, "Algebraic %+s on %p", object::name(op), obj);
switch(op)
{
case EVAL:
record(algebraic_error, "Invoked default algebraic handler");
rt.error("Algebraic is not implemented");
return ERROR;
default:
// Check if anyone else knows how to deal with it
return DELEGATE(command);
}
}

88
src/algebraic.h Normal file
View file

@ -0,0 +1,88 @@
#ifndef ALGEBRAIC_H
#define ALGEBRAIC_H
// ****************************************************************************
// algebraic.h DB48X project
// ****************************************************************************
//
// File Description:
//
// RPL algebraic objects
//
// RPL algebraics are objects that can be placed in algebraic expression
// (between quotes). They are defined by a precedence and an arity.
// Items with higher precedence are grouped, a.g. * has higher than +
// Arity is the number of arguments the command takes
//
//
//
// ****************************************************************************
// (C) 2022 Christophe de Dinechin <christophe@dinechin.org>
// This software is licensed under the terms outlined in LICENSE.txt
// ****************************************************************************
// This file is part of DB48X.
//
// DB48X is free software: you can redistribute it and/or modify
// it under the terms outlined in the LICENSE.txt file
//
// DB48X is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// ****************************************************************************
//
// Unlike traditional RPL, algebraics are case-insensitive, i.e. you can
// use either "DUP" or "dup". There is a setting to display them as upper
// or lowercase. The reason is that on the DM42, lowercases look good.
//
// Additionally, many algebraics also have a long form. There is also an
// option to prefer displaying as long form. This does not impact encoding,
// and when typing programs, you can always use the short form
#include "command.h"
struct algebraic : command
// ----------------------------------------------------------------------------
// Shared logic for all algebraics
// ----------------------------------------------------------------------------
{
algebraic(id i): command(i) {}
// Arity is the number of arguments this takes on the stack
static uint arity() { return 1; }
// Precedence is the precedence when rendering as equations
static uint precedence() { return 1; }
// Standard object interface
OBJECT_HANDLER_NO_ID(algebraic);
};
// Macro to defined an algebraic command
#define ALGEBRAIC_DECLARE(derived, arit, prec) \
struct derived : algebraic \
{ \
derived(id i = ID_##derived) : algebraic(i) {} \
\
static uint arity() { return arit; } \
static uint precedence() { return prec; } \
\
OBJECT_HANDLER(derived) \
{ \
if (op == EVAL) \
{ \
RT.algebraic(#derived); \
return ((derived *) obj)->evaluate(); \
} \
return DELEGATE(algebraic); \
} \
result evaluate(); \
}
#define ALGEBRAIC_BODY(derived) \
object::result derived::evaluate()
#define ALGEBRAIC(derived, arit, prec) \
ALGEBRAIC_DECLARE(derived, arit, prec); \
inline ALGEBRAIC_BODY(derived)
#endif // ALGEBRAIC_H

View file

@ -29,6 +29,7 @@
#include "object.h"
#include "algebraic.h"
#include "decimal-32.h"
#include "decimal-64.h"
#include "decimal128.h"