LINUX.ORG.RU

Языки системного уровня

 , ,


0

3

Всем привет! Вопрос - какие сейчас существуют языки системного программирования? Интересно что придумали на замену Си. О ржавом вкурсе. Его можно не упоминать

Перемещено leave из desktop

Ответ на: комментарий от sparkie

Внезапно: кресты.

Не надо портить человеку впечатление о программировании! Пусть мечты его остаются радужными!

P.S. На работе приходится использовать это чудо человеческой мысли. Каждый день мысленно ругаю его авторов

anonymous
()
Ответ на: комментарий от Obezyan

Предлагаю клоунам поднажать в этом ответе - вы отстаёте от людей с чувством юмора.

Obezyan
()
Ответ на: комментарий от sparkie

Ещё несколько лет и системный уровень на питоне писать начнут, вот тогда крестофобы завоють по настоящему:-)

AntonI ★★★★★
()

Если тебе по существу, то системным программированием можно заниматься на любом ЯП, умеющем нативную компиляцию и не вводящем принудительную сборку мусора. А если вопрос «какой ЯП сейчас принято считать системным», то это как раз то, о чём ты просил не упоминать. :)

hobbit ★★★★★
()
Ответ на: комментарий от anonymous

...ругаю его авторов

Бьерна этого вашего Страуструпа?

sparkie ★★★★★
()

Странная какая-то тема. Операционная система управляет процессами, памятью и вводом-выводом. Реализовать это можно на любом не слишком специализированном ЯП, на что справедливо указали в комментариях. Поэтому рассуждать о системном уровне несколько странно.

На практике обычно нужна сишечка, чтобы абстрагироваться от каждого конкретного ассемблера, но при этом эффективно ворочать байтами. Как вариант, C++. Поэтому весьма условно системным уровнем можно считать уровень средний.

Так уж сложилось, что Linux написан на C, но недавно притащили еще и Rust, на котором можно написать какой-нибудь модуль ядра. Windows написана на C++. Чтобы присоединиться к состоявшимся проектам, нужно писать на тех же языках.

Если же писать свою систему с нуля, то можно взять что угодно. Для дела - что угодно среднеуровневое. Чисто для фана - да хоть Perl.

Vidrele ★★★
()

Forth и modula вроде все еще хоть и редко используются во всяком embedded.

anonymous
()
Ответ на: комментарий от hateyoufeel

Haskell, Common Lisp, OCaml.

OCaml да уже везде вроде засунули, даже в восьмиразрядные процессоры, но хаскель вроде же кроме генерации сишного кода в таком качестве не используется, тупо рантайм не даст. Лисп или схему да тоже можно ужать очень сильно.

anonymous
()
Ответ на: комментарий от anonymous

OCaml да уже везде вроде засунули, даже в восьмиразрядные процессоры

Вряд ли. Тоже рантайм не даст.

но хаскель вроде же кроме генерации сишного кода в таком качестве не используется, тупо рантайм не даст.

Зачем сишного? Смотри, анон, генерация ассемблера под 6502 прямо из кода на хачкелле!

https://hackage.haskell.org/package/sixty-five-oh-two

В общем-то, никто не мешает таким же макаром сделать поддержку вообще любого восьмибитного контроллера. Благо, у них система команд довольно куцая обычно. Задача уровня курсовой для второкурсника.

hateyoufeel ★★★★★
()
Последнее исправление: hateyoufeel (всего исправлений: 1)
Ответ на: комментарий от hobbit

зачем ты пишешь умное в этом бреду эмоций ?? :)

pfg ★★★★★
()
Ответ на: комментарий от HE_KOT

м-м-м, мне кажется это про другое (кодирование данных наверное), можно по подробнее как по шине передаются сигналы трех уровней :)

pfg ★★★★★
()
Последнее исправление: pfg (всего исправлений: 1)
Ответ на: комментарий от hateyoufeel

Вряд ли. Тоже рантайм не даст.

У OCaml он легко усекается http://www.algo-prog.info/ocapic/web/index.php?id=ocapic весь рантайм (с GC !) это около 1000 строк на ассемблере плюс интерпретатор байт кода в 2500 строк.

Зачем сишного? Смотри, анон, генерация ассемблера под 6502 прямо из кода на хачкелле!

Да сразу форт вспоминается, с его форт ассемблером, но у хаскеля это все же не то, понятно что DSL но по сути ближе просто к компилятору-транслятору.

anonymous
()
Ответ на: комментарий от pfg

можно по подробнее как по шине передаются сигналы трех уровней

В современных ssd лежат в кондерах сигналы уже кажется больше трех уровней.

anonymous
()
Ответ на: комментарий от anonymous

знаю :) до 32 в QLC, но для работы онных уровней там намудрено очень много схемотехники.
мудрить подобную схемотехнику на каждую сигнальную линию очень не выгодно, тем более есть более эффективные системы повышения пропускной способонсти сигнальной линии.
потому и предполагаю что тут попутан физический уровень с какойто кодировкой типа хемминга.

pfg ★★★★★
()
Ответ на: комментарий от anonymous

У OCaml он легко усекается http://www.algo-prog.info/ocapic/web/index.php?id=ocapic весь рантайм (с GC !) это около 1000 строк на ассемблере плюс интерпретатор байт кода в 2500 строк.

Мне что-то кажется, код вот на этом окамле не будет с кодом на обычном окамле иметь почти ничего общего. Т.е. это отдельный диалект с совершенно отдельной практикой написания кода. Я не очень понимаю этот онанизм на добавление поддержки экзотических таргетов в какой-то язык, если почти вся кодовая база этого языка ни разу не применима.

У хачкелла с 6502 можно использовать огромную библиотеку, благо она останется вся только на стадии компиляции, а в бинарик уйдёт довольно маленький выхлоп без необходимости в каком-либо рантайме в принципе.

но у хаскеля это все же не то, понятно что DSL но по сути ближе просто к компилятору-транслятору.

Да нет, это как раз именно то что нужно. Хачкель точно так же в Verilog транслируют, например. Получается весьма офигенно.

hateyoufeel ★★★★★
()
Последнее исправление: hateyoufeel (всего исправлений: 1)
Ответ на: комментарий от anonymous

Почему сразу «скриптомакака»? По себе судишь? По-моему можно нисколько не любить C++, оставаясь при этом хорошим разработчиком на тех же самых C++. Просто на них работы больше. Где вот ты хорошую работу найдешь на тех же Rust или Haskell? Вот они красивы и по-умному продуманы, а не как «само так получилось», но на C++ работы просто больше.

Смотрел сейчас на hh одну вакансию на Rust. Оказалась крипта… И так многое на Rust. Да еще и иностранщина обычно какая-то

anonymous
()
Ответ на: комментарий от hobbit

Если тебе по существу, то системным программированием можно заниматься на любом ЯП, умеющем нативную компиляцию и не вводящем принудительную сборку мусора.

При условии что этот любой язык С/С++. Если бы было что-то более подходящее на нём бы во всю писали.

Ygor ★★★★★
()
Ответ на: комментарий от anonymous

Rust

они красивы и по-умному продуманы

ну тут ты совсем пережирнил

anonymous
()
Ответ на: комментарий от PhD

Да Common Lisp самый актуальный, живой, развивающийся, с самым большим коммьюнити, лучшими библиотеками и так далее.

В сторону схемы и ее вариантов вообще не смотри, разве что для обучения

lovesan ★★
()
Ответ на: комментарий от anonymous

интересно, уперлись в какой-то предел %)
странно, что не применили ddr модуляцию, или сериализацию в lvds, хотя PCIe и так lvds… дробление уровней внутри lvds… надо почитать.

pfg ★★★★★
()
Ответ на: комментарий от Shushundr

я круче – у меня флуда меньше и всё по делу.

anonymous
()
Ответ на: комментарий от lovesan

вот, кстати, лавсан. переадресую вопрос

про !ъ:нанотехнологии и выше и ниже по треду (например, про тот же tinygo).

ты его подробно смотрел? что именно там не реализовано? сколько занимает минималистичный рантайм и куда именно оно такое вот недоделанное может поместиться?

SDK для микроконтроллеров итп, тоже в основном сишные.

ну вот тебе, например, для go или .net модное и молодёжное.

там как, можно на Dylan.NET с нанотехнологиями что-нибудь писать или «да, но пока нет»?

я вот не понял этот хайп и пиар про tinygo и nanoframework.

хотя про руст и аду частично понял.

проще всего рантайм отстреливался и заменялся на свою tiny реализацию в аде, ним, D v1.0 том же или схеме ribbit.

я уж не говорю что выше и ниже по треду вполне можно было бы на схеме реализовать асм кодогенерацию, на асме – схему, на схеме – акторную модель какую-нибудь.

а то какое-то странное «системное» программирование получается – с толстым рантаймом и плохоструктурированным концептуально вагоном фич которые не используешь, а платить всё равно надо.

модно и молодёжно, ога.

anonymous
()
Ответ на: комментарий от AntonI

Nim, SparkLark или ConvergePL с CTMP ?

например, на последнем можно запилить свой ассемблер: examples/dsls/wsi_asm.

или конечные автоматы: statemachine.

далее читаем например 11-gholum.pdf или от того же автора в кодогенераторе Ikarus scheme: ikarus.intel-assembler.ss, и про схему ribbit и justin.lol sectorlisp

и получаем «ассемблер на лиспе» (ну или лисп на таком ассемблере если подраскрутить метациклически)

если про конечные автоматы – читаем Шалыто про SWITCH-технологию и Легалова про автоматное программирование.

в общем, питон это прежде всего тулинг. например, asciidoc довольно приятный. хотя переписанный на nim был бы компактнее.

а вообще странно видеть питоноподобное в системном программировании – там же глобальные блокировки интепретатора всю дорогу, и рантайм сам по себе довольно толстый.

вот какой-нибудь компилируемый в си недопитон с питонячьим синтаксисом – ещё куда ни шло.

главное, чтобы оно в очередной ч0рный ящик не начало превращаться.

anonymous
()
Ответ на: комментарий от anonymous

на русте, например

чтобы поржать.

и поискать там GIL в руст реализации недопитона.

anonymous
()
Ответ на: комментарий от Vidrele

Поэтому рассуждать о системном уровне несколько странно.

ну например: первый вариант.

в аде есть task и task type, task entry и механизм синхронизации через рандеву. синхронизируются task entry и контролируемая память. то есть далее мы получаем понятный вид многозадачности – встроенной в сам язык.

можно написать планировщик, например. который реализует пул объектов. например, берёт access type (корректно типизированную, проверяемую компилятором ссылку) а не address type (обычные сырые сишные указатели) на конкретные tasks, или их элементы. помещаем это в массив, и получаем статически заданный во время компиляции пул объектов.

и запускаем две задачи: одна реализует обновление GUI, другая – планировщик. который запускает каждую задачу из массива.

то есть: компилятор знает о «задачном типе» и контролируемой памяти получаем многозадачность проверяемую компилятором.

не то чтобы там невозможно было сделать deadlock/livelock.

но например, проверить какие-то контракты на SPARK для этих задач.

то есть: на системном уровне – в ада встроена многозадачность в язык и адекватная модульность, программирование по-большому (с родительскими и дочерними пакетами, параметризацией модулей дженериками).

второй вариант. берём BCPL, C, C++. в котором всего этого нет.

и получает нетранзитивность константости – не проверямую компилятором. потому что он на этом уровне рассуждать не умеет – концепции не интегрированы в язык. а UB – интегрировано.

2.5 tiny или обычный go и его встроенную многозадачность на CSP.

третий вариант. берём Dlang и Compile-time metaprogramming и например, immutable а не const. опа, оказывается D умеет – а С++ не умеет.

четвёртый вариант. берём языки с изменяемым синтаксисом и макросами: коммон лисп и его макросы, схему и её модульные гигиеничные макросы, форт и какие-то костыли поверх IMMEDIATE/COMPILE слов.

получаем eDSL слабо интегрированный в язык (но и его может оказаться достаточно).

пятый вариант. берём язык с полноценным CTMP в духе ConvergePL. чтобы макросы компилировались в корректно типизированные AST, проверяемые во время компиляции.

и какой-то интерфейс API между compile time/runtime частями в духе $<CEI::lift(...) и т.п.

и получаем корректно типизированные макросы.

в духе первоначальной посылки pfg:

то, на чем можно создать систему необходимого качества с нуля :)

это означает, что все примитивы (концепции, парадигмы) должны быть написаны на таком системном языке, с нуля – на нём самом вся система полностью – а не только лишь отдельные части.

аки метапрог эдакий

хотя можно например использовать C библиотеки через FFI (понимая где и именно в чём эти абстракции начинают протекать и становятся unsafe).

Страуструп как-то сказал: что unsafe в С++ можно впендюрить сбоку, при большом желании.

после чего я очень засомневался в что он вообще понимает что такое unsafe. и в его проектировании, модульности (которой нет) и мультипарадигменности (плохо интегрированной между собой) и концептуальной целостности.

оставайся cfront очередным язычком уровня vala – и это можно было бы пережить.

хуже того, ведь это всё спекается в какой-то фрактал.

очередного «кластера метапарадигм».

anonymous
()
Ответ на: комментарий от Shushundr

«каким должен быть язык программирования»

С точки зрения контента сайт бестолковый

галопом по европам:

Graydon Hoare: 21 compilers and 3 orders of magnitude in 60 minutes LtU

PDF

увидел там #21 особей (specimen).

есть довольно компактные, в небольшое число строк.

ещё например можно добавить QBE про SSA и Myrrdin на нём.

а так — довольно занятный обзор по компиляторам.

anonymous
()
Ответ на: комментарий от anonymous

почитал бегло нагугленное описание :) да, внутри lvds сделали дробление сигнала на 4 уровня. мдааа.

pfg ★★★★★
()
Последнее исправление: pfg (всего исправлений: 2)
Ответ на: комментарий от anonymous

можно добавить QBE про SSA и Myrrdin на нём

На чём, на «нём»?

dataman ★★★★★
()

потому что на языке Си прогать это сложнее чем на форуме языком чесать?

splinter ★★★★★
()
Ответ на: комментарий от hateyoufeel
accumulatorLoadNStore :: Instruction
accumulatorLoadNStore = do
    lda (Immediate 0x10)
    sta (Absolute 0x0200)
    rts (Implied)

Ууух, какая срань. Я так и на сишных макросах смогу.

PPP328 ★★★★★
()
Последнее исправление: PPP328 (всего исправлений: 1)
Ответ на: комментарий от PPP328

Ууух, какая срань. Я так и на сишных макросах смогу.

Ты можешь на сишных макросах сделать статические проверки ассемблерного кода, не позволяющие сунуть неправильный операнд не в ту инструкцию? Удачи.

hateyoufeel ★★★★★
()
Ответ на: комментарий от hateyoufeel

Ты можешь на сишных макросах сделать статические проверки ассемблерного кода, не позволяющие сунуть неправильный операнд не в ту инструкцию?

Да.

Можно даже с проверкой самих передаваемый значений, там же опкод меняется в зависимости от того, что сунули, ZP, адрес, значение или сахарок в виде A,X/A,Y/(A),Y/(A, X). Всё без проблем чекается. Мне даже в отличие от этой хаскеле-срани не нужно указывать какой тип передачи значения, я и сам могу задетектить:

// Concatenate
#define CAT__(x) x
#define CAT_(x, y) CAT__(x ## y)
#define CAT(x, y) CAT_(x, y)

// Count variadica arguments
#define ARGC(...) ARGC_(__VA_ARGS__, ARGC_RSEQ_N())
#define ARGC_(...) ARGC_N(__VA_ARGS__) 
#define ARGC_N(_1, _2, N, ...) N 
#define ARGC_RSEQ_N() 2, 1, 0

// Syntax routines
#define EXPAND(x) x
#define COMMA(x) ,

// OPCODES
#define OPCODE_LDA_ABSOLUTE                  0xAD // LDA 0x0000..0xFFFF
#define OPCODE_LDA_ABSOLUTE_INDEXX           0xBD // LDA 0x0000..0xFFFF, X
#define OPCODE_LDA_ABSOLUTE_INDEXY           0xB9 // LDA 0x0000..0xFFFF, Y
#define OPCODE_LDA_IMMEDIATE                 0xA9 // LDA #0x00..#0xFF
#define OPCODE_LDA_ZEROPAGE                  0xA5 // LDA 0x00..0xFF
#define OPCODE_LDA_ZEROPAGE_INDIRECT_INDEXX  0xA1 // LDA (0x00..0xFF, X)
#define OPCODE_LDA_ZEROPAGE_INDEXX           0xB5 // LDA 0x00..0xFF, X
#define OPCODE_LDA_ZEROPAGE_INDIRECTY_INDEXY 0xB1 // LDA (0x00..0xFF), Y

#define OPCODE_CPX_ABSOLUTE                  0xEC // CPX 0x0000..0xFFFF
#define OPCODE_CPX_IMMEDIATE                 0xE0 // CPX #0x00..0xFF
#define OPCODE_CPX_ZEROPAGE                  0xE4 // CPX 0x00..0xFF

#define OPCODE_RTS                           0x60 // RTS

// VALUE CONVERTERS

// ZP tester
#define VALUE_TEST_0x00 0
#define VALUE_TEST_0x01 0
#define VALUE_TEST_0x02 0
#define VALUE_TEST_0x03 0
#define VALUE_TEST_0x04 0
#define VALUE_TEST_0x05 0
// ... I'm too lazy, works for MVP
#define VALUE_TEST_0xFF 0

// ADDRESS tester
#define VALUE_TEST_0x0001 1
#define VALUE_TEST_0x0002 1
#define VALUE_TEST_0x0003 1
#define VALUE_TEST_0x0004 1
#define VALUE_TEST_0x0005 1
// .. I'm too lazy, works for MVP
#define VALUE_TEST_0xFFFF 1

// IMMEDIATE tester
#define VALUE_TEST__0x00 2
#define VALUE_TEST__0x01 2
#define VALUE_TEST__0x02 2
#define VALUE_TEST__0x03 2
#define VALUE_TEST__0x04 2
// .. I'm too lazy, works for MVP
#define VALUE_TEST__0x05 2

// Immediate marker remover
#define VALUE_DEIM_0x00 0x00
#define VALUE_DEIM_0x01 0x01
#define VALUE_DEIM_0x02 0x02
#define VALUE_DEIM_0x03 0x03
#define VALUE_DEIM_0x04 0x04
// .. I'm too lazy, works for MVP
#define VALUE_DEIM_0xFF 0xFF

// U16 splitter
#define U16_SPLIT_0x0000 0x00, 0x00
#define U16_SPLIT_0x0001 0x01, 0x00
#define U16_SPLIT_0x0002 0x02, 0x00
#define U16_SPLIT_0x0003 0x03, 0x00
#define U16_SPLIT_0x0004 0x04, 0x00
// .. I'm too lazy, works for MVP
#define U16_SPLIT_0xFFFF 0xFF, 0xFF

// INSTRUCTION: LDA
/* Allowed LDA notations:
 * a  |   a, x  |  a, y  | #
 * zp | (zp, x) | zp, x  | (zp), y */

#define LDA_CHECKZPX(...) CAT(LDA_CHECKZPX_, ARGC(__VA_ARGS__)),

// zp
#define LDA_PROCESSOR_ARG1_1_0(val) OPCODE_LDA_ZEROPAGE, val,
// a
#define LDA_PROCESSOR_ARG1_1_1(val) OPCODE_LDA_ABSOLUTE, CAT(U16_SPLIT_, val),
// _
#define LDA_PROCESSOR_ARG1_1_2(val) OPCODE_LDA_IMMEDIATE, CAT(VALUE_DEIM, val),

// a | _ | zp
#define LDA_PROCESSOR_ARG1_1(x) CAT(LDA_PROCESSOR_ARG1_1_, CAT(VALUE_TEST_, x))(x)

// (zp, x)
#define LDA_PROCESSOR_ARG1_2_(x, reg) OPCODE_LDA_ZEROPAGE_INDIRECT_INDEXX, x,
#define LDA_PROCESSOR_ARG1_2(x) LDA_PROCESSOR_ARG1_2_ x

// a | _ | zp | (zp, x)
#define LDA_ARGC_1(x) CAT(LDA_PROCESSOR_ARG1_,ARGC(LDA_CHECKZPX x))(x)

// a,x
#define LDA_PROCESSOR_AXY_X(val) OPCODE_LDA_ABSOLUTE_INDEXX, CAT(U16_SPLIT_, val),
// a,y
#define LDA_PROCESSOR_AXY_Y(val) OPCODE_LDA_ABSOLUTE_INDEXY, CAT(U16_SPLIT_, val),

// a,x | a, y
#define LDA_PREOCESSOR_AXYZP_1(val, reg) CAT(LDA_PROCESSOR_AXY_, reg)(val)

// zp, x
#define LDA_PREOCESSOR_AXYZP_0(val, reg) OPCODE_LDA_ZEROPAGE_INDEXX, val,

// a, x | a, y | zp, x
#define LDA_PROCESSOR_ARG2_1(val, reg) CAT(LDA_PREOCESSOR_AXYZP_, CAT(VALUE_TEST_, val))(val, reg)

// (zp), y
#define LDA_PROCESSOR_ARG2_2(val, reg) OPCODE_LDA_ZEROPAGE_INDIRECTY_INDEXY, EXPAND val,

// a, x | a, y | zp, x | (zp), y
#define LDA_ARGC_2(val, reg) CAT(LDA_PROCESSOR_ARG2_, ARGC(LDA_CHECKINDIR COMMA val))(val, reg)

#define LDA(...) CAT(LDA_ARGC, CAT(_, ARGC(__VA_ARGS__)))(__VA_ARGS__)


// INSTRUCTION: RTS
// Implied only
#define RTS OPCODE_RTS,

// INSTRUCTION: CPX
// a, #, zp

#define CPX_ARGC_2(a, b) "CPX cannot be used with 2 arguments"

#define CPX_CHECKZPX(...) CAT(CPX_CHECKZPX_, ARGC(__VA_ARGS__)),

// zp
#define CPX_PROCESSOR_ARG1_1_0(val) OPCODE_CPX_ZEROPAGE, val,
// a
#define CPX_PROCESSOR_ARG1_1_1(val) OPCODE_CPX_ABSOLUTE, CAT(U16_SPLIT_, val),
// _
#define CPX_PROCESSOR_ARG1_1_2(val) OPCODE_CPX_IMMEDIATE, CAT(VALUE_DEIM, val),

// a | _ | zp
#define CPX_PROCESSOR_ARG1_1(x) CAT(CPX_PROCESSOR_ARG1_1_, CAT(VALUE_TEST_, x))(x)

// (zp, x)
#define CPX_PROCESSOR_ARG1_2_(x, reg) "CPX cannot be used with ZP-indirect syntax"
#define CPX_PROCESSOR_ARG1_2(x) CPX_PROCESSOR_ARG1_2_ x

#define CPX_ARGC_1(x) CAT(CPX_PROCESSOR_ARG1_,ARGC(CPX_CHECKZPX x))(x)

#define CPX(...) CAT(CPX_ARGC, CAT(_, ARGC(__VA_ARGS__)))(__VA_ARGS__)


/* Notes: 
 *  * Use C-like hex ("0x" prefix)
 *  * For immediate value use "_" prefix. */

const unsigned char binary[] = {
    LDA (0x0001)        // 0xAD, 0x01, 0x00,
    LDA (0x0002, X)     // 0xBD, 0x02, 0x00,
    LDA (0x0003, Y)     // 0xB9, 0x03, 0x00,
    LDA (_0x04)         // 0xA9, 0x04,
    LDA (0x05)          // 0xA5, 0x05,
    LDA ((0x04, X))     // 0xA1, 0x06,
    LDA (0x03, X)       // 0xB5, 0x03,
    LDA ((0x02), Y)     // 0xB1, 0x02,

    CPX (0x0001)        // 0xEC, 0x01, 0x00,
    CPX (0x0002, X)     // <<<BAD
    CPX (0x0003, Y)     // <<<BAD
    CPX (_0x04)         // 0xE0, 0x04,
    CPX (0x05)          // 0xE4, 0x05,
    CPX ((0x04, X))     // <<<BAD
    CPX (0x03, X)       // <<<BAD
    CPX ((0x02), Y)     // <<<BAD

    RTS                 // 0x60
}

gcc -E main.c | grep -v "^#"

const unsigned char binary[] = {
    0xAD, 0x01, 0x00,
    0xBD, 0x02, 0x00,
    0xB9, 0x03, 0x00,
    0xA9, 0x04,
    0xA5, 0x05,
    0xA1, 0x04,
    0xB5, 0x03,
    0xB1, 0x02,

    0xEC, 0x01, 0x00,
    "CPX cannot be used with 2 arguments"
    "CPX cannot be used with 2 arguments"
    0xE0, 0x04,
    0xE4, 0x05,
    "CPX cannot be used with ZP-indirect syntax"
    "CPX cannot be used with 2 arguments"
    "CPX cannot be used with 2 arguments"

    0x60,
}

На компиляции, соответственно, высветит строку с ошибкой

P.S. Мне лень генерить чиселки, там сейчас саппорт от 0x0000 до 0x0005. Кому нужно - тот сам сгенерит строчки.

PPP328 ★★★★★
()
Последнее исправление: PPP328 (всего исправлений: 3)
Ответ на: комментарий от hateyoufeel

Работает? Работает. Лучше чем хаскель? Лучше - не требует указывать тип передачи. Остальное в контексте вопроса не важно.

PPP328 ★★★★★
()
Ответ на: комментарий от anonymous

Портянка в отдельном хэдере лежать будет, как и модуль, в котором хаскелевские преобразования написаны. Никогда на Си не писали?

PPP328 ★★★★★
()
Ответ на: комментарий от PPP328

Работает? Работает.

Не уверен. Я не запускал.

Лучше чем хаскель? Лучше - не требует указывать тип передачи.

Не лучше. Тип в хачкелле тоже можно не указывать, но автор библиотеки вот так вот порешил.

У хачкелловой версии есть куча плюшек. Например, вполне можно считать время выполнения кода и ставить ограничения на это. Функция больше 100500 тактов занимает? Получай ошибку! Вот ради таких плюх всё это тащемта и делают. Ну и ради лулзов, конечно же.

hateyoufeel ★★★★★
()
Последнее исправление: hateyoufeel (всего исправлений: 1)
Ответ на: комментарий от hateyoufeel

Не уверен. Я не запускал.

Я запускал. Выхлоп выше.

но автор библиотеки вот так вот порешил.

Ну вот когда порешит не указывать - тогда сравняемся. И чот я не уверен, что в каскеле можно отличить 0x00 от 0x0000, а в 6502 это вообще разные вещи.

PPP328 ★★★★★
()
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.