Реализация стека в программе CL (OS400/iSeries)

Я начинаю программировать с использованием CL в системе IBM i. Моя задача - реализовать калькулятор RPN с использованием языка CL. Как правило, этот калькулятор использует стек. Но я понятия не имею, необходимо реализовать его в CL. Может кто-нибудь дать мне совет? Может быть, * переменные PTR являются решением, но кто-то может дать мне пример, как его использовать?

Заранее спасибо JS

редактировать:

Язык CL навязывается моим преподавателем.

Моя программа должна получать знаки от пользователя (цифры / числа, знаки математических операций).
После получения каждой подписи программа должна проанализировать то, что было получено, а затем предпринять некоторые действия, согласно псевдокоду:

Do when new sign was entered:
if: entered sign is a number
    then push it into stack
else if: entered sign is a sign of mathematical operation 
    then 
    - pop two elements from stack 
    - make operation using this elements and entered sign 
    - push result into stack

Моя проблема заключается в том, как реализовать или заменить этот стек. Необходимость достижения элемента в порядке LIFO, и я не знаю, сколько элементов в итоге будет содержать структура.

3 ответа

Решение

Поймите, что CL не подходит для этого. Следующее не проверено:

DCL &ARRAY *CHAR 50
DCL &PTR *PTR ADDRESS(&ARRAY)
DCL &ELEM *CHAR 10 STG(*BASED) BASPTR(&PTR)
DCL &i *DEC (9 0)
...
/* Loop through the array */
DOFOR VAR(&i) FROM(1) TO(5) BY(1)
  CHGVAR %OFFSET(&PTR) (%OFFSET(&PTR) + 10)
  /* &ELEM is the current array element */
ENDDO

Разместите некоторый код; что ты пробовал? Если вы не можете опубликовать какой-либо код, опубликуйте псевдокод и объясните, что вы хотите, чтобы код делал.

РЕДАКТИРОВАТЬ: приведенный выше фрагмент кода реализует массив. Это очень похоже на стек. LIFO так же просто, как отслеживать последний индекс массива. В приведенном выше фрагменте CHGVAR добавляет 10 байтов к указателю. Это 10 байтов, потому что каждый элемент массива / элемент стека составляет 10 байтов (DCL &ELEM). Этот конкретный стек содержит 5 записей - 5 раз 10 = 50 (DCL &ARRAY). Добавление 10 байтов - это PUSH, вычитание 10 байтов - это POP. Current &PTR является самой последней записью стека.

Ваш следующий шаг должен состоять в том, чтобы написать одну подпрограмму для каждой из основных операций в вашем наброске. Начните с НАЖАТЬ. Если вы не знакомы с отладчиками в IBM i, используйте DMPCLPGM, чтобы увидеть результаты работы вашего кода. Попробуйте, затем, если у вас остались вопросы, опубликуйте свой код и задайте конкретный вопрос об этом коде. Программирование - это написание кода, так что прыгайте и пробуйте!:-)

Насколько я помню, преподаватель сказал, что размер стека должен составлять всего 4 объекта (10 будет излишним). Если только мы не говорим об одном и том же репетиторе (pwr?).

Спасибо за ваш ответ Бак, мне удалось понять, как работают указатели благодаря вам:)

Я реализовал стек для этой конкретной проблемы:

PGM                                                                  
DCL        VAR(&STACK) TYPE(*CHAR) LEN(20)                           
DCL        VAR(&STACKPTR) TYPE(*PTR) ADDRESS(&STACK)                 
DCL        VAR(&STACKVAL) TYPE(*CHAR) STG(*BASED) BASPTR(&STACKPTR) LEN(5)                                                 

/* ----------------------------------------------------- */
/* code that uses PUSH and POP subroutines when required */
/* ----------------------------------------------------- */

SUBR       SUBR(PUSH)                                                             
  CHGVAR     VAR(&STACKVAL) VALUE(&WYRAZENIE)                   
  CHGVAR     VAR(%OFFSET(&STACKPTR)) VALUE(%OFFSET(&STACKPTR)+5)
ENDSUBR                                                         
SUBR       SUBR(POP)                                            
  CHGVAR     VAR(%OFFSET(&STACKPTR)) VALUE(%OFFSET(&STACKPTR)-5)               
ENDSUBR                                                         
ENDPGM                                                          

Конечно, нет контроля переполнения или чего-то еще, но это дает вам идею:)

Создайте очередь данных *LIFO. Записи, отправленные в очередь, могут быть получены в порядке "последний пришел - первым вышел".

Другие вопросы по тегам