How about if, for PASM, we renamed these instructions to NOTF, ANDF, ORF and XORF (F for 'function', let's say)? XORF is just there for consistency.
Noooo..."AND", "OR", "XOR", "NOT", "ADD", "SUB", "MUL", "DIV", "JMP", etc are the fundamental things we expect a machine to do. They should not be obfuscated with a meaningless "F" here and there.
Higher level languages have "&", "|", "^", "~", etc to make such expressions concise.
Can I be extremist and suggest removing PASM and any kind of assembler from Spin altogether. Thus making such syntax issues easier.
One thing I'd like to do before getting this out is maybe clear up some name-space conflicts.
NOT, AND, and OR are both PASM instructions and boolean operators. This is going to cause headaches.
How about if, for PASM, we renamed these instructions to NOTF, ANDF, ORF and XORF (F for 'function', let's say)? XORF is just there for consistency.
Is that really necessary? Those keywords have had dual meanings in Spin/PASM for 11 years, and they've never caused any trouble. In PASM, the context (instruction vs. operand) is more than sufficient to distinguish between meanings.
-Phil
They're going to cause trouble in Spin2 for me, since all PASM instructions are also going to be methods, so people can get their feet wet.
How about if, for PASM, we renamed these instructions to NOTF, ANDF, ORF and XORF (F for 'function', let's say)? XORF is just there for consistency.
Noooo..."AND", "OR", "XOR", "NOT", "ADD", "SUB", "MUL", "DIV", "JMP", etc are the fundamental things we expect a machine to do. They should not be obfuscated with a meaningless "F" here and there.
Higher level languages have "&", "|", "^", "~", etc to make such expressions concise.
Can I be extremist and suggest removing PASM and any kind of assembler from Spin altogether. Thus making such syntax issues easier.
You can. You may be right. Phil hates the idea, too. I like simple, also.
I think since the current mission is to get some Spin2 framework up and running quickly, and since verilog is rightly frozen, it makes more sense to mess with the Spin2 tokens (at least for now).
I think Phil's right and there will be some way to sort them by context. It may require another pass or something. It'll probably become apparent during development.
Any value in doing that? It brings the convention in line with DIRL/DIRH/DIRN/etc.
Can you expand what each opcode actually does ? Does SETBC, move carry to BitD ?
SET/CLR are well understood, and someone many 'bitch' over those new names
NOTB I would have named CPLB
When asking these questions, can you give use examples, illustrating what the problem under discussion actually is ?
I'd generate new names, only if the shared ones cause some unsolvable side effects.
Any value in doing that? It brings the convention in line with DIRL/DIRH/DIRN/etc.
Can you expand what each opcode actually does ? Does SETBC, move carry to BitD ?
SET/CLR are well understood, and someone many 'bitch' over those new names
NOTB I would have named CPLB
When asking these questions, can you give use examples, illustrating what the problem under discussion actually is ?
I'd generate new names, only if the shared ones cause some unsolvable side effects.
Here are their functions:
ISOB D,{#}S {WC,WZ} Isolate bit S[4:0] of D. C = bit S[4:0] of D. *
NOTB D,{#}S {WC,WZ} Not bit S[4:0] of D. C = bit S[4:0] of D. *
CLRB D,{#}S {WC,WZ} Clear bit S[4:0] of D. C = bit S[4:0] of D. *
SETB D,{#}S {WC,WZ} Set bit S[4:0] of D. C = bit S[4:0] of D. *
SETBC D,{#}S {WC,WZ} Set bit S[4:0] of D to C. C = bit S[4:0] of D. *
SETBNC D,{#}S {WC,WZ} Set bit S[4:0] of D to !C. C = bit S[4:0] of D. *
SETBZ D,{#}S {WC,WZ} Set bit S[4:0] of D to Z. C = bit S[4:0] of D. *
SETBNZ D,{#}S {WC,WZ} Set bit S[4:0] of D to !Z. C = bit S[4:0] of D. *
I'll think I'll leave them as they are.
Okay, I'm not feeling like anything has to change. I'll get the compiles done.
Perhaps Spin methods for PASM instructions can just end with a "_". For example:
NOT_(Dv,S)
NOT_ will never be confused with NOT.
So these are intended as Assembler Wrappers, like a cleaner version of in-line ASM ?
(in line asm is still planned?)
In that case, yes, a common prefix or suffix char can group all of them as ASM derived.
One thing I'd like to do before getting this out is maybe clear up some name-space conflicts.
NOT, AND, and OR are both PASM instructions and boolean operators. This is going to cause headaches.
How about if, for PASM, we renamed these instructions to NOTF, ANDF, ORF and XORF (F for 'function', let's say)? XORF is just there for consistency.
Is that really necessary? Those keywords have had dual meanings in Spin/PASM for 11 years, and they've never caused any trouble. In PASM, the context (instruction vs. operand) is more than sufficient to distinguish between meanings.
-Phil
+1 (I have no problem, and would in fact prefer NOT, AND, OR, XOR.
Perhaps Spin methods for PASM instructions can just end with a "_". For example:
NOT_(Dv,S)
NOT_ will never be confused with NOT.
So these are intended as Assembler Wrappers, like a cleaner version of in-line ASM ?
(in line asm is still planned?)
In that case, yes, a common prefix or suffix char can group all of them as ASM derived.
It's not for in-line PASM, but for exercising individual instructions. This gives Spin access to the hardware functions without needing to repackage everything into some optimized and different format. In-line PASM will be allowed, too.
ISOB D,{#}S {WC,WZ} Isolate bit S[4:0] of D. C = bit S[4:0] of D. *
NOTB D,{#}S {WC,WZ} Not bit S[4:0] of D. C = bit S[4:0] of D. *
CLRB D,{#}S {WC,WZ} Clear bit S[4:0] of D. C = bit S[4:0] of D. *
SETB D,{#}S {WC,WZ} Set bit S[4:0] of D. C = bit S[4:0] of D. *
SETBC D,{#}S {WC,WZ} Set bit S[4:0] of D to C. C = bit S[4:0] of D. *
SETBNC D,{#}S {WC,WZ} Set bit S[4:0] of D to !C. C = bit S[4:0] of D. *
SETBZ D,{#}S {WC,WZ} Set bit S[4:0] of D to Z. C = bit S[4:0] of D. *
SETBNZ D,{#}S {WC,WZ} Set bit S[4:0] of D to !Z. C = bit S[4:0] of D. *
I'll think I'll leave them as they are.
Given those actual operations, I would have named them like this :
ISOB D,{#}S {WC,WZ} Isolate bit S[4:0] of D. C = bit S[4:0] of D. *
CPLB D,{#}S {WC,WZ} Toggle bit S[4:0] of D. C = bit S[4:0] of D. *
CLRB D,{#}S {WC,WZ} Clear bit S[4:0] of D. C = bit S[4:0] of D. *
SETB D,{#}S {WC,WZ} Set bit S[4:0] of D. C = bit S[4:0] of D. *
MOVBC D,{#}S {WC,WZ} Set bit S[4:0] of D to C. C = bit S[4:0] of D. *
MOVBNC D,{#}S {WC,WZ} Set bit S[4:0] of D to !C. C = bit S[4:0] of D. *
MOVBZ D,{#}S {WC,WZ} Set bit S[4:0] of D to Z. C = bit S[4:0] of D. *
MOVBNZ D,{#}S {WC,WZ} Set bit S[4:0] of D to !Z. C = bit S[4:0] of D. *
CY -> Bit is less of a SET and more of a COPY or MOVE operation.
Is the last 'C=' part dependent on the {WC} ?
What is 'isolate' ? is that intended to copy bit to C, aka MOVCB ?
Any value in doing that? It brings the convention in line with DIRL/DIRH/DIRN/etc.
I like the BITxxx instructions because it puts them together in documentation and instruction summaries, articularly since there is a family of them.
I would prefer this though...
BITISO --> BITX (extract bit)
Any value in doing that? It brings the convention in line with DIRL/DIRH/DIRN/etc.
I like the BITxxx instructions because it puts them together in documentation and instruction summaries, articularly since there is a family of them.
I would prefer this though...
BITISO --> BITX (extract bit)
ISOB D,{#}S {WC,WZ} Isolate bit S[4:0] of D. C = bit S[4:0] of D. *
NOTB D,{#}S {WC,WZ} Not bit S[4:0] of D. C = bit S[4:0] of D. *
CLRB D,{#}S {WC,WZ} Clear bit S[4:0] of D. C = bit S[4:0] of D. *
SETB D,{#}S {WC,WZ} Set bit S[4:0] of D. C = bit S[4:0] of D. *
SETBC D,{#}S {WC,WZ} Set bit S[4:0] of D to C. C = bit S[4:0] of D. *
SETBNC D,{#}S {WC,WZ} Set bit S[4:0] of D to !C. C = bit S[4:0] of D. *
SETBZ D,{#}S {WC,WZ} Set bit S[4:0] of D to Z. C = bit S[4:0] of D. *
SETBNZ D,{#}S {WC,WZ} Set bit S[4:0] of D to !Z. C = bit S[4:0] of D. *
I'll think I'll leave them as they are.
Given those actual operations, I would have named them like this :
ISOB D,{#}S {WC,WZ} Isolate bit S[4:0] of D. C = bit S[4:0] of D. *
CPLB D,{#}S {WC,WZ} Toggle bit S[4:0] of D. C = bit S[4:0] of D. *
CLRB D,{#}S {WC,WZ} Clear bit S[4:0] of D. C = bit S[4:0] of D. *
SETB D,{#}S {WC,WZ} Set bit S[4:0] of D. C = bit S[4:0] of D. *
MOVBC D,{#}S {WC,WZ} Set bit S[4:0] of D to C. C = bit S[4:0] of D. *
MOVBNC D,{#}S {WC,WZ} Set bit S[4:0] of D to !C. C = bit S[4:0] of D. *
MOVBZ D,{#}S {WC,WZ} Set bit S[4:0] of D to Z. C = bit S[4:0] of D. *
MOVBNZ D,{#}S {WC,WZ} Set bit S[4:0] of D to !Z. C = bit S[4:0] of D. *
CY -> Bit is less of a SET and more of a COPY or MOVE operation.
Is the last 'C=' part dependent on the {WC} ?
What is 'isolate' ? is that intended to copy bit to C, aka MOVCB ?
Isolate ANDs away all other bits in D, leaving only the bit of interest.
Use WC to get the value of the bit into C.
SETBC, for example, means copy C to the bit. Would you like BITC better?
Maybe this is all we need, as DIR/OUT instructions go:
EEEE 1101011 CZL DDDDDDDDD 001011000 DRVL {#}D {WC,WZ} OUT bit of pin D[5:0] = 0, DIR bit = 1, C/!Z = IN bit.
EEEE 1101011 CZL DDDDDDDDD 001011001 DRVH {#}D {WC,WZ} OUT bit of pin D[5:0] = 1, DIR bit = 1, C/!Z = IN bit.
EEEE 1101011 CZL DDDDDDDDD 001011010 DRVC {#}D {WC,WZ} OUT bit of pin D[5:0] = C, DIR bit = 1, C/!Z = IN bit.
EEEE 1101011 CZL DDDDDDDDD 001011011 DRVNC {#}D {WC,WZ} OUT bit of pin D[5:0] = !C, DIR bit = 1, C/!Z = IN bit.
EEEE 1101011 CZL DDDDDDDDD 001011100 DRVZ {#}D {WC,WZ} OUT bit of pin D[5:0] = Z, DIR bit = 1, C/!Z = IN bit.
EEEE 1101011 CZL DDDDDDDDD 001011101 DRVNZ {#}D {WC,WZ} OUT bit of pin D[5:0] = !Z, DIR bit = 1, C/!Z = IN bit.
EEEE 1101011 CZL DDDDDDDDD 001011110 DRVN {#}D {WC,WZ} OUT bit of pin D[5:0] = !bit, DIR bit = 1, C/!Z = IN bit.
EEEE 1101011 CZL DDDDDDDDD 001011111 FLT {#}D {WC,WZ} OUT bit of pin D[5:0] = 0, DIR bit = 0, C/!Z = IN bit.
Would that be complete?
I don't see any need/requirement for all the other cases. We don't need every possibility of FLT, just 0 and no change.
Can we then use PINxxx as follows, and add PINFLT ?
EEEE 1101011 CZL DDDDDDDDD 001011000 PINL {#}D {WC,WZ} OUT bit of pin D[5:0] = 0, DIR bit = 1, C/!Z = IN bit.
EEEE 1101011 CZL DDDDDDDDD 001011001 PINH {#}D {WC,WZ} OUT bit of pin D[5:0] = 1, DIR bit = 1, C/!Z = IN bit.
EEEE 1101011 CZL DDDDDDDDD 001011010 PINC {#}D {WC,WZ} OUT bit of pin D[5:0] = C, DIR bit = 1, C/!Z = IN bit.
EEEE 1101011 CZL DDDDDDDDD 001011011 PINNC {#}D {WC,WZ} OUT bit of pin D[5:0] = !C, DIR bit = 1, C/!Z = IN bit.
EEEE 1101011 CZL DDDDDDDDD 001011100 PINZ {#}D {WC,WZ} OUT bit of pin D[5:0] = Z, DIR bit = 1, C/!Z = IN bit.
EEEE 1101011 CZL DDDDDDDDD 001011101 PINNZ {#}D {WC,WZ} OUT bit of pin D[5:0] = !Z, DIR bit = 1, C/!Z = IN bit.
EEEE 1101011 CZL DDDDDDDDD 001011110 PIN {#}D {WC,WZ} OUT bit of pin D[5:0] = bit, DIR bit = 1, C/!Z = IN bit.
PINN {#}D {WC,WZ} OUT bit of pin D[5:0] = !bit, DIR bit = 1, C/!Z = IN bit.
EEEE 1101011 CZL DDDDDDDDD 001011111 PINFLTL {#}D {WC,WZ} OUT bit of pin D[5:0] = 0, DIR bit = 0, C/!Z = IN bit.
PINFLT {#}D {WC,WZ} OUT bit of pin D[5:0] = bit, DIR bit = 0, C/!Z = IN bit.
EEEE 1101011 CZL DDDDDDDDD 001001111 x PININ {#}D {WC,WZ} OUT bit of pin D[5:0] = bit, DIR bit = bit, C/!Z = IN bit.
I like the BITxxx instructions because it puts them together in documentation and instruction summaries, articularly since there is a family of them.
? You can group names in documents just fine without needing a common prefix, just as Chip already did above.
The family actually has 2 sub groups, using a common prefix rather cloaks that difference. IMO using 3 letters for BIT, instead of B, leaves precious few for the actual operation in the menmonic.
In my version, write/bit output commands SETB/CLRB/CPLB are clearly distinct from copy bit commands MOVxx
SETBC, for example, means copy C to the bit. Would you like BITC better?
The problem is the SET usually means 'Set value to logical 1', when the actual operation is a MOVE/Copy one.
BITC consumes too many mnemonic chars where B will do fine. (and gets a bit close to bitch?)
What is the complementary opcode for move a Bit to C ?
EEEE 1101011 CZL DDDDDDDDD 001011110 PIN {#}D {WC,WZ} OUT bit of pin D[5:0] = bit, DIR bit = 1, C/!Z = IN bit.
PINN {#}D {WC,WZ} OUT bit of pin D[5:0] = !bit, DIR bit = 1, C/!Z = IN bit.
PINFLT {#}D {WC,WZ} OUT bit of pin D[5:0] = bit, DIR bit = 0, C/!Z = IN bit.
EEEE 1101011 CZL DDDDDDDDD 001001111 x PININ {#}D {WC,WZ} OUT bit of pin D[5:0] = bit, DIR bit = bit, C/!Z = IN bit.
Where does bit mentioned here come from ?
I can see a need for CY -> DIR, which may be what you mean in the last line ?
SETBC, for example, means copy C to the bit. Would you like BITC better?
The problem is the SET usually means 'Set value to logical 1', when the actual operation is a MOVE/Copy one.
BITC consumes too many mnemonic chars where B will do fine. (and gets a bit close to bitch?)
What is the complementary opcode for move a Bit to C ?
We have 7 chars for mnemonics, so why is the prefix "BIT" too long? It describes perfectly what the instruction does - it changes a BIT.
We use C/NC/Z/NZ/L/H as the extensions.
We are missing a standard extension for...
NOT (INVERT) - possible extensions... N (not) / NB (not bit) / INV (invert) / V (invert)
and sometimes we need an extension for remaining the same...
possible extensions... S (same) / B (bit) / <blank> (same/bit)
The same would apply to "PIN" with the added extensions for "FLT" (float = DIR=0=input).
With regard to being able to place a family beginning with the same prefix, it is absolutely easier to document and summarise, because when one looks for something, one likes to look alphabetically. If the instruction set is compartmentalised, it it easy to search for, and simpler and shorter to describe a family, rather than each one separately.
Would you like me to look over the instruction grouping an produce a summary as I have done previously?
There may be some decoding simplification possible during synthesis if the instruction are grouped accordingly, as well as simplifying coding/decoding assemblers/compilers/deassemblers/debuggers.
If so, could post the instruction list before you compile the FPGA codes?
Would you like me to look over the instruction grouping an produce a summary as I have done previously?
There may be some decoding simplification possible during synthesis if the instruction are grouped accordingly, as well as simplifying coding/decoding assemblers/compilers/deassemblers/debuggers.
If so, could post the instruction list before you compile the FPGA codes?
Ummm... Didn't Chip just say that the Verilog was frozen?
1. Eliminate @@ -- not to mention the hideous @@@. Make @ mean "the address of", period, regardless of context. IOW, figure out the actual address at compile time, even if it means an extra compile pass or two, or maybe even a linking phase. In Spin, @ vs. @@ causes a lot of confusion, and neither is entirely adequate for the simple job they're supposed to perform.
2. Add the ternary operator: condition ? eval_if_true : eval_if_false. Probably have to use ?? and :: to avoid ambiguity with the random operator.
3. Something better has to be done with strings. Although the utility of string(...) for comma-separated lists is indisputable, it is pretty wordy, especially for simple strings like "abcdef". It would be nice to come up with some sort of shorthand notation. Maybe let a simple "abc" return a pointer the way string does. But what to do about "a", which returns $61 now. Require a pseudo-function, like ord? Actually, ord would be handy for strings up to 4 bytes in length, since they can be packed into a long.
4. "Lazy" Booleans (e.g. && ||). If the outcome of a Boolean expression is known before completion, quit evaluating the rest of it.
5. Variable-length argument lists. Allow stuff like
my_sum := sum(12, a, $56, x)
PUB sum(count, args[]) | i
repeat i from 0 to count - 1
result += args[i]
where count is implicitly assigned the value 4 in the above method call. This would come especially handy in formatting routines, where you have a format string à laprintf, followed by a list of values to print.
Anyway, that's some of it. I'll probably be adding more...
3. Something better has to be done with strings. Although the utility of string(...) for comma-separated lists is indisputable, it is pretty wordy, especially for simple strings like "abcdef". It would be nice to come up with some sort of shorthand notation. Maybe let a simple "abc" return a pointer the way string does. But what to do about "a", which returns $61 now. Require a pseudo-function, like ord? Actually, ord would be handy for strings up to 4 bytes in length, since they can be packed into a long.
How about @"asdf" instead of string("asdf")?
Also, how about supporting escape sequences to make it easier to embed quotes and newlines and such? And how about allowing embedded 0 bytes, trusting the programmer to be aware of the possible consequences of putting them in null-terminated strings?
Comments
Higher level languages have "&", "|", "^", "~", etc to make such expressions concise.
Can I be extremist and suggest removing PASM and any kind of assembler from Spin altogether. Thus making such syntax issues easier.
The "B" suffix would be my first choice, except that it already ends all the bit instructions:
Those could be changed to:
They're going to cause trouble in Spin2 for me, since all PASM instructions are also going to be methods, so people can get their feet wet.
You can. You may be right. Phil hates the idea, too. I like simple, also.
Okay. NOT, AND, OR, and XOR stay the same.
Into these...
Any value in doing that? It brings the convention in line with DIRL/DIRH/DIRN/etc.
I think Phil's right and there will be some way to sort them by context. It may require another pass or something. It'll probably become apparent during development.
Is this about the PASM procedures for all instructions being planned?
If so, then we should be able to name them somehow for that context, that doesn't make the PASM day to day assembly harder to understand.
Can you expand what each opcode actually does ? Does SETBC, move carry to BitD ?
SET/CLR are well understood, and someone many 'bitch' over those new names
NOTB I would have named CPLB
When asking these questions, can you give use examples, illustrating what the problem under discussion actually is ?
I'd generate new names, only if the shared ones cause some unsolvable side effects.
Perhaps Spin methods for PASM instructions can just end with a "_". For example:
NOT_(Dv,S)
NOT_ will never be confused with NOT.
Sorry for the frantic name concerns. I just want to get this straight before everyone is committed to it.
Here are their functions:
I'll think I'll leave them as they are.
Okay, I'm not feeling like anything has to change. I'll get the compiles done.
(in line asm is still planned?)
In that case, yes, a common prefix or suffix char can group all of them as ASM derived.
It's not for in-line PASM, but for exercising individual instructions. This gives Spin access to the hardware functions without needing to repackage everything into some optimized and different format. In-line PASM will be allowed, too.
CY -> Bit is less of a SET and more of a COPY or MOVE operation.
Is the last 'C=' part dependent on the {WC} ?
What is 'isolate' ? is that intended to copy bit to C, aka MOVCB ?
I would prefer this though...
BITISO --> BITX (extract bit)
I like BITX.
Isolate ANDs away all other bits in D, leaving only the bit of interest.
Use WC to get the value of the bit into C.
SETBC, for example, means copy C to the bit. Would you like BITC better?
Can we then use PINxxx as follows, and add PINFLT ? Some alternate possible naming options
PIN / PINB / PINDRV / PINOUT / PINENA
PINN / PINNB / PINDRVN / PINOUTN / PINENAN / PINNOT / PININV
The family actually has 2 sub groups, using a common prefix rather cloaks that difference. IMO using 3 letters for BIT, instead of B, leaves precious few for the actual operation in the menmonic.
In my version, write/bit output commands SETB/CLRB/CPLB are clearly distinct from copy bit commands MOVxx
The problem is the SET usually means 'Set value to logical 1', when the actual operation is a MOVE/Copy one.
BITC consumes too many mnemonic chars where B will do fine. (and gets a bit close to bitch?)
What is the complementary opcode for move a Bit to C ?
I can see a need for CY -> DIR, which may be what you mean in the last line ?
We have 7 chars for mnemonics, so why is the prefix "BIT" too long? It describes perfectly what the instruction does - it changes a BIT.
We use C/NC/Z/NZ/L/H as the extensions.
We are missing a standard extension for...
NOT (INVERT) - possible extensions... N (not) / NB (not bit) / INV (invert) / V (invert)
and sometimes we need an extension for remaining the same...
possible extensions... S (same) / B (bit) / <blank> (same/bit)
The same would apply to "PIN" with the added extensions for "FLT" (float = DIR=0=input).
With regard to being able to place a family beginning with the same prefix, it is absolutely easier to document and summarise, because when one looks for something, one likes to look alphabetically. If the instruction set is compartmentalised, it it easy to search for, and simpler and shorter to describe a family, rather than each one separately.
Would you like me to look over the instruction grouping an produce a summary as I have done previously?
There may be some decoding simplification possible during synthesis if the instruction are grouped accordingly, as well as simplifying coding/decoding assemblers/compilers/deassemblers/debuggers.
If so, could post the instruction list before you compile the FPGA codes?
No need to be sorry. Underscore seems great!
1. Eliminate @@ -- not to mention the hideous @@@. Make @ mean "the address of", period, regardless of context. IOW, figure out the actual address at compile time, even if it means an extra compile pass or two, or maybe even a linking phase. In Spin, @ vs. @@ causes a lot of confusion, and neither is entirely adequate for the simple job they're supposed to perform.
2. Add the ternary operator: condition ? eval_if_true : eval_if_false. Probably have to use ?? and :: to avoid ambiguity with the random operator.
3. Something better has to be done with strings. Although the utility of string(...) for comma-separated lists is indisputable, it is pretty wordy, especially for simple strings like "abcdef". It would be nice to come up with some sort of shorthand notation. Maybe let a simple "abc" return a pointer the way string does. But what to do about "a", which returns $61 now. Require a pseudo-function, like ord? Actually, ord would be handy for strings up to 4 bytes in length, since they can be packed into a long.
4. "Lazy" Booleans (e.g. && ||). If the outcome of a Boolean expression is known before completion, quit evaluating the rest of it.
5. Variable-length argument lists. Allow stuff like
where count is implicitly assigned the value 4 in the above method call. This would come especially handy in formatting routines, where you have a format string à la printf, followed by a list of values to print.
Anyway, that's some of it. I'll probably be adding more...
-Phil
How about @"asdf" instead of string("asdf")?
Also, how about supporting escape sequences to make it easier to embed quotes and newlines and such? And how about allowing embedded 0 bytes, trusting the programmer to be aware of the possible consequences of putting them in null-terminated strings?
Not sure how that could work, since the zeroes would terminate the string prematurely. Where would that be useful?
-Phil