Skip to content

Commit

Permalink
Boilerplate for handling completions
Browse files Browse the repository at this point in the history
  • Loading branch information
Ahnfelt committed Apr 16, 2023
1 parent 7936f41 commit 79906d7
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 44 deletions.
80 changes: 40 additions & 40 deletions compiler/Inference.ff
Original file line number Diff line number Diff line change
Expand Up @@ -233,9 +233,9 @@ extend self: Inference {
throw(CompileError(at, "This kind of pattern is not allowed for newtypes"))
}
self.unification.unify(at, expected, instantiated.scheme.signature.returnType)
let parameters = instantiated.scheme.signature.parameters.sortBy { _.name }
let parameters = instantiated.scheme.signature.parameters.sortBy {_.name}
let recordType =
TConstructor(at, "Record$" + parameters.map { _.name }.join("$"), parameters.map { _.valueType })
TConstructor(at, "Record$" + parameters.map {_.name}.join("$"), parameters.map {_.valueType})
if(self.hoverAt.contains(at)) {
self.hoverResult = Some(recordType)
}
Expand All @@ -252,7 +252,7 @@ extend self: Inference {
}
patterns.zip(instantiated.scheme.signature.parameters).map {| Pair(pattern, parameter) =>
self.inferPattern(environment, parameter.valueType, pattern)
}.foldLeft(Map.empty[String, Type]()) { _.addAll(_) }
}.foldLeft(Map.empty[String, Type]()) {_.addAll(_)}
}
}

Expand All @@ -267,16 +267,16 @@ extend self: Inference {
| EInt _ => literal("Int")
| EFloat _ => literal("Float")
| EVariable e =>
self.lookup(environment, e.at, e.name, []).map { instantiated =>
self.lookup(environment, e.at, e.name, []).map {instantiated =>
if(instantiated.scheme.isVariable) {
self.unification.unify(e.at, expected, instantiated.scheme.signature.returnType)
term
} else {
self.inferEtaExpansion(
environment,
expected,
e.at,
instantiated.scheme.signature,
environment
expected
e.at
instantiated.scheme.signature
term
)
}
Expand All @@ -289,7 +289,7 @@ extend self: Inference {
self.unification.substitute(recordType).{
| TConstructor(_, name, typeArguments)@t {name.startsWith("Record$")} =>
let fieldNames = name.split('$').toList().dropFirst(1)
fieldNames.pairs().find { _.second == e.field }.map { _.first }.map { index =>
fieldNames.pairs().find {_.second == e.field}.map {_.first}.map {index =>
let t1 = typeArguments.grab(index)
self.unification.unify(e.at, expected, t1)
e.EField(record = record)
Expand All @@ -305,8 +305,8 @@ extend self: Inference {
parameters = instantiated.scheme.signature.parameters.dropFirst(1)
)
self.unification.unify(
e.at,
recordType,
e.at
recordType
instantiated.scheme.signature.parameters.grab(0).valueType
)
self.inferEtaExpansion(environment, expected, e.at, signature, term)
Expand All @@ -325,22 +325,22 @@ extend self: Inference {
throw(CompileError(e.at, "No such field " + e.field + " on unknown type: $" + index))
}
| EWildcard e =>
self.lookup(environment, e.at, "_w" + e.index, []).map { instantiated =>
self.lookup(environment, e.at, "_w" + e.index, []).map {instantiated =>
self.unification.unify(e.at, expected, instantiated.scheme.signature.returnType)
term
}.grab()
| EList(at, t, items) =>
let listType = TConstructor(term.at, core("List"), [t])
self.unification.unify(at, expected, listType)
EList(at, t, items.map { | Pair(item, spread) =>
Pair(self.inferTerm(environment, if(spread) { listType } else { t }, item), spread)
EList(at, t, items.map {| Pair(item, spread) =>
Pair(self.inferTerm(environment, if(spread) {listType} else {t}, item), spread)
})
| ESequential(at, before, after) =>
let newExpected = self.unification.freshUnificationVariable(at)
before.{
| EPipe(at1, value, effect1, ELambda(at2, Lambda(at3, effect3, cases))) =>
let e = EVariant(at, "ff:core/Unit.Unit", [], None)
let newCases = cases.map { case => case.MatchCase(body = ESequential(case.at, case.body, e)) }
let newCases = cases.map {case => case.MatchCase(body = ESequential(case.at, case.body, e))}
let newPipe = EPipe(at1, value, effect1, ELambda(at2, Lambda(at3, effect3, newCases)))
after.{
| EVariant(at, "ff:core/Unit.Unit", _, _) =>
Expand Down Expand Up @@ -385,24 +385,24 @@ extend self: Inference {
self.inferArguments(e.at, environment, instantiated.scheme.signature.parameters, _)
}
e.EVariant(
typeArguments = instantiated.typeArguments.map { _.second }
typeArguments = instantiated.typeArguments.map {_.second}
arguments = arguments
)
| EVariantIs e =>
let instantiated = self.lookup(environment, e.at, e.name, e.typeArguments).else {
throw(CompileError(e.at, "Symbol not in scope: " + e.name))
}
let parameters = instantiated.scheme.signature.parameters.sortBy { _.name }
let parameters = instantiated.scheme.signature.parameters.sortBy {_.name}
let recordType =
TConstructor(e.at, "Record$" + parameters.map { _.name }.join("$"), parameters.map { _.valueType })
TConstructor(e.at, "Record$" + parameters.map {_.name}.join("$"), parameters.map {_.valueType})
let functionType = TConstructor(e.at, "Function$1", [
self.unification.freshUnificationVariable(e.at),
self.unification.freshUnificationVariable(e.at)
instantiated.scheme.signature.returnType
TConstructor(e.at, core("Option"), [recordType])
])
self.unification.unify(e.at, expected, functionType)
e.EVariantIs(
typeArguments = instantiated.typeArguments.map { _.second }
typeArguments = instantiated.typeArguments.map {_.second}
)
| ECopy e =>
let scheme = self.lookup(environment, e.at, e.name, []).else {
Expand All @@ -412,12 +412,12 @@ extend self: Inference {
throw(CompileError(e.at, "Newtypes can't be copied"))
}
let signature = scheme.signature
let parameterNames = signature.parameters.map { _.name }
e.arguments.find { a => !parameterNames.any { _ == a.name } }.each {
let parameterNames = signature.parameters.map {_.name}
e.arguments.find {a => !parameterNames.any {_ == a.name}}.each {
| Field(at, name, value) => throw(CompileError(at, "Unknown parameter: " + name))
}
let arguments = parameterNames.map { name =>
e.arguments.find { _.name == name }.map {
let arguments = parameterNames.map {name =>
e.arguments.find {_.name == name}.map {
| Field(at, _, value) => Argument(at, Some(name), value)
}.else {
Argument(e.at, Some(name), EField(e.at, False, EVariable(e.at, "_c"), name))
Expand All @@ -432,8 +432,8 @@ extend self: Inference {
| EPipe e =>
let valueType = self.unification.freshUnificationVariable(e.at)
let functionType = TConstructor(e.at, "Function$1", [
e.effect,
valueType,
e.effect
valueType
expected
])
let value = self.inferTerm(environment, valueType, e.value)
Expand All @@ -450,7 +450,7 @@ extend self: Inference {
}
call.function.{
| EVariable(variableAt, x) =>
if(x.first().any { c => c != '_' && !c.isAsciiLetter() }) {
if(x.first().any {c => c != '_' && !c.isAsciiLetter()}) {
self.inferOperator(environment, expected, x, term)
} else {
self.lookup(environment, e.at, x, e.typeArguments).{
Expand Down Expand Up @@ -509,7 +509,7 @@ extend self: Inference {
}
| ERecord e =>
let fields = e.fields.sortBy {_.name}
let fieldTypes = fields.map { self.unification.freshUnificationVariable(_.at) }
let fieldTypes = fields.map {self.unification.freshUnificationVariable(_.at)}
let recordType =
TConstructor(e.at, "Record$" + fields.map {_.name}.join("$"), fieldTypes)
self.unification.unify(e.at, expected, recordType)
Expand All @@ -520,20 +520,20 @@ extend self: Inference {
fields = newFields
)
| EFunctions(at, functions, body) =>
let functionMap = functions.map { f =>
let functionMap = functions.map {f =>
let scheme = Scheme(False, False, False, False, f.signature)
Pair(f.signature.name, scheme)
}.toMap()
let environment2 = environment.Environment(symbols = environment.symbols.addAll(functionMap))
let newFunctions = functions.map { self.inferFunctionDefinition(environment2, _) }
let newFunctions = functions.map {self.inferFunctionDefinition(environment2, _)}
let newBody = self.inferTerm(environment2, expected, body)
EFunctions(
at = at,
functions = newFunctions,
at = at
functions = newFunctions
body = newBody
)
| EAssign e =>
self.lookup(environment, e.at, e.variable, []).map { instantiated =>
self.lookup(environment, e.at, e.variable, []).map {instantiated =>
if(instantiated.scheme.isMutable) {
let value = self.inferAssignment(
environment = environment
Expand Down Expand Up @@ -607,12 +607,12 @@ extend self: Inference {
}

inferMethodCall(
environment: Environment,
expected: Type,
signature: Signature,
instantiation: List[Pair[String, Type]],
term: Term,
record: Term,
environment: Environment
expected: Type
signature: Signature
instantiation: List[Pair[String, Type]]
term: Term
record: Term
recordType: Type
name: String
): Term {
Expand All @@ -629,7 +629,7 @@ extend self: Inference {
self.unification.affect(term.at, signature.effect, environment.effect)
e.ECall(
target = StaticCall(name, instanceCall = False, tailCall = call.tailCall)
typeArguments = instantiation.map { _.second }
typeArguments = instantiation.map {_.second}
arguments = [selfArgument, ...arguments]
effect = signature.effect
)
Expand Down
8 changes: 5 additions & 3 deletions compiler/Tokenizer.ff
Original file line number Diff line number Diff line change
Expand Up @@ -196,11 +196,13 @@ tokenize(file: String, code: String, completionAt: Option[Location]): Array[Toke
}

if(
line != completionLine || 1 + i - lineOffset != completionColumn ||
o != LDot || i >= code.size() || code.grab(i).isAsciiLetter() || code.grab(i) == '{'
line == completionLine && 1 + i - lineOffset == completionColumn - 1 &&
o == LDot && i < code.size() && !code.grab(i).isAsciiLetter() && code.grab(i) != '{'
) {
emitToken(o, start, i)
emitToken(LLower, i, i)
}

emitToken(o, start, i)

} elseIf {
code.grab(i) == '(' || code.grab(i) == '[' || code.grab(i) == '{'
Expand Down
2 changes: 1 addition & 1 deletion vscode/syntaxes/firefly.tmLanguage.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
},
"field-or-call": {
"name": "entity.name.function.member.firefly",
"match": "(?<=[^.][.}][ ]*)[a-z][A-Za-z0-9]*\\b|(?<!\\bextend[ \\t]+)\\b[a-z][A-Za-z0-9]*(?=[ ]*[({\\[])"
"match": "(?<=[^.][.}][ ]*)[a-z][A-Za-z0-9]*\\b|(?<!\\bextend[ \\t]+|@[ \\t]*|\\b[A-Z][A-Za-z0-9]+[ \\t]+)\\b[a-z][A-Za-z0-9]*(?=[ ]*[({\\[])"
},
"upper-dot": {
"name": "entity.name.namespace.firefly",
Expand Down

0 comments on commit 79906d7

Please sign in to comment.