Author Topic: The Imperium programming language - IPL  (Read 71613 times)

0 Members and 3 Guests are viewing this topic.

Offline DiTBho

  • Super Contributor
  • ***
  • Posts: 3944
  • Country: gb
Re: A microcontroller programming language
« Reply #500 on: December 19, 2022, 04:40:48 am »
The first kernel of riscos was written in arm-assembly, but with smart macros

The first kernel of amigaos was written in m68k-macro-assembly, and somehow looked like "C--"

Linux is written in C but emulating some OO capabilities, somehow looks "C+" (not "C++", but emulating some of its features)

The first word Linux driver written in Rust for apple m1 is interesting

« Last Edit: December 19, 2022, 04:47:38 am by DiTBho »
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 
The following users thanked this post: MK14

Online SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14647
  • Country: fr
Re: A microcontroller programming language
« Reply #501 on: December 19, 2022, 04:47:42 am »
The first word Linux driver written in Rust for apple m1 is interesting

Have you looked at it?
 

Offline gnuarm

  • Super Contributor
  • ***
  • Posts: 2246
  • Country: pr
Re: A microcontroller programming language
« Reply #502 on: December 19, 2022, 05:23:12 am »
Quote
Calling it a trick or a hack is silly.  I designed a bit slice processor as a DMA controller for an array processor (the supercomputer of the 70s).  I wanted to use some instructions that I created, which were not part of the assembler by default.  I added them.  QA didn't complain.  I just had to document it.

Whatever, emitted how, so?
If it's inline asm DC. Then it's an hack.

I don't recall, that was nearly 50 years ago.  I seem to recall one supervisor being initially upset that technically, this used a different assembler, so it must not have been a DC, rather a "hack" to the assembler code. 

But once it was thoroughly documented in the project, he was happy.

You should never learn Forth coding.  I am confident it would blow your mind... and not in the good way.  Some people aren't bound so rigidly.


Quote
Quote
QA didn't complain.  I just had to document it.

Doc is good but doesn't pay money.
Code rejected means no money.

Sorry, you are incomprehensible.  Can you speak English?
Rick C.  --  Puerto Rico is not a country... It's part of the USA
  - Get 1,000 miles of free Supercharging
  - Tesla referral code - https://ts.la/richard11209
 

Offline gnuarm

  • Super Contributor
  • ***
  • Posts: 2246
  • Country: pr
Re: A microcontroller programming language
« Reply #503 on: December 19, 2022, 05:49:15 am »
Quote
PostScript works best in a non-interactive batch processing mode.

This is the exact opposite of Forth... well, I shouldn't say opposite.  Forth handles batch mode just fine.  But the interactivity of Forth is a powerful debugging technique.

EVERY programming language works better in non-interactive mode for large and complex programs.

That's very bogus.  Any large program is developed in pieces, which are defined in pieces, etc., until they constitute small programs. 

When people run an ICE on a project, they are using the same methods used interactively, but with much more complexity because of the massive code base.

Forth is actually a bit famous for simplifying most coding.  Once you learn the philosophy, it becomes second nature to work in the "Forth" way testing the lower level code thoroughly before integrating at the next level. 

But people who are entrenched with using tools like ICE, don't appreciate, or possibly understand simpler ways of working.


Quote
It's not the opposite of Forth, it's similar to Forth except BETTER for interactive programming and debugging, because Postscript is late-binding by default.

I was responding to this quote from the web page...

"PostScript works best in a non-interactive batch processing mode."

Now you are saying Postscript is interactive.  Someone needs to make up their minds.


Quote
This means that you can define your words in any order, whether the words they use have been defined already or not, and you can re-define a word while debugging and existing words will automatically use the new definition.

I'm no expert on compilation, but it sounds to me that late-binding would be a bit slow.


Quote
This is not possible (or at least is not usually done) in address-threaded or subroutine-threaded Forth. It is more easily done in token-threaded Forth (the slowest implementation).

When speed is needed, individual functions or even bodies of IFs or loops can be early-bound (address-threaded, essentially)

Actually, Forth supports something similar, using words DEFER and IS.  This must be set up at compile time, but can be changed at run time.  So interactive debugging with alternate definitions for a given word is supported.  There is no run time penalty on most systems, while on others it would be slight.  It is essentially like changing the subroutine call by using an intermediary. 

I've used this for changing an interface between a serial port or a socket connection.
Rick C.  --  Puerto Rico is not a country... It's part of the USA
  - Get 1,000 miles of free Supercharging
  - Tesla referral code - https://ts.la/richard11209
 
The following users thanked this post: MK14

Offline DiTBho

  • Super Contributor
  • ***
  • Posts: 3944
  • Country: gb
Re: A microcontroller programming language
« Reply #504 on: December 19, 2022, 05:51:08 am »
The first word Linux driver written in Rust for apple m1 is interesting

Have you looked at it?

Yup. I looked at it in very superficial ways, I have no specific RUST knowledge to make judgments.
I will  :-//
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline brucehoult

  • Super Contributor
  • ***
  • Posts: 4087
  • Country: nz
Re: A microcontroller programming language
« Reply #505 on: December 19, 2022, 06:01:38 am »
EVERY programming language works better in non-interactive mode for large and complex programs.

That's very bogus.  Any large program is developed in pieces, which are defined in pieces, etc., until they constitute small programs. 

When people run an ICE on a project, they are using the same methods used interactively, but with much more complexity because of the massive code base.

Forth is actually a bit famous for simplifying most coding.  Once you learn the philosophy, it becomes second nature to work in the "Forth" way testing the lower level code thoroughly before integrating at the next level. 

But people who are entrenched with using tools like ICE, don't appreciate, or possibly understand simpler ways of working.

I wouldn't know an ICE if it bit me in the arse.

BASIC is interactive. Python is interactive. Both are better written in a text editor, except in rare circumstances where you don't know WTF the the language does or want to poke at some peripheral.

Quote
Quote
It's not the opposite of Forth, it's similar to Forth except BETTER for interactive programming and debugging, because Postscript is late-binding by default.

I was responding to this quote from the web page...

"PostScript works best in a non-interactive batch processing mode."

Now you are saying Postscript is interactive.  Someone needs to make up their minds.

Dude, that's not my web page. It's the opinion of someone who is not in this discussion.

Something being interactive doesn't mean you want to work that way all the time.

Quote
Quote
This means that you can define your words in any order, whether the words they use have been defined already or not, and you can re-define a word while debugging and existing words will automatically use the new definition.

I'm no expert on compilation, but it sounds to me that late-binding would be a bit slow.

OF COURSE it is. It's also far more flexible. That's why lots and lots of people program most of their application logic in slow-as-molasses Python, and do the few bits where you can tell the difference in C.

It's better if you can do it all in one language.

Quote
Quote
This is not possible (or at least is not usually done) in address-threaded or subroutine-threaded Forth. It is more easily done in token-threaded Forth (the slowest implementation).

When speed is needed, individual functions or even bodies of IFs or loops can be early-bound (address-threaded, essentially)

Actually, Forth supports something similar, using words DEFER and IS.  This must be set up at compile time, but can be changed at run time.  So interactive debugging with alternate definitions for a given word is supported.  There is no run time penalty on most systems, while on others it would be slight.  It is essentially like changing the subroutine call by using an intermediary. 

Which means Forth has is bass-ackwards, as the flexible slow method should be the DEFAULT. not something you have to jump through hoops to get.

I've been using Forth, on and off for more than 40 years, when appropriate. And PostScript for 37 years.
 

Offline cfbsoftware

  • Regular Contributor
  • *
  • Posts: 118
  • Country: au
    • Astrobe: Oberon IDE for Cortex-M and FPGA Development
Re: A microcontroller programming language
« Reply #506 on: December 19, 2022, 06:02:57 am »
Quote
These bit patterns can be emitted directly by the compiler without using an assembler.     
emitted how? By inline asm DC?
No. All of the code generated by our Oberon compilers (as is true for most, if not all, of Prof Wirth's compilers based on) is written as 16-bit or 32-bit words directly into the binary file. No assembly code is generated; no assembler pass is necessary or is used.

e.g. for the Project Oberon RISC5 FPGA compiler:

Quote
Instructions are emitted sequentially and emitted by the four procedures Put0, Put1, Put2, Put3. They directly correspond to the instruction formats of the RISC processor (see Chapter 11). The instructions are stored in the array code and the compiler variable pc serves as running index.

https://people.inf.ethz.ch/wirth/ProjectOberon/PO.Applications.pdf


Chris Burrows
CFB Software
https://www.astrobe.com
 
The following users thanked this post: MK14

Offline gnuarm

  • Super Contributor
  • ***
  • Posts: 2246
  • Country: pr
Re: A microcontroller programming language
« Reply #507 on: December 19, 2022, 06:35:59 am »
EVERY programming language works better in non-interactive mode for large and complex programs.

That's very bogus.  Any large program is developed in pieces, which are defined in pieces, etc., until they constitute small programs. 

When people run an ICE on a project, they are using the same methods used interactively, but with much more complexity because of the massive code base.

Forth is actually a bit famous for simplifying most coding.  Once you learn the philosophy, it becomes second nature to work in the "Forth" way testing the lower level code thoroughly before integrating at the next level. 

But people who are entrenched with using tools like ICE, don't appreciate, or possibly understand simpler ways of working.

I wouldn't know an ICE if it bit me in the arse.

BASIC is interactive. Python is interactive. Both are better written in a text editor, except in rare circumstances where you don't know WTF the the language does or want to poke at some peripheral.

I think you fail to understand.  No one writes Forth code at the console, then writing it again into an editor.  But when you have unexpected results, you can retype the definition in question and explore what it does... interactively.  Interactive debugging. 

Interactive is a good way to first pass test the code by running it with corner cases of data input.  In fact, many Forth users include the test code with their source so it can be tested at any time.


Quote
Quote
Quote
It's not the opposite of Forth, it's similar to Forth except BETTER for interactive programming and debugging, because Postscript is late-binding by default.

I was responding to this quote from the web page...

"PostScript works best in a non-interactive batch processing mode."

Now you are saying Postscript is interactive.  Someone needs to make up their minds.

Dude, that's not my web page. It's the opinion of someone who is not in this discussion.

Fine, but it was posted.  If you didn't post it, why are you responding???


Quote
Something being interactive doesn't mean you want to work that way all the time.

Who said you have to work interactively all the time? 

You seem very jumpy about this.  What is bothering you?


Quote
Quote
Quote
This means that you can define your words in any order, whether the words they use have been defined already or not, and you can re-define a word while debugging and existing words will automatically use the new definition.

I'm no expert on compilation, but it sounds to me that late-binding would be a bit slow.

OF COURSE it is. It's also far more flexible. That's why lots and lots of people program most of their application logic in slow-as-molasses Python, and do the few bits where you can tell the difference in C.

It's better if you can do it all in one language.

Quote
Quote
This is not possible (or at least is not usually done) in address-threaded or subroutine-threaded Forth. It is more easily done in token-threaded Forth (the slowest implementation).

When speed is needed, individual functions or even bodies of IFs or loops can be early-bound (address-threaded, essentially)

Actually, Forth supports something similar, using words DEFER and IS.  This must be set up at compile time, but can be changed at run time.  So interactive debugging with alternate definitions for a given word is supported.  There is no run time penalty on most systems, while on others it would be slight.  It is essentially like changing the subroutine call by using an intermediary. 

Which means Forth has is bass-ackwards, as the flexible slow method should be the DEFAULT. not something you have to jump through hoops to get.

I've been using Forth, on and off for more than 40 years, when appropriate. And PostScript for 37 years.

Yeah, you have a bug up your rear about this.  I would like to discuss this with you, but you are just so argumentative. 

You have your opinions (very strong ones) and I have mine.  Thanks for sharing.
Rick C.  --  Puerto Rico is not a country... It's part of the USA
  - Get 1,000 miles of free Supercharging
  - Tesla referral code - https://ts.la/richard11209
 
The following users thanked this post: MK14

Offline Kalvin

  • Super Contributor
  • ***
  • Posts: 2145
  • Country: fi
  • Embedded SW/HW.
Re: A microcontroller programming language
« Reply #508 on: December 19, 2022, 09:19:52 am »
Here are my 2c (Did not read through the whole thread, so please forgive me if these are dupilcates):

1. In C the arrays are quite problematic when passed to functions, because the length of the array is not implicitly passed as an argument. So, the new language should pass the length of an array implicitly to the function to be called. The length of the passed array needs to be accessible inside the called function. Enabling/disabling run-time checks for validating array accesses should be supported globally / by compilation unit / by function, and during unit testing. Also, when passing a variable or an array as a void*, the caller should pass the total size of the item in bytes to the called function.

2. In C handling of endianess when declaring structs and bit fields required some work in order to make code portable across different architectures: Keywords and language constructs for native / big endian / little endian should be provided, and the compiler should take care of producing code for the correct endianess.

3. In C the padding of structs requires careful design to get it right, especially when porting to different architectures. The compiler should provide simple and intuitive means for specifying and asserting the padding.

4. Design by contract (https://en.wikipedia.org/wiki/Design_by_contract) should be supported natively by the compiler so that the verification of the contracts can be enabled during compilation time and when running the unit tests. The run-time validation of the contract asserts, pre- and postcondition contracts should be controllable globally / by compilation unit / by function when creating for the actual production build. In C this can be done using macros, but this should be built-in into the language, and should be supported during run-time system.

5. Modern C compilers complain when comparing unsigned value to a signed value, which is good. But modern C compilers allow assigning unsigned variables to signed variables, and vice versa. Assigning unsigned variables to signed variables, and vice versa, should be flagged as an error by default in general. Literal values should be casted automatically by the compiler, of course. If the user wants to assign signed variables to unsigned variables, and vice versa, the operation should be done explicitly by the programmer.

6. Native 8-bit unsigned and signed data types, and a separate 8-bit char data type which is not compatible with the integer types without proper casting.

7. Strict type checking. For example the following should not be allowed without explicit cast, because they are declared to be different data types although they are both int8_t types at the end of the day:

Code: [Select]
typedef int8_t apple_t;
typedef int8_t orange_t;

apple_t apples = 0;
orange_t oranges = 0;

apples = oranges; /* This should be flagged as an error without explicit cast */

Edit:
8. More intuitive way to work with bits/bitmasks.
« Last Edit: December 19, 2022, 09:26:54 am by Kalvin »
 

Offline Sherlock HolmesTopic starter

  • Frequent Contributor
  • **
  • !
  • Posts: 570
  • Country: us
Re: A microcontroller programming language
« Reply #509 on: December 19, 2022, 11:11:53 am »
Here are my 2c (Did not read through the whole thread, so please forgive me if these are dupilcates):

1. In C the arrays are quite problematic when passed to functions, because the length of the array is not implicitly passed as an argument. So, the new language should pass the length of an array implicitly to the function to be called. The length of the passed array needs to be accessible inside the called function. Enabling/disabling run-time checks for validating array accesses should be supported globally / by compilation unit / by function, and during unit testing. Also, when passing a variable or an array as a void*, the caller should pass the total size of the item in bytes to the called function.

2. In C handling of endianess when declaring structs and bit fields required some work in order to make code portable across different architectures: Keywords and language constructs for native / big endian / little endian should be provided, and the compiler should take care of producing code for the correct endianess.

3. In C the padding of structs requires careful design to get it right, especially when porting to different architectures. The compiler should provide simple and intuitive means for specifying and asserting the padding.

4. Design by contract (https://en.wikipedia.org/wiki/Design_by_contract) should be supported natively by the compiler so that the verification of the contracts can be enabled during compilation time and when running the unit tests. The run-time validation of the contract asserts, pre- and postcondition contracts should be controllable globally / by compilation unit / by function when creating for the actual production build. In C this can be done using macros, but this should be built-in into the language, and should be supported during run-time system.

5. Modern C compilers complain when comparing unsigned value to a signed value, which is good. But modern C compilers allow assigning unsigned variables to signed variables, and vice versa. Assigning unsigned variables to signed variables, and vice versa, should be flagged as an error by default in general. Literal values should be casted automatically by the compiler, of course. If the user wants to assign signed variables to unsigned variables, and vice versa, the operation should be done explicitly by the programmer.

6. Native 8-bit unsigned and signed data types, and a separate 8-bit char data type which is not compatible with the integer types without proper casting.

7. Strict type checking. For example the following should not be allowed without explicit cast, because they are declared to be different data types although they are both int8_t types at the end of the day:

Code: [Select]
typedef int8_t apple_t;
typedef int8_t orange_t;

apple_t apples = 0;
orange_t oranges = 0;

apples = oranges; /* This should be flagged as an error without explicit cast */

Edit:
8. More intuitive way to work with bits/bitmasks.

This is an excellent post, very helpful. I will respond later, many of the points you raise were already being considered but you've include several insightful additions.
“When you have eliminated all which is impossible, then whatever remains, however improbable, must be the truth.” ~ Arthur Conan Doyle, The Case-Book of Sherlock Holmes
 

Offline DiTBho

  • Super Contributor
  • ***
  • Posts: 3944
  • Country: gb
Re: A microcontroller programming language
« Reply #510 on: December 19, 2022, 12:34:30 pm »
I don't recall, that was nearly 50 years ago.  I seem to recall one supervisor being initially upset that technically, this used a different assembler, so it must not have been a DC, rather a "hack" to the assembler code. 

No way, if it was a C file with assembly inline DC, it was an hack!

my-c can fix this, but it requires an advanced set of internal mechanisms to define new operators that map to new hw opcodes in a consistent way to let the compiler know their boundaries, their negative side effect (if any), provide ways to observe and verify (this is useful for ICE test cases) and also provide code rejection on error.

[] -> { ok, maybe, nothing }

But once it was thoroughly documented in the project, he was happy.

documenting hacks, well ... yes, bettern than nothing

You should never learn Forth coding.  I am confident it would blow your mind... and not in the good way.  Some people aren't bound so rigidly.

I have ZERO interest in Forth. It's not even close to what I think.
I make programs in C and Ada for a living.
Recently I am looking at RUST with interest.

Sorry, you are incomprehensible.  Can you speak English?

You said that QA doesn't complain (when) you just have to document your code.
I said that doc is always a good practice but doesn't pay money.

to pay : give someone something in return for { work done, goods received, debt incurred, favor done }

pay(someone, something) ->
{
work done: your clients(code commited, QA passed) -> return you money
favor done: your colleagues(code documented, hacks demystified) -> return you gratitude
}

Documenting things is always a great thing, it helps you with future work on the same code, it repays your colleagues gratitude in return (if they have to work on your code), but what only matters to you at the end of the week is whether the code passes or fails QA.

My customers won't pay a cent for the document, and won't pay a cent if the code fails QA.

Thus, documenting has a lower priority.
It's not good, but it's how it works.
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline Kalvin

  • Super Contributor
  • ***
  • Posts: 2145
  • Country: fi
  • Embedded SW/HW.
Re: A microcontroller programming language
« Reply #511 on: December 19, 2022, 12:41:01 pm »
One final note: Classical if - then - elseif - else probelm. My suggestion is something like this:

Code: [Select]
if (expr)
  stmts;
elif (expr)
  stmts;
else
  stmts;
endif

Thus a simple test:

Code: [Select]
if (expr)
  stmts;
endif

A simple test with else clause:

Code: [Select]
if (expr)
  stmts;
else
  stmts;
endif

etc.
 
The following users thanked this post: Sherlock Holmes

Offline newbrain

  • Super Contributor
  • ***
  • Posts: 1736
  • Country: se
Re: A microcontroller programming language
« Reply #512 on: December 19, 2022, 12:51:43 pm »
7. Strict type checking. For example the following should not be allowed without explicit cast, because they are declared to be different data types although they are both int8_t types at the end of the day:

Code: [Select]
typedef int8_t apple_t;
typedef int8_t orange_t;

apple_t apples = 0;
orange_t oranges = 0;

apples = oranges; /* This should be flagged as an error without explicit cast */

Such a strict type checking might be good, or not. Opinions differ.
Not even Pascal does what you are suggesting.

Would you also object to apples = apples + 1; ?
If not, why not? It's a new type (casting away the fact that typedef in C does not introduce new types, only synonyms: C11 6.7.8 §3).

Shouldn't it be apples = (apple_t)((int8_t)apples + 1);?

After all, apple_t and int8_t are no longer the same type (if they were, so would be orange_t and we are back to C semantics), so why should I expect to have the same operations defined on them.

BTW: what would be the if-then-else if-else problem?
Nandemo wa shiranai wa yo, shitteru koto dake.
 

Offline Kalvin

  • Super Contributor
  • ***
  • Posts: 2145
  • Country: fi
  • Embedded SW/HW.
Re: A microcontroller programming language
« Reply #513 on: December 19, 2022, 01:03:04 pm »
Would you also object to apples = apples + 1; ?
If not, why not? It's a new type (casting away the fact that typedef in C does not introduce new types, only synonyms: C11 6.7.8 §3).

Shouldn't it be apples = (apple_t)((int8_t)apples + 1);?

After all, apple_t and int8_t are no longer the same type (if they were, so would be orange_t and we are back to C semantics), so why should I expect to have the same operations defined on them.

The assignment and mixed arithmetic between different types should not be allowed by default.

These are just fine:
Code: [Select]
apples = apples + 1;
apples++;
apples = (apples << 1) | 1;

However, mixed arithmetic between different types should not be allowed by default:
Code: [Select]
apples = 1 + oranges;
apples = (oranges << 1) | 1;
apples = apples + oranges * 2

BTW: what would be the if-then-else if-else problem?

The classical dangling else problem, and accidental missing braces in C.

Edit:
typedef in C does not introduce new types, only synonyms: C11 6.7.8 §3)
I would like to see that typedef defines a new type. For declaring a synonym, a new keyword alias** for example, should be used instead.
** alias may not be a good keyword here, but you get the idea.
« Last Edit: December 19, 2022, 01:11:54 pm by Kalvin »
 

Offline DiTBho

  • Super Contributor
  • ***
  • Posts: 3944
  • Country: gb
Re: A microcontroller programming language
« Reply #514 on: December 19, 2022, 01:06:32 pm »
4. Design by contract

my-c does exactly that with both language-specific support and ICE. I'm very happy that someone finally talked about it ;D

it is very useful during the develpment phases, great later during test cases for test-reports, which then my customers are very happy to pay for, not only because it certifies (with reproducible procedures) QA passed, but also because they can easily re-use most of the code to create production "diagnostics".
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline Sherlock HolmesTopic starter

  • Frequent Contributor
  • **
  • !
  • Posts: 570
  • Country: us
Re: A microcontroller programming language
« Reply #515 on: December 19, 2022, 01:19:21 pm »
Here are my 2c (Did not read through the whole thread, so please forgive me if these are dupilcates):

1. In C the arrays are quite problematic when passed to functions, because the length of the array is not implicitly passed as an argument. So, the new language should pass the length of an array implicitly to the function to be called. The length of the passed array needs to be accessible inside the called function. Enabling/disabling run-time checks for validating array accesses should be supported globally / by compilation unit / by function, and during unit testing. Also, when passing a variable or an array as a void*, the caller should pass the total size of the item in bytes to the called function.

This is a language goal. The problem was solved years ago and is available to us straight from PL/I, here's how I envisage it looking in revised grammar: (this grammar is being actively developed currently, based on PL/I but slowly being revised as language goals solidify).

Code: [Select]

dcl matrix(10,20) string(64) varying;

func scan_for_text(table) returns bool

   arg table(*,*) string(64);

   var x = Dim(table,0);  // i.e 10
   var y = Dim(table,1);  // i.e 20

   var isup = is_uppercase(table(3,7));

end

func is_uppercase(text) returns bool

   arg text string(*);

end


Enabling dynamic access to array and varying string metadata is fundamental, I'm glad you raised it.


2. In C handling of endianess when declaring structs and bit fields required some work in order to make code portable across different architectures: Keywords and language constructs for native / big endian / little endian should be provided, and the compiler should take care of producing code for the correct endianess.

This is interesting, I know that Arm supports both types, how would you envisage this looking to a developer? what aspects of code are influenced by this?

3. In C the padding of structs requires careful design to get it right, especially when porting to different architectures. The compiler should provide simple and intuitive means for specifying and asserting the padding.

I agree, PL/I was richer in this area, taking that and revising it is a goal, controlling alignment, physical member ordering, padding, with control at the structure level and member level.

4. Design by contract (https://en.wikipedia.org/wiki/Design_by_contract) should be supported natively by the compiler so that the verification of the contracts can be enabled during compilation time and when running the unit tests. The run-time validation of the contract asserts, pre- and postcondition contracts should be controllable globally / by compilation unit / by function when creating for the actual production build. In C this can be done using macros, but this should be built-in into the language, and should be supported during run-time system.

Completely new area to me! I've read bits about it in Ada and Spark, I need to study this more, unsure of how to quantify the scope, but it could well impact grammar design so should be thought about early on.

5. Modern C compilers complain when comparing unsigned value to a signed value, which is good. But modern C compilers allow assigning unsigned variables to signed variables, and vice versa. Assigning unsigned variables to signed variables, and vice versa, should be flagged as an error by default in general. Literal values should be casted automatically by the compiler, of course. If the user wants to assign signed variables to unsigned variables, and vice versa, the operation should be done explicitly by the programmer.

Well first off, strict consistency is an absolute must, different policies in different circumstances is just asking for problems. Scenarios that can lead to unexpected, non-intuitive outcomes are a real problem, this falls into exception support area too.

6. Native 8-bit unsigned and signed data types, and a separate 8-bit char data type which is not compatible with the integer types without proper casting.

Again PL/I was attentive here, it had the 'char' data type, in essence a 'byte' with no concept of sign. For numeric use we can do this:

Code: [Select]

dcl counter bin(8) signed;
dcl totals bin(16) unsigned;
dcl rate bin(16,4) signed;
dcl interim bin(12); // defaults to signed (perhaps)


This shows the arbitrary fixed point binary types, fixed decimal is included as well.

7. Strict type checking. For example the following should not be allowed without explicit cast, because they are declared to be different data types although they are both int8_t types at the end of the day:

Code: [Select]
typedef int8_t apple_t;
typedef int8_t orange_t;

apple_t apples = 0;
orange_t oranges = 0;

apples = oranges; /* This should be flagged as an error without explicit cast */


8. More intuitive way to work with bits/bitmasks.

Type conversion is a big area here, PL/I never supported user defined type names, but it should be supported. Whether it simply be analogous to C's typedef, I'm not sure yet. It makes little sense to me though, to allow a new type name to be defined for an existing type name, no idea why C allows that.

As for bit fields and stuff, the 'bit' is a native language data type here. One can declare bit strings (akin to our familiar) character strings. And I envisage 'pad' as a type too, one can declare multiple explicit padding members if desired and all pad members can even have the same name if so desired, easing readability of code.

Thanks again for your detailed post!
“When you have eliminated all which is impossible, then whatever remains, however improbable, must be the truth.” ~ Arthur Conan Doyle, The Case-Book of Sherlock Holmes
 

Offline Kalvin

  • Super Contributor
  • ***
  • Posts: 2145
  • Country: fi
  • Embedded SW/HW.
Re: A microcontroller programming language
« Reply #516 on: December 19, 2022, 01:31:06 pm »
Last thing for now: Checked assignments, which will be checked at run-time so that the compiler will generate code to check that the assigned value is within the allowed numerical range of the variable where the results will be assigned to. Trying to assign a value outside the allowed range will generate a run-time error. This feature should be enabled during unit testing, and should be controllable (enable/disable) globally / by compilation unit / by function during build time.

Just some random thoughts: Probably a new operator := could be defined for checked assignment. Probably a checked block could be defined so that all assignments inside the checked block will be checked during run-time if the compile-time option for the checked assignment was enabled globally or by compilation unit / by function. **. I dunno.

Edit:
** Maybe some kind of saturated assignment could be defined so that if the value to be assigned is outside the valid numerical range, the programmer can provide the upper and lower limits of a value to be assigned. If the programmer doesn't provide the limits, the compiler will use the minimum and maximum values automagically? Just thinking aloud here.
« Last Edit: December 19, 2022, 01:47:08 pm by Kalvin »
 

Offline DiTBho

  • Super Contributor
  • ***
  • Posts: 3944
  • Country: gb
Re: A microcontroller programming language
« Reply #517 on: December 19, 2022, 01:54:07 pm »
I know that Arm supports both types, how would you envisage this looking to a developer? what aspects of code are influenced by this?

Endianness

At early boot, SONY PSX1 (MIPS R3000), as well as POWER10, can be configured LE or BE with one bit.
Once configured, it is active and cannot be easily changed until the hardware is reset.

Sony configured the PSX1 CPU as LE. Years ago I hacked the firmware with a ROMemulator to force it as BE. Kind of toy-hack, funny to do, nothing serious.

Taylos sells their POWER10 configured as LE, so I reflashed my boss's POWER10 workstation firmware to be PPC64/BE compliant. This saved me houndred hours of work, because I only have PPC64/BE stages available and prepairing a PPC64/LE .... costs no less than two weeks.

Sure, with POWER10, MIPS5+ and some modern ARMs there are also instructions that convert the data { 16, 32 } bits LE <----> BE.

Mac_part, which is BE because designed for PowerMac, is one of the recent things I fixed on ARM64, which is LE and can't be forced BE without pain.

So, I wrote a C function to convert endianness. Easy job, you can even "inline" it. When you mind its needs, well, you find it only requires endianness conversion when mounting a partition, and it's fine that way until unmount.

Coprocessors and high-internet-working like Tulip chip can offload CPU but when they shoot ... they wants BE-only (and your target is LE) large-block data ready, so it can be worth the effort of an assembly module that directly use hardware instructions.

It depends on how often you need it.

I mean, nice to have feature, but it's not a primary need  :-//
« Last Edit: December 19, 2022, 02:03:14 pm by DiTBho »
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline Sherlock HolmesTopic starter

  • Frequent Contributor
  • **
  • !
  • Posts: 570
  • Country: us
Re: A microcontroller programming language
« Reply #518 on: December 19, 2022, 02:09:24 pm »
I know that Arm supports both types, how would you envisage this looking to a developer? what aspects of code are influenced by this?

Endianness

At early boot, SONY PSX1 (MIPS R3000), as well as POWER10, can be configured LE or BE with one bit.
Once configured, it is active and cannot be easily changed until the hardware is reset.

Sony configured the PSX1 CPU as LE. Years ago I hacked the firmware with a ROMemulator to force it as BE. Kind of toy-hack, funny to do, nothing serious.

Taylos sells their POWER10 configured as LE, so I reflashed my boss's POWER10 workstation firmware to be PPC64/BE compliant. This saved me houndred hours of work, because I only have PPC64/BE stages available and prepairing a PPC64/LE .... costs no less than two weeks.

Sure, with POWER10, MIPS5+ and some modern ARMs there are also instructions that convert the data { 16, 32 } bits LE <----> BE.

Mac_part, which is BE because designed for PowerMac, is one of the recent things I fixed on ARM64, which is LE and can't be forced BE without pain.

So, I wrote a C function to convert endianness. Easy job, you can even "inline" it. When you mind its needs, well, you find it only requires endianness conversion when mounting a partition, and it's fine that way until unmount.

Coprocessors and high-internet-working like Tulip chip can offload CPU but when they shoot ... they wants BE-only (and your target is LE) large-block data ready, so it can be worth the effort of an assembly module that directly use hardware instructions.

It depends on how often you need it.

I mean, nice to have feature, but it's not a primary need  :-//

So what are the code constructs that are not symmetrical with respect to endianness? For example a = b + c ; will (semantically) behave the same way yes? what code does not or would not behave symmetrically?


“When you have eliminated all which is impossible, then whatever remains, however improbable, must be the truth.” ~ Arthur Conan Doyle, The Case-Book of Sherlock Holmes
 

Offline gnuarm

  • Super Contributor
  • ***
  • Posts: 2246
  • Country: pr
Re: A microcontroller programming language
« Reply #519 on: December 19, 2022, 02:14:20 pm »
I don't recall, that was nearly 50 years ago.  I seem to recall one supervisor being initially upset that technically, this used a different assembler, so it must not have been a DC, rather a "hack" to the assembler code. 

No way, if it was a C file with assembly inline DC, it was an hack!

I don't think I was clear.  I'm saying the assembler tool was most likely modified to support the added instruction(s).


Quote
my-c can fix this, but it requires an advanced set of internal mechanisms to define new operators that map to new hw opcodes in a consistent way to let the compiler know their boundaries, their negative side effect (if any), provide ways to observe and verify (this is useful for ICE test cases) and also provide code rejection on error.

[] -> { ok, maybe, nothing }

But once it was thoroughly documented in the project, he was happy.

documenting hacks, well ... yes, bettern than nothing

You should never learn Forth coding.  I am confident it would blow your mind... and not in the good way.  Some people aren't bound so rigidly.

I have ZERO interest in Forth. It's not even close to what I think.
I make programs in C and Ada for a living.
Recently I am looking at RUST with interest.

Yes, I fully expected this.


Quote
Sorry, you are incomprehensible.  Can you speak English?

You said that QA doesn't complain (when) you just have to document your code.
I said that doc is always a good practice but doesn't pay money.

to pay : give someone something in return for { work done, goods received, debt incurred, favor done }

pay(someone, something) ->
{
work done: your clients(code commited, QA passed) -> return you money
favor done: your colleagues(code documented, hacks demystified) -> return you gratitude
}

I don't need you to be a dictionary.  I just need you to use the English language well.


Quote
Documenting things is always a great thing, it helps you with future work on the same code, it repays your colleagues gratitude in return (if they have to work on your code), but what only matters to you at the end of the week is whether the code passes or fails QA.

Spoken like a hack.


Quote
My customers won't pay a cent for the document, and won't pay a cent if the code fails QA.

Thus, documenting has a lower priority.
It's not good, but it's how it works.

Where you live perhaps.

One of my jobs was 100% documentation.  The only code I wrote was to support documentation. 
Rick C.  --  Puerto Rico is not a country... It's part of the USA
  - Get 1,000 miles of free Supercharging
  - Tesla referral code - https://ts.la/richard11209
 

Offline DiTBho

  • Super Contributor
  • ***
  • Posts: 3944
  • Country: gb
Re: A microcontroller programming language
« Reply #520 on: December 19, 2022, 02:27:37 pm »
So what are the code constructs that are not symmetrical with respect to endianness? For example a = b + c ; will (semantically) behave the same way yes? what code does not or would not behave symmetrically?

Once BE/LE defined at boot (x86 is LE-only, it's hw wired that way), a CPU has an endianness, and so it operates untill reset.

Problems are with the load/store only when it has to access devices that has/need different endianness.
Here you need endianess conversion.

The simplest example is mac_part.
Fields are BE when you read them from the partition on the disk.
You read BE, you convert LE, so your LE-CPU (x86) can understand fields.
You keep them LE in your CPU memory space untill you need to modify something and update its copy on disk. So, you convert LE back to BE, and force sync.

With the Co-Processor, you prepare a temporary buffer, LE to BE, to feed its needs.
And you consume its block-response, BE to LE, to serve your kernel driver needs.
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline gnuarm

  • Super Contributor
  • ***
  • Posts: 2246
  • Country: pr
Re: A microcontroller programming language
« Reply #521 on: December 19, 2022, 02:29:36 pm »
7. Strict type checking. For example the following should not be allowed without explicit cast, because they are declared to be different data types although they are both int8_t types at the end of the day:

Code: [Select]
typedef int8_t apple_t;
typedef int8_t orange_t;

apple_t apples = 0;
orange_t oranges = 0;

apples = oranges; /* This should be flagged as an error without explicit cast */

Such a strict type checking might be good, or not. Opinions differ.
Not even Pascal does what you are suggesting.

Would you also object to apples = apples + 1; ?
If not, why not? It's a new type (casting away the fact that typedef in C does not introduce new types, only synonyms: C11 6.7.8 §3).

Shouldn't it be apples = (apple_t)((int8_t)apples + 1);?

After all, apple_t and int8_t are no longer the same type (if they were, so would be orange_t and we are back to C semantics), so why should I expect to have the same operations defined on them.

BTW: what would be the if-then-else if-else problem?

I code with Forth  and VHDL.  Forth has types, but no type checking.  VHDL has the sorts of type checking as shown above (or close to it).  I don't know that VHDL tools have ever found an actual bug in my code through type checking.  It has caused me to do an awful lot of type conversions/casts though.
Rick C.  --  Puerto Rico is not a country... It's part of the USA
  - Get 1,000 miles of free Supercharging
  - Tesla referral code - https://ts.la/richard11209
 
The following users thanked this post: newbrain

Offline DiTBho

  • Super Contributor
  • ***
  • Posts: 3944
  • Country: gb
Re: A microcontroller programming language
« Reply #522 on: December 19, 2022, 02:31:54 pm »
I don't need you to be a dictionary.  I just need you to use the English language well.
Porn website.
Spoken like a hack.
Where you live perhaps.

Alright, enjoy my ignore list.
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 
The following users thanked this post: brucehoult

Offline Sherlock HolmesTopic starter

  • Frequent Contributor
  • **
  • !
  • Posts: 570
  • Country: us
Re: A microcontroller programming language
« Reply #523 on: December 19, 2022, 02:32:15 pm »
Last thing for now: Checked assignments, which will be checked at run-time so that the compiler will generate code to check that the assigned value is within the allowed numerical range of the variable where the results will be assigned to. Trying to assign a value outside the allowed range will generate a run-time error. This feature should be enabled during unit testing, and should be controllable (enable/disable) globally / by compilation unit / by function during build time.

Just some random thoughts: Probably a new operator := could be defined for checked assignment. Probably a checked block could be defined so that all assignments inside the checked block will be checked during run-time if the compile-time option for the checked assignment was enabled globally or by compilation unit / by function. **. I dunno.

Edit:
** Maybe some kind of saturated assignment could be defined so that if the value to be assigned is outside the valid numerical range, the programmer can provide the upper and lower limits of a value to be assigned. If the programmer doesn't provide the limits, the compiler will use the minimum and maximum values automagically? Just thinking aloud here.

PL/I was (it seems) the first high level language to support exceptions (termed "conditions" in that language, following IBM naming conventions with their old PSW mainframe register). This was a huge help in the development of Multics and was used to confine bugs or restrict their impact. Their syntax was different to say Java or C# or C++, but that's just a detail. The way it worked was the same.

This included system generated exceptions as well as programmer defined, so I full expect that to be an inherent language feature here.

Runtime checks are important too, array bounds checks are non-negotiable, optional yes but always available if needed. There are also two distinct types of array bound checks, lets call them "shallow" and "deep".

The shallow check is very quick and checks only that the identified array element is part of the array, e.g.

Code: [Select]

dcl table(10,10) bin(16);

table(4,11) = 100; // passes shallow check because it access absolute element 51 out of 100, a valid array element.

The deep check is more costly and checks that each subscripts lies within the declared bounds. Failing a shallow check is still a bug but cannot directly corrupt memory, these are options I'd make available to the developer (or will be, if I take this forward seriously).

But I fully support these kinds of runtime checking options, enabled for new, barely exercised code and perhaps disabled in once a certain level of confidence is achieved, perhaps these options could be specified granularly too in some way as you suggest above, perhaps even enabled or disabled at runtime...


« Last Edit: December 19, 2022, 02:51:22 pm by Sherlock Holmes »
“When you have eliminated all which is impossible, then whatever remains, however improbable, must be the truth.” ~ Arthur Conan Doyle, The Case-Book of Sherlock Holmes
 

Offline Sherlock HolmesTopic starter

  • Frequent Contributor
  • **
  • !
  • Posts: 570
  • Country: us
Re: A microcontroller programming language
« Reply #524 on: December 19, 2022, 02:49:50 pm »
So what are the code constructs that are not symmetrical with respect to endianness? For example a = b + c ; will (semantically) behave the same way yes? what code does not or would not behave symmetrically?

Once BE/LE defined at boot (x86 is LE-only, it's hw wired that way), a CPU has an endianness, and so it operates untill reset.

Problems are with the load/store only when it has to access devices that has/need different endianness.
Here you need endianess conversion.

The simplest example is mac_part.
Fields are BE when you read them from the partition on the disk.
You read BE, you convert LE, so your LE-CPU (x86) can understand fields.
You keep them LE in your CPU memory space untill you need to modify something and update its copy on disk. So, you convert LE back to BE, and force sync.

With the Co-Processor, you prepare a temporary buffer, LE to BE, to feed its needs.
And you consume its block-response, BE to LE, to serve your kernel driver needs.

OK I see, so there's a runtime need to sometimes convert the endianness of data that's been input to the system in some way, from some external source, that's interesting. So we could allow code to discover the current endianness at runtime and also facilitate such conversions, e.g.

Code: [Select]

dcl IsBigEndian builtin;
dcl LittleEndian builtin;

// assume this data item has been populated by some IO read, and some_ptr has therefore been set

dcl partition_data bin(32) signed based(some_ptr);

if IsBigEndian() then // Both builtin functions are included for convenience, so we also have IsLittleEndian
   partition_data = LittleEndian (partition_data);
end


Is this sufficient? does this capture the gist of this? It could be extended too so that we can do this to a structure, where all endian dependent members are automatically taken care of:

Code: [Select]

data_header = LittleEndian (data_header);


Where data_header is an aggregate like an array/structure or both, this would impact numeric fields, floats and pointers/offsets even...
« Last Edit: December 19, 2022, 02:53:59 pm by Sherlock Holmes »
“When you have eliminated all which is impossible, then whatever remains, however improbable, must be the truth.” ~ Arthur Conan Doyle, The Case-Book of Sherlock Holmes
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf