Skip to content

Commit 7d18c75

Browse files
authored
Merge pull request #55 from qupa-project/constant-argument
Constant argument
2 parents f5773df + 9b6ee41 commit 7d18c75

File tree

13 files changed

+73
-63
lines changed

13 files changed

+73
-63
lines changed

changelog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
- [x] Elif statement
1515
- [x] Fixed inverted signedness issues on integer comparison
1616
- [x] Escaped string characters
17+
- [x] Constant Function Arguments
1718

1819
## Fixes
1920
- [x] Bug with nested structure access

compiler/component/execution/base.js

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -176,15 +176,6 @@ class ExecutionBase {
176176
template
177177
);
178178

179-
if (type === null) {
180-
return null;
181-
}
182-
183-
// Linear types are handled by address, not value
184-
if (type.type.typeSystem == "linear") {
185-
type.pointer++;
186-
}
187-
188179
return type;
189180
}
190181

compiler/component/execution/index.js

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -80,12 +80,6 @@ class Execution extends ExecutionFlow {
8080
this.getFile().throw(`Error: Invalid type name "${Flattern.DataTypeStr(ast.tokens[0])}"`, ast.ref.start, ast.ref.end);
8181
return null;
8282
}
83-
typeRef.localLife = ast.tokens[0];
84-
85-
// Complex types are handled by address, not value
86-
if (typeRef.type.typeSystem == "linear" || typeRef.type instanceof Array) {
87-
typeRef.pointer++;
88-
}
8983

9084
this.scope.register_Var(
9185
typeRef,

compiler/component/function_instance.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,10 @@ class Function_Instance {
6868
// Flaten signature types AST into a single array
6969
let types = [ head.tokens[0] ];
7070
let borrows = [ false ];
71+
let consts = [ false ];
7172
if (args.length > 0) {
72-
borrows = borrows.concat(args.map(x => x[0]));
73+
borrows = borrows.concat(args.map(x => x[0] == "@"));
74+
consts = consts.concat(args.map(x => x[0] == "#"));
7375
types = types.concat(args.map((x) => x[1]));
7476
}
7577

@@ -83,8 +85,9 @@ class Function_Instance {
8385
for (let [i, type] of types.entries()){
8486
let search = exec.resolveType(type);
8587
if (search instanceof TypeRef) {
86-
search.pointer = type.tokens[0]; // Copy the pointer level across
87-
search.lent = borrows[i];
88+
search.pointer = type.tokens[0]; // Copy the pointer level across
89+
search.lent = borrows[i];
90+
search.constant = consts[i];
8891

8992
this.signature.push(search);
9093
} else {

compiler/component/memory/scope.js

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -71,15 +71,17 @@ class Scope {
7171
));
7272

7373
// Assigning name space to argument value
74-
let chg = this.variables[arg.name].markUpdated(new LLVM.Argument(
75-
this.variables[arg.name].type.toLLVM(),
76-
new LLVM.Name(id.reference(), false)
77-
),
78-
true,
79-
{
80-
start: arg.ref,
81-
end: arg.ref
82-
});
74+
let chg = this.variables[arg.name].markUpdated(
75+
new LLVM.Argument(
76+
this.variables[arg.name].type.toLLVM(),
77+
new LLVM.Name(id.reference(), false)
78+
),
79+
true,
80+
{
81+
start: arg.ref,
82+
end: arg.ref
83+
}
84+
);
8385
if (chg.error) {
8486
this.getFile().throw(chg.msg, chg.ref.start, chg.ref.end);
8587
return null;
@@ -248,7 +250,7 @@ class Scope {
248250
// If the value is undefined in all states
249251
// Resolve the result to be undefined with no errors
250252
if (!branches.map( x => x.scope.variables[name].isUndefined()).includes(false)) {
251-
this.variables[name].makeUndefined();
253+
this.variables[name].makeUndefined(ref);
252254
continue;
253255
}
254256

compiler/component/memory/variable.js

Lines changed: 37 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -152,19 +152,28 @@ class Variable extends Value {
152152
msg: "Cannot give ownership of a borrowed value to a child function",
153153
ref
154154
};
155+
} else if (this.type.constant) {
156+
return {
157+
error: true,
158+
msg: `Cannot consume a constant value\n Recommend cloning $${this.name}`,
159+
ref
160+
};
155161
}
156162

157-
this.makeUndefined();
163+
this.makeUndefined(ref);
158164
this.lastUninit = ref.start;
159165
}
160166

161167
out.type = this.type;
162168
return out;
163169
}
164170

165-
makeUndefined() {
166-
this.store = null;
171+
makeUndefined(ref) {
172+
this.elements.clear();
173+
this.isDecomposed = false;
167174
this.probability = null;
175+
this.store = null;
176+
this.lastUninit = ref.start;
168177
}
169178

170179
/**
@@ -175,19 +184,26 @@ class Variable extends Value {
175184
* @returns {Error?}
176185
*/
177186
markUpdated (register, force = false, ref) {
178-
if (!force && this.type.lent) {
179-
return {
180-
error: true,
181-
msg: "Cannot overwite a lent value",
182-
ref
183-
};
187+
if (!force) {
188+
if (this.type.lent) {
189+
return {
190+
error: true,
191+
msg: "Cannot overwite a lent value",
192+
ref
193+
};
194+
} else if (this.type.constant) {
195+
return {
196+
error: true,
197+
msg: "Cannot overwite a constant value",
198+
ref
199+
};
200+
}
184201
}
185202

186-
this.store = register;
203+
this.isDecomposed = false;
187204
this.probability = null;
188-
this.lastUninit = null;
189205
this.hasUpdated = true;
190-
this.isDecomposed = false;
206+
this.store = register;
191207

192208
return true;
193209
}
@@ -235,6 +251,7 @@ class Variable extends Value {
235251
let out;
236252
if (!this.elements.has(gep.index)) {
237253
let read = struct.accessGEPByIndex(gep.index, this.store);
254+
read.type.constant = read.type.constant || this.type.constant;
238255
out = new Variable(
239256
read.type,
240257
`${this.name}.${accessor}`,
@@ -712,7 +729,7 @@ class Variable extends Value {
712729
cleanup(ref) {
713730
let frag = new LLVM.Fragment();
714731

715-
if (this.isClone) { // Do nothing as this variable is a clone
732+
if (this.isClone || this.type.constant) { // Do nothing as this variable is a clone/constant
716733
return frag;
717734
} else if (this.type.lent) { // Borrowed types need to be recomposed
718735
let res = this.resolve(ref, false);
@@ -750,13 +767,15 @@ class Variable extends Value {
750767
msg: "Cannot delete an already undefined value",
751768
ref: ref
752769
};
770+
} else if (this.type.constant) {
771+
return {
772+
error: true,
773+
msg: "Cannot delete a constant value",
774+
ref: ref
775+
};
753776
}
754777

755-
this.elements = new Map();
756-
this.isDecomposed = false;
757-
this.probability = null;
758-
this.store = null;
759-
this.lastUninit = ref.start;
778+
this.makeUndefined(ref);
760779
return new LLVM.Fragment();
761780
}
762781
}

compiler/component/struct.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ class Structure extends TypeDef {
144144
return {
145145
preamble: preamble,
146146
instruction: val,
147-
type: type
147+
type: type.duplicate()
148148
};
149149
}
150150

@@ -226,12 +226,11 @@ class Structure extends TypeDef {
226226

227227
let term = new Struct_Term(
228228
name,
229-
new TypeRef(typeNode.tokens[0], typeRef.type),
229+
new TypeRef(0, typeRef.type),
230230
node.ref.start
231231
);
232232
this.terms.push(term);
233233
this.size += term.size;
234-
235234
return true;
236235
}
237236

compiler/component/typeRef.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,11 @@ class TypeRef {
99
* @param {Number} pointerLvl
1010
* @param {Type} type
1111
*/
12-
constructor (pointerLvl, type, lent = false) {
12+
constructor (pointerLvl, type, lent = false, constant = false) {
1313
this.pointer = pointerLvl;
1414
this.type = type;
1515
this.lent = lent;
16+
this.constant = constant;
1617
}
1718

1819
getName () {
@@ -55,7 +56,7 @@ class TypeRef {
5556
* Creates a clone of this reference
5657
*/
5758
duplicate () {
58-
return new TypeRef(this.pointer, this.type, this.lent);
59+
return new TypeRef(this.pointer, this.type, this.lent, this.constant);
5960
}
6061

6162

compiler/parser/parse.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -700,7 +700,7 @@ function Simplify_Func_Args_List (node) {
700700
let ittr = node.tokens[0].concat(node.tokens[2].map(x => x.tokens[2][0]));
701701

702702
node.tokens = ittr.map((arg) => [
703-
arg.tokens[4].length > 0, // borrowed?
703+
arg.tokens[4][0] ? arg.tokens[4][0].tokens : null, // borrowed?
704704
Simplify_Data_Type(arg.tokens[6][0]), // type
705705
Simplify_Name(arg.tokens[0][0]) // name
706706
]);

compiler/parser/syntax.bnf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ program ::= w* ( stmt_top w* )*
8383
func_head ::= "fn" w+ name w* func_arguments w* ( ":" w* data_type )?
8484
func_arguments ::= "(" w* func_arg_list? ")"
8585
func_arg_list ::= func_arg w* ( "," w* func_arg w* )*
86-
func_arg ::= name w* ":" w* "@"? w* data_type
86+
func_arg ::= name w* ":" w* ( "@" | "#" )? w* data_type
8787
function_body ::= "{" w* ( func_stmt w* )* "}"
8888
func_stmt ::= comment | if | return | composition | declare | delete | assign | declare_assign | call_procedure
8989

0 commit comments

Comments
 (0)