about summary refs log blame commit diff stats
path: root/archive/2.transect/compiler8
blob: b3b3527152314968df1ae8b3830dba3c4250236e (plain) (tree)




















































                                                                                                    
== Goal

A memory-safe language with a simple translator to x86 that can be feasibly written in x86.

== Definitions of terms

Memory-safe: it should be impossible to:
  a) create a pointer out of arbitrary data, or
  b) to access heap memory after it's been freed.

Simple: do all the work in a 2-pass translator:
  Pass 1: check each instruction's types in isolation.
  Pass 2: emit code for each instruction in isolation.

== types

int
char
(address _)
(array _ n)
(ref _)

== implications

addresses can't be saved to stack or global,
      or included in compound types
      or used across a call (to eliminate possibility of free)

<reg x> : (address T) <- advance <reg/mem> : (array T), <reg offset> : (index T)

arrays require a size
(ref array _) may not include a size

argv has type (array (ref array char))

variables on stack, heap and global are references. The name points at the
address. Use '*' to get at the value.

instructions performing lookups write to register, so that we can reuse the register for temporaries
instructions performing lookups can't read from the register they write to.
  But most instructions read from the register they write to?! (in-out params)

== open questions

If bounds checks can take multiple instructions, why not perform array
indexing in a single statement in the language?

But we want addresses as intermediate points to combine instructions with.

Maybe disallow addresses to function calls, but allow addresses to non-heap
structures to be used spanning function calls and labels.

That's just for ergonomics. Doesn't add new capability.
e.Attribute */ .highlight .nb { color: #003388 } /* Name.Builtin */ .highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */ .highlight .no { color: #003366; font-weight: bold } /* Name.Constant */ .highlight .nd { color: #555555 } /* Name.Decorator */ .highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */ .highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */ .highlight .nl { color: #336699; font-style: italic } /* Name.Label */ .highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ .highlight .py { color: #336699; font-weight: bold } /* Name.Property */ .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
parse/0: instruction: 30
parse/0:   ingredient: {name: "location", value: 0, type: 0, properties: ["location": "type"]}
parse/0:   ingredient: {name: "30", value: 0, type: 0, properties: ["30": "literal"]}
parse/0:   product: {name: "default-space", value: 0, type: 2-0, properties: ["default-space": "address":"space"]}
parse/0: instruction: 30
parse/0:   ingredient: {name: "abc", value: 0, type: 0, properties: ["abc": "literal-string"]}
parse/0:   product: {name: "x", value: 0, type: 2-5-8, properties: ["x": "address":"array":"character"]}
parse/0: instruction: 100
parse/0:   ingredient: {name: "x", value: 0, type: 2-5-8, properties: ["x": "address":"array":"character"]}
parse/0:   ingredient: {name: "x", value: 0, type: 2-5-8, properties: ["x": "address":"array":"character"]}
parse/0:   product: {name: "3", value: 0, type: 3, properties: ["3": "boolean", "raw": ]}
new/0: location -> 1
new/0: abc -> 0
name/0: assign x 1
after-brace/0: recipe test-string-equal-reflexive
after-brace/0: new ...
after-brace/0: new ...
after-brace/0: string-equal ...
run/0: instruction test-string-equal-reflexive/0
mem/0: array size is 30
run/0: instruction test-string-equal-reflexive/1
mem/0: storing 1030 in location 1002
run/0: instruction test-string-equal-reflexive/2
mem/0: location 1002 is 1030
mem/0: location 1002 is 1030
run/0: instruction string-equal/0
mem/0: array size is 30
run/0: instruction string-equal/1
run/0: product 0 is 1030
mem/0: storing 1030 in location 1036
run/0: instruction string-equal/2
mem/0: location 1036 is 1030
mem/0: storing 3 in location 1037
run/0: instruction string-equal/3
run/0: product 0 is 1030
mem/0: storing 1030 in location 1038
run/0: instruction string-equal/4
mem/0: location 1038 is 1030
mem/0: storing 3 in location 1039
run/0: instruction string-equal/6
run/0: ingredient 0 is a-len
mem/0: location 1037 is 3
run/0: ingredient 1 is b-len
mem/0: location 1039 is 3
run/0: product 0 is 1
mem/0: storing 1 in location 1040
run/0: instruction string-equal/7
mem/0: location 1040 is 1
run/0: ingredient 0 is 1
run/0: ingredient 1 is 
run/0: jumping to instruction 9
run/0: instruction string-equal/10
run/0: ingredient 0 is 0
mem/0: storing 0 in location 1041
run/0: instruction string-equal/12
run/0: ingredient 0 is i
mem/0: location 1041 is 0
run/0: ingredient 1 is a-len
mem/0: location 1037 is 3
run/0: product 0 is 0
mem/0: storing 0 in location 1042
run/0: instruction string-equal/13
mem/0: location 1042 is 0
run/0: ingredient 0 is 0
run/0: jump-if fell through
run/0: instruction string-equal/14
run/0: ingredient 0 is {name: "a", value: 1, type: 2-5-8, properties: ["a": "address":"array":"character", "deref": ]}
mem/0: location 1036 is 1030
run/0: ingredient 1 is {name: "i", value: 6, type: 1, properties: ["i": "integer"]}
mem/0: location 1041 is 0
run/0: address to copy is 1031
run/0: its type is 8
mem/0: location 1031 is 97
run/0: product 0 is 97
mem/0: storing 97 in location 1043
run/0: instruction string-equal/15
run/0: ingredient 0 is {name: "b", value: 3, type: 2-5-8, properties: ["b": "address":"array":"character", "deref": ]}
mem/0: location 1038 is 1030
run/0: ingredient 1 is {name: "i", value: 6, type: 1, properties: ["i": "integer"]}
mem/0: location 1041 is 0
run/0: address to copy is 1031
run/0: its type is 8
mem/0: location 1031 is 97
run/0: product 0 is 97
mem/0: storing 97 in location 1044
run/0: instruction string-equal/17
run/0: ingredient 0 is a2
mem/0: location 1043 is 97
run/0: ingredient 1 is b2
mem/0: location 1044 is 97
run/0: product 0 is 1
mem/0: storing 1 in location 1045
run/0: instruction string-equal/18
mem/0: location 1045 is 1
run/0: ingredient 0 is 1
run/0: ingredient 1 is 
run/0: jumping to instruction 20
run/0: instruction string-equal/21
run/0: ingredient 0 is i
mem/0: location 1041 is 0
run/0: ingredient 1 is 1
run/0: product 0 is 1
mem/0: storing 1 in location 1041
run/0: instruction string-equal/22
run/0: ingredient 0 is -11
run/0: pc now 11
run/0: instruction string-equal/12
run/0: ingredient 0 is i
mem/0: location 1041 is 1
run/0: ingredient 1 is a-len
mem/0: location 1037 is 3
run/0: product 0 is 0
mem/0: storing 0 in location 1042
run/0: instruction string-equal/13
mem/0: location 1042 is 0
run/0: ingredient 0 is 0
run/0: jump-if fell through
run/0: instruction string-equal/14
run/0: ingredient 0 is {name: "a", value: 1, type: 2-5-8, properties: ["a": "address":"array":"character", "deref": ]}
mem/0: location 1036 is 1030
run/0: ingredient 1 is {name: "i", value: 6, type: 1, properties: ["i": "integer"]}
mem/0: location 1041 is 1
run/0: address to copy is 1032
run/0: its type is 8
mem/0: location 1032 is 98
run/0: product 0 is 98
mem/0: storing 98 in location 1043
run/0: instruction string-equal/15
run/0: ingredient 0 is {name: "b", value: 3, type: 2-5-8, properties: ["b": "address":"array":"character", "deref": ]}
mem/0: location 1038 is 1030
run/0: ingredient 1 is {name: "i", value: 6, type: 1, properties: ["i": "integer"]}
mem/0: location 1041 is 1
run/0: address to copy is 1032
run/0: its type is 8
mem/0: location 1032 is 98
run/0: product 0 is 98
mem/0: storing 98 in location 1044
run/0: instruction string-equal/17
run/0: ingredient 0 is a2
mem/0: location 1043 is 98
run/0: ingredient 1 is b2
mem/0: location 1044 is 98
run/0: product 0 is 1
mem/0: storing 1 in location 1045
run/0: instruction string-equal/18
mem/0: location 1045 is 1
run/0: ingredient 0 is 1
run/0: ingredient 1 is 
run/0: jumping to instruction 20
run/0: instruction string-equal/21
run/0: ingredient 0 is i
mem/0: location 1041 is 1
run/0: ingredient 1 is 1
run/0: product 0 is 2
mem/0: storing 2 in location 1041
run/0: instruction string-equal/22
run/0: ingredient 0 is -11
run/0: pc now 11
run/0: instruction string-equal/12
run/0: ingredient 0 is i
mem/0: location 1041 is 2
run/0: ingredient 1 is a-len
mem/0: location 1037 is 3
run/0: product 0 is 0
mem/0: storing 0 in location 1042
run/0: instruction string-equal/13
mem/0: location 1042 is 0
run/0: ingredient 0 is 0
run/0: jump-if fell through
run/0: instruction string-equal/14
run/0: ingredient 0 is {name: "a", value: 1, type: 2-5-8, properties: ["a": "address":"array":"character", "deref": ]}
mem/0: location 1036 is 1030
run/0: ingredient 1 is {name: "i", value: 6, type: 1, properties: ["i": "integer"]}
mem/0: location 1041 is 2
run/0: address to copy is 1033
run/0: its type is 8
mem/0: location 1033 is 99
run/0: product 0 is 99
mem/0: storing 99 in location 1043
run/0: instruction string-equal/15
run/0: ingredient 0 is {name: "b", value: 3, type: 2-5-8, properties: ["b": "address":"array":"character", "deref": ]}
mem/0: location 1038 is 1030
run/0: ingredient 1 is {name: "i", value: 6, type: 1, properties: ["i": "integer"]}
mem/0: location 1041 is 2
run/0: address to copy is 1033
run/0: its type is 8
mem/0: location 1033 is 99
run/0: product 0 is 99
mem/0: storing 99 in location 1044
run/0: instruction string-equal/17
run/0: ingredient 0 is a2
mem/0: location 1043 is 99
run/0: ingredient 1 is b2
mem/0: location 1044 is 99
run/0: product 0 is 1
mem/0: storing 1 in location 1045
run/0: instruction string-equal/18
mem/0: location 1045 is 1
run/0: ingredient 0 is 1
run/0: ingredient 1 is 
run/0: jumping to instruction 20
run/0: instruction string-equal/21
run/0: ingredient 0 is i
mem/0: location 1041 is 2
run/0: ingredient 1 is 1
run/0: product 0 is 3
mem/0: storing 3 in location 1041
run/0: instruction string-equal/22
run/0: ingredient 0 is -11
run/0: pc now 11
run/0: instruction string-equal/12
run/0: ingredient 0 is i
mem/0: location 1041 is 3
run/0: ingredient 1 is a-len
mem/0: location 1037 is 3
run/0: product 0 is 1
mem/0: storing 1 in location 1042
run/0: instruction string-equal/13
mem/0: location 1042 is 1
run/0: ingredient 0 is 1
run/0: ingredient 1 is 
run/0: jumping to instruction 23
run/0: instruction string-equal/24
run/0: result 0 is 1
mem/0: storing 1 in location 3