1
1
mirror of https://github.com/github/semantic.git synced 2024-12-01 00:33:59 +03:00

Merge remote-tracking branch 'origin/master' into source-aware-reprinter

This commit is contained in:
Timothy Clem 2018-08-20 10:17:38 -07:00
commit 3c53862e19
25 changed files with 1282 additions and 1057 deletions

View File

@ -0,0 +1,31 @@
---
type: cabal
name: haskeline
version: 0.7.4.2
summary: A command-line interface for user input, written in Haskell.
homepage: https://github.com/judah/haskeline
license: bsd-2-clause
---
Copyright 2007-2009, Judah Jacobson.
All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistribution of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
- Redistribution in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR THE CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -12,11 +12,11 @@ import Semantic.Task (withOptions)
import Semantic.Util hiding (evalRubyProject, evalPythonProject, evaluateProject) import Semantic.Util hiding (evalRubyProject, evalPythonProject, evaluateProject)
-- Duplicating this stuff from Util to shut off the logging -- Duplicating this stuff from Util to shut off the logging
evalRubyProject = justEvaluating <=< evaluateProject (Proxy :: Proxy 'Language.Ruby) rubyParser Language.Ruby evalRubyProject = justEvaluating <=< evaluateProject (Proxy :: Proxy 'Language.Ruby) rubyParser
evalPythonProject = justEvaluating <=< evaluateProject (Proxy :: Proxy 'Language.Python) pythonParser Language.Python evalPythonProject = justEvaluating <=< evaluateProject (Proxy :: Proxy 'Language.Python) pythonParser
evaluateProject proxy parser lang paths = withOptions defaultOptions $ \ config logger statter -> evaluateProject proxy parser paths = withOptions defaultOptions $ \ config logger statter ->
evaluateProject' (TaskConfig config logger statter) proxy parser lang paths evaluateProject' (TaskConfig config logger statter) proxy parser paths
-- We use `fmap show` to ensure that all the parts of the result of evaluation are -- We use `fmap show` to ensure that all the parts of the result of evaluation are
-- evaluated themselves. While an NFData instance is the most morally correct way -- evaluated themselves. While an NFData instance is the most morally correct way
@ -30,10 +30,10 @@ rbEval :: FilePath -> Benchmarkable
rbEval p = whnfIO . fmap show . evalRubyProject $ ["bench/bench-fixtures/ruby/" <> p] rbEval p = whnfIO . fmap show . evalRubyProject $ ["bench/bench-fixtures/ruby/" <> p]
pyCall :: FilePath -> Benchmarkable pyCall :: FilePath -> Benchmarkable
pyCall p = whnfIO $ callGraphProject pythonParser (Proxy @'Language.Python) Language.Python defaultOptions ["bench/bench-fixtures/python/" <> p] pyCall p = whnfIO $ callGraphProject pythonParser (Proxy @'Language.Python) defaultOptions ["bench/bench-fixtures/python/" <> p]
rbCall :: FilePath -> Benchmarkable rbCall :: FilePath -> Benchmarkable
rbCall p = whnfIO $ callGraphProject rubyParser (Proxy @'Language.Ruby) Language.Ruby defaultOptions ["bench/bench-fixtures/ruby/" <> p] rbCall p = whnfIO $ callGraphProject rubyParser (Proxy @'Language.Ruby) defaultOptions ["bench/bench-fixtures/ruby/" <> p]
main :: IO () main :: IO ()
main = defaultMain main = defaultMain

View File

@ -30,25 +30,6 @@ message PythonDiff {
} }
} }
message QualifiedName {
oneof sum {
QualifiedName qualifiedName = 1;
RelativeQualifiedName relativeQualifiedName = 2;
}
message QualifiedName {
repeated string paths = 1;
}
message RelativeQualifiedName {
string path = 1;
QualifiedName maybeQualifiedName = 2;
}
}
message Alias {
bytes aliasValue = 1;
bytes aliasName = 2;
}
message PythonSyntax { message PythonSyntax {
oneof syntax { oneof syntax {
Comment comment = 1; Comment comment = 1;
@ -158,12 +139,6 @@ message Function {
PythonDiff functionBody = 4; PythonDiff functionBody = 4;
} }
message Variable {
PythonDiff variableName = 1;
PythonDiff variableType = 2;
PythonDiff variableValue = 3;
}
message Plus { message Plus {
PythonDiff lhs = 1; PythonDiff lhs = 1;
PythonDiff rhs = 2; PythonDiff rhs = 2;
@ -361,6 +336,26 @@ message Tuple {
repeated PythonDiff tupleContents = 1; repeated PythonDiff tupleContents = 1;
} }
message Ellipsis { }
message FutureImport {
repeated Alias futureImportSymbols = 1;
}
message Import {
QualifiedName importFrom = 1;
repeated Alias importSymbols = 2;
}
message QualifiedImport {
repeated string qualifiedImportFrom = 1;
}
message QualifiedAliasedImport {
QualifiedName qualifiedAliasedImportFrom = 1;
PythonDiff qualifiedAliasedImportAlias = 2;
}
message Redirect { message Redirect {
PythonDiff lhs = 1; PythonDiff lhs = 1;
PythonDiff rhs = 2; PythonDiff rhs = 2;
@ -442,26 +437,6 @@ message Yield {
PythonDiff value = 1; PythonDiff value = 1;
} }
message Ellipsis { }
message Import {
QualifiedName importFrom = 1;
repeated Alias importSymbols = 2;
}
message FutureImport {
repeated Alias futureImportSymbols = 1;
}
message QualifiedImport {
repeated string qualifiedImportFrom = 1;
}
message QualifiedAliasedImport {
QualifiedName qualifiedAliasedImportFrom = 1;
PythonDiff qualifiedAliasedImportAlias = 2;
}
message Context { message Context {
repeated PythonDiff contextTerms = 1; repeated PythonDiff contextTerms = 1;
PythonDiff contextSubject = 2; PythonDiff contextSubject = 2;
@ -488,3 +463,22 @@ message Annotation {
message List { message List {
repeated PythonDiff listContent = 1; repeated PythonDiff listContent = 1;
} }
message QualifiedName {
oneof sum {
QualifiedName qualifiedName = 1;
RelativeQualifiedName relativeQualifiedName = 2;
}
message QualifiedName {
repeated string paths = 1;
}
message RelativeQualifiedName {
string path = 1;
QualifiedName maybeQualifiedName = 2;
}
}
message Alias {
bytes aliasValue = 1;
bytes aliasName = 2;
}

View File

@ -12,25 +12,6 @@ message PythonTerm {
PythonSyntax syntax = 1; PythonSyntax syntax = 1;
} }
message QualifiedName {
oneof sum {
QualifiedName qualifiedName = 1;
RelativeQualifiedName relativeQualifiedName = 2;
}
message QualifiedName {
repeated string paths = 1;
}
message RelativeQualifiedName {
string path = 1;
QualifiedName maybeQualifiedName = 2;
}
}
message Alias {
bytes aliasValue = 1;
bytes aliasName = 2;
}
message PythonSyntax { message PythonSyntax {
oneof syntax { oneof syntax {
Comment comment = 1; Comment comment = 1;
@ -337,6 +318,26 @@ message Tuple {
repeated PythonTerm tupleContents = 1; repeated PythonTerm tupleContents = 1;
} }
message Ellipsis { }
message FutureImport {
repeated Alias futureImportSymbols = 1;
}
message Import {
QualifiedName importFrom = 1;
repeated Alias importSymbols = 2;
}
message QualifiedImport {
repeated string qualifiedImportFrom = 1;
}
message QualifiedAliasedImport {
QualifiedName qualifiedAliasedImportFrom = 1;
PythonTerm qualifiedAliasedImportAlias = 2;
}
message Redirect { message Redirect {
PythonTerm lhs = 1; PythonTerm lhs = 1;
PythonTerm rhs = 2; PythonTerm rhs = 2;
@ -418,26 +419,6 @@ message Yield {
PythonTerm value = 1; PythonTerm value = 1;
} }
message Ellipsis { }
message Import {
QualifiedName importFrom = 1;
repeated Alias importSymbols = 2;
}
message FutureImport {
repeated Alias futureImportSymbols = 1;
}
message QualifiedImport {
repeated string qualifiedImportFrom = 1;
}
message QualifiedAliasedImport {
QualifiedName qualifiedAliasedImportFrom = 1;
PythonTerm qualifiedAliasedImportAlias = 2;
}
message Context { message Context {
repeated PythonTerm contextTerms = 1; repeated PythonTerm contextTerms = 1;
PythonTerm contextSubject = 2; PythonTerm contextSubject = 2;
@ -464,3 +445,22 @@ message Annotation {
message List { message List {
repeated PythonTerm listContent = 1; repeated PythonTerm listContent = 1;
} }
message QualifiedName {
oneof sum {
QualifiedName qualifiedName = 1;
RelativeQualifiedName relativeQualifiedName = 2;
}
message QualifiedName {
repeated string paths = 1;
}
message RelativeQualifiedName {
string path = 1;
QualifiedName maybeQualifiedName = 2;
}
}
message Alias {
bytes aliasValue = 1;
bytes aliasName = 2;
}

View File

@ -30,391 +30,6 @@ message RubyDiff {
} }
} }
message Comment {
string commentContent = 1;
}
message Function {
repeated RubyDiff functionContext = 1;
RubyDiff functionName = 2;
repeated RubyDiff functionParameters = 3;
RubyDiff functionBody = 4;
}
message Method {
repeated RubyDiff methodContext = 1;
RubyDiff methodReceiver = 2;
RubyDiff methodName = 3;
repeated RubyDiff methodParameters = 4;
RubyDiff methodBody = 5;
}
message File { }
message Line { }
message Error {
repeated ErrorSite errorCallStack = 1;
repeated string errorExpected = 2;
string errorActual = 3;
repeated RubyDiff errorChildren = 4;
}
message And {
RubyDiff lhs = 1;
RubyDiff rhs = 2;
}
message BAnd {
RubyDiff left = 1;
RubyDiff right = 2;
}
message BOr {
RubyDiff left = 1;
RubyDiff right = 2;
}
message BXOr {
RubyDiff left = 1;
RubyDiff right = 2;
}
message Call {
repeated RubyDiff callContext = 1;
RubyDiff callFunction = 2;
repeated RubyDiff callParams = 3;
RubyDiff callBlock = 4;
}
message Comparison {
RubyDiff lhs = 1;
RubyDiff rhs = 2;
}
message Complement {
RubyDiff value = 1;
}
message DividedBy {
RubyDiff lhs = 1;
RubyDiff rhs = 2;
}
message Enumeration {
RubyDiff enumerationStart = 1;
RubyDiff enumerationEnd = 2;
RubyDiff enumerationStep = 3;
}
message Equal {
RubyDiff lhs = 1;
RubyDiff rhs = 2;
}
message FloorDivision {
RubyDiff lhs = 1;
RubyDiff rhs = 2;
}
message GreaterThan {
RubyDiff lhs = 1;
RubyDiff rhs = 2;
}
message GreaterThanEqual {
RubyDiff lhs = 1;
RubyDiff rhs = 2;
}
message LShift {
RubyDiff left = 1;
RubyDiff right = 2;
}
message LessThan {
RubyDiff lhs = 1;
RubyDiff rhs = 2;
}
message LessThanEqual {
RubyDiff lhs = 1;
RubyDiff rhs = 2;
}
message Matches {
RubyDiff lhs = 1;
RubyDiff rhs = 2;
}
message Member {
RubyDiff lhs = 1;
RubyDiff rhs = 2;
}
message MemberAccess {
RubyDiff lhs = 1;
bytes rhs = 2;
}
message Minus {
RubyDiff lhs = 1;
RubyDiff rhs = 2;
}
message Modulo {
RubyDiff lhs = 1;
RubyDiff rhs = 2;
}
message Negate {
RubyDiff value = 1;
}
message Not {
RubyDiff value = 1;
}
message NotMatches {
RubyDiff lhs = 1;
RubyDiff rhs = 2;
}
message Or {
RubyDiff lhs = 1;
RubyDiff rhs = 2;
}
message Plus {
RubyDiff lhs = 1;
RubyDiff rhs = 2;
}
message Power {
RubyDiff lhs = 1;
RubyDiff rhs = 2;
}
message RShift {
RubyDiff left = 1;
RubyDiff right = 2;
}
message ScopeResolution {
repeated RubyDiff scopes = 1;
}
message StrictEqual {
RubyDiff lhs = 1;
RubyDiff rhs = 2;
}
message Subscript {
RubyDiff lhs = 1;
repeated RubyDiff rhs = 2;
}
message Times {
RubyDiff lhs = 1;
RubyDiff rhs = 2;
}
message This { }
message XOr {
RubyDiff lhs = 1;
RubyDiff rhs = 2;
}
message Array {
repeated RubyDiff arrayElements = 1;
}
message Boolean {
bool booleanContent = 1;
}
message Character {
string characterContent = 1;
}
message Complex {
string value = 1;
}
message EscapeSequence {
string value = 1;
}
message Float {
string floatContent = 1;
}
message Hash {
repeated RubyDiff hashElements = 1;
}
message Integer {
string integerContent = 1;
}
message InterpolationElement {
RubyDiff interpolationBody = 1;
}
message KeyValue {
RubyDiff key = 1;
RubyDiff value = 2;
}
message Null { }
message Rational {
string value = 1;
}
message Regex {
string regexContent = 1;
}
message String {
repeated RubyDiff stringElements = 1;
}
message Symbol {
repeated RubyDiff symbolElements = 1;
}
message SymbolElement {
string symbolContent = 1;
}
message TextElement {
string textElementContent = 1;
}
message Class {
RubyDiff classIdentifier = 1;
repeated RubyDiff classSuperClass = 2;
RubyDiff classBody = 3;
}
message Load {
RubyDiff loadPath = 1;
repeated RubyDiff loadWrap = 2;
}
message LowPrecedenceAnd {
RubyDiff lhs = 1;
RubyDiff rhs = 2;
}
message LowPrecedenceOr {
RubyDiff lhs = 1;
RubyDiff rhs = 2;
}
message Module {
RubyDiff moduleIdentifier = 1;
repeated RubyDiff moduleStatements = 2;
}
message Require {
bool requireRelative = 1;
RubyDiff requirePath = 2;
}
message Send {
repeated RubyDiff sendReceiver = 1;
repeated RubyDiff sendSelector = 2;
repeated RubyDiff sendArgs = 3;
repeated RubyDiff sendBlock = 4;
}
message Assignment {
repeated RubyDiff assignmentContext = 1;
RubyDiff assignmentTarget = 2;
RubyDiff assignmentValue = 3;
}
message Break {
RubyDiff value = 1;
}
message Catch {
RubyDiff catchException = 1;
RubyDiff catchBody = 2;
}
message Continue {
RubyDiff value = 1;
}
message Else {
RubyDiff elseCondition = 1;
RubyDiff elseBody = 2;
}
message Finally {
RubyDiff value = 1;
}
message ForEach {
RubyDiff forEachBinding = 1;
RubyDiff forEachSubject = 2;
RubyDiff forEachBody = 3;
}
message If {
RubyDiff ifCondition = 1;
RubyDiff ifThenBody = 2;
RubyDiff ifElseBody = 3;
}
message Match {
RubyDiff matchSubject = 1;
RubyDiff matchPatterns = 2;
}
message Pattern {
RubyDiff value = 1;
RubyDiff patternBody = 2;
}
message Retry {
RubyDiff value = 1;
}
message Return {
RubyDiff value = 1;
}
message ScopeEntry {
repeated RubyDiff terms = 1;
}
message ScopeExit {
repeated RubyDiff terms = 1;
}
message Statements {
repeated RubyDiff statements = 1;
}
message Try {
RubyDiff tryBody = 1;
repeated RubyDiff tryCatch = 2;
}
message While {
RubyDiff whileCondition = 1;
RubyDiff whileBody = 2;
}
message Yield {
RubyDiff value = 1;
}
message RubySyntax { message RubySyntax {
oneof syntax { oneof syntax {
Comment comment = 1; Comment comment = 1;
@ -506,6 +121,346 @@ message RubySyntax {
} }
} }
message Comment {
string commentContent = 1;
}
message Function {
repeated RubyDiff functionContext = 1;
RubyDiff functionName = 2;
repeated RubyDiff functionParameters = 3;
RubyDiff functionBody = 4;
}
message Method {
repeated RubyDiff methodContext = 1;
RubyDiff methodReceiver = 2;
RubyDiff methodName = 3;
repeated RubyDiff methodParameters = 4;
RubyDiff methodBody = 5;
}
message File { }
message Line { }
message Plus {
RubyDiff lhs = 1;
RubyDiff rhs = 2;
}
message Minus {
RubyDiff lhs = 1;
RubyDiff rhs = 2;
}
message Times {
RubyDiff lhs = 1;
RubyDiff rhs = 2;
}
message DividedBy {
RubyDiff lhs = 1;
RubyDiff rhs = 2;
}
message Modulo {
RubyDiff lhs = 1;
RubyDiff rhs = 2;
}
message Power {
RubyDiff lhs = 1;
RubyDiff rhs = 2;
}
message Negate {
RubyDiff value = 1;
}
message FloorDivision {
RubyDiff lhs = 1;
RubyDiff rhs = 2;
}
message BAnd {
RubyDiff left = 1;
RubyDiff right = 2;
}
message BOr {
RubyDiff left = 1;
RubyDiff right = 2;
}
message BXOr {
RubyDiff left = 1;
RubyDiff right = 2;
}
message LShift {
RubyDiff left = 1;
RubyDiff right = 2;
}
message RShift {
RubyDiff left = 1;
RubyDiff right = 2;
}
message Complement {
RubyDiff value = 1;
}
message And {
RubyDiff lhs = 1;
RubyDiff rhs = 2;
}
message Not {
RubyDiff value = 1;
}
message Or {
RubyDiff lhs = 1;
RubyDiff rhs = 2;
}
message XOr {
RubyDiff lhs = 1;
RubyDiff rhs = 2;
}
message Call {
repeated RubyDiff callContext = 1;
RubyDiff callFunction = 2;
repeated RubyDiff callParams = 3;
RubyDiff callBlock = 4;
}
message LessThan {
RubyDiff lhs = 1;
RubyDiff rhs = 2;
}
message LessThanEqual {
RubyDiff lhs = 1;
RubyDiff rhs = 2;
}
message GreaterThan {
RubyDiff lhs = 1;
RubyDiff rhs = 2;
}
message GreaterThanEqual {
RubyDiff lhs = 1;
RubyDiff rhs = 2;
}
message Equal {
RubyDiff lhs = 1;
RubyDiff rhs = 2;
}
message StrictEqual {
RubyDiff lhs = 1;
RubyDiff rhs = 2;
}
message Comparison {
RubyDiff lhs = 1;
RubyDiff rhs = 2;
}
message Enumeration {
RubyDiff enumerationStart = 1;
RubyDiff enumerationEnd = 2;
RubyDiff enumerationStep = 3;
}
message Matches {
RubyDiff lhs = 1;
RubyDiff rhs = 2;
}
message NotMatches {
RubyDiff lhs = 1;
RubyDiff rhs = 2;
}
message MemberAccess {
RubyDiff lhs = 1;
bytes rhs = 2;
}
message ScopeResolution {
repeated RubyDiff scopes = 1;
}
message Subscript {
RubyDiff lhs = 1;
repeated RubyDiff rhs = 2;
}
message Member {
RubyDiff lhs = 1;
RubyDiff rhs = 2;
}
message This { }
message Array {
repeated RubyDiff arrayElements = 1;
}
message Boolean {
bool booleanContent = 1;
}
message Character {
string characterContent = 1;
}
message Complex {
string value = 1;
}
message EscapeSequence {
string value = 1;
}
message Float {
string floatContent = 1;
}
message Hash {
repeated RubyDiff hashElements = 1;
}
message Integer {
string integerContent = 1;
}
message InterpolationElement {
RubyDiff interpolationBody = 1;
}
message KeyValue {
RubyDiff key = 1;
RubyDiff value = 2;
}
message Null { }
message Rational {
string value = 1;
}
message Regex {
string regexContent = 1;
}
message String {
repeated RubyDiff stringElements = 1;
}
message Symbol {
repeated RubyDiff symbolElements = 1;
}
message SymbolElement {
string symbolContent = 1;
}
message TextElement {
string textElementContent = 1;
}
message Assignment {
repeated RubyDiff assignmentContext = 1;
RubyDiff assignmentTarget = 2;
RubyDiff assignmentValue = 3;
}
message Break {
RubyDiff value = 1;
}
message Catch {
RubyDiff catchException = 1;
RubyDiff catchBody = 2;
}
message Continue {
RubyDiff value = 1;
}
message Else {
RubyDiff elseCondition = 1;
RubyDiff elseBody = 2;
}
message Finally {
RubyDiff value = 1;
}
message ForEach {
RubyDiff forEachBinding = 1;
RubyDiff forEachSubject = 2;
RubyDiff forEachBody = 3;
}
message If {
RubyDiff ifCondition = 1;
RubyDiff ifThenBody = 2;
RubyDiff ifElseBody = 3;
}
message Match {
RubyDiff matchSubject = 1;
RubyDiff matchPatterns = 2;
}
message Pattern {
RubyDiff value = 1;
RubyDiff patternBody = 2;
}
message Retry {
RubyDiff value = 1;
}
message Return {
RubyDiff value = 1;
}
message ScopeEntry {
repeated RubyDiff terms = 1;
}
message ScopeExit {
repeated RubyDiff terms = 1;
}
message Statements {
repeated RubyDiff statements = 1;
}
message Try {
RubyDiff tryBody = 1;
repeated RubyDiff tryCatch = 2;
}
message While {
RubyDiff whileCondition = 1;
RubyDiff whileBody = 2;
}
message Yield {
RubyDiff value = 1;
}
message Context { message Context {
repeated RubyDiff contextTerms = 1; repeated RubyDiff contextTerms = 1;
RubyDiff contextSubject = 2; RubyDiff contextSubject = 2;
@ -513,10 +468,55 @@ message Context {
message Empty { } message Empty { }
message Error {
repeated ErrorSite errorCallStack = 1;
repeated string errorExpected = 2;
string errorActual = 3;
repeated RubyDiff errorChildren = 4;
}
message Identifier { message Identifier {
bytes name = 1; bytes name = 1;
} }
message Class {
RubyDiff classIdentifier = 1;
repeated RubyDiff classSuperClass = 2;
RubyDiff classBody = 3;
}
message Load {
RubyDiff loadPath = 1;
repeated RubyDiff loadWrap = 2;
}
message LowPrecedenceAnd {
RubyDiff lhs = 1;
RubyDiff rhs = 2;
}
message LowPrecedenceOr {
RubyDiff lhs = 1;
RubyDiff rhs = 2;
}
message Module {
RubyDiff moduleIdentifier = 1;
repeated RubyDiff moduleStatements = 2;
}
message Require {
bool requireRelative = 1;
RubyDiff requirePath = 2;
}
message Send {
repeated RubyDiff sendReceiver = 1;
repeated RubyDiff sendSelector = 2;
repeated RubyDiff sendArgs = 3;
repeated RubyDiff sendBlock = 4;
}
message List { message List {
repeated RubyDiff listContent = 1; repeated RubyDiff listContent = 1;
} }

View File

@ -12,391 +12,6 @@ message RubyTerm {
RubySyntax syntax = 1; RubySyntax syntax = 1;
} }
message Comment {
string commentContent = 1;
}
message Function {
repeated RubyTerm functionContext = 1;
RubyTerm functionName = 2;
repeated RubyTerm functionParameters = 3;
RubyTerm functionBody = 4;
}
message Method {
repeated RubyTerm methodContext = 1;
RubyTerm methodReceiver = 2;
RubyTerm methodName = 3;
repeated RubyTerm methodParameters = 4;
RubyTerm methodBody = 5;
}
message File { }
message Line { }
message Error {
repeated ErrorSite errorCallStack = 1;
repeated string errorExpected = 2;
string errorActual = 3;
repeated RubyTerm errorChildren = 4;
}
message And {
RubyTerm lhs = 1;
RubyTerm rhs = 2;
}
message BAnd {
RubyTerm left = 1;
RubyTerm right = 2;
}
message BOr {
RubyTerm left = 1;
RubyTerm right = 2;
}
message BXOr {
RubyTerm left = 1;
RubyTerm right = 2;
}
message Call {
repeated RubyTerm callContext = 1;
RubyTerm callFunction = 2;
repeated RubyTerm callParams = 3;
RubyTerm callBlock = 4;
}
message Comparison {
RubyTerm lhs = 1;
RubyTerm rhs = 2;
}
message Complement {
RubyTerm value = 1;
}
message DividedBy {
RubyTerm lhs = 1;
RubyTerm rhs = 2;
}
message Enumeration {
RubyTerm enumerationStart = 1;
RubyTerm enumerationEnd = 2;
RubyTerm enumerationStep = 3;
}
message Equal {
RubyTerm lhs = 1;
RubyTerm rhs = 2;
}
message FloorDivision {
RubyTerm lhs = 1;
RubyTerm rhs = 2;
}
message GreaterThan {
RubyTerm lhs = 1;
RubyTerm rhs = 2;
}
message GreaterThanEqual {
RubyTerm lhs = 1;
RubyTerm rhs = 2;
}
message LShift {
RubyTerm left = 1;
RubyTerm right = 2;
}
message LessThan {
RubyTerm lhs = 1;
RubyTerm rhs = 2;
}
message LessThanEqual {
RubyTerm lhs = 1;
RubyTerm rhs = 2;
}
message Matches {
RubyTerm lhs = 1;
RubyTerm rhs = 2;
}
message Member {
RubyTerm lhs = 1;
RubyTerm rhs = 2;
}
message MemberAccess {
RubyTerm lhs = 1;
bytes rhs = 2;
}
message Minus {
RubyTerm lhs = 1;
RubyTerm rhs = 2;
}
message Modulo {
RubyTerm lhs = 1;
RubyTerm rhs = 2;
}
message Negate {
RubyTerm value = 1;
}
message Not {
RubyTerm value = 1;
}
message NotMatches {
RubyTerm lhs = 1;
RubyTerm rhs = 2;
}
message Or {
RubyTerm lhs = 1;
RubyTerm rhs = 2;
}
message Plus {
RubyTerm lhs = 1;
RubyTerm rhs = 2;
}
message Power {
RubyTerm lhs = 1;
RubyTerm rhs = 2;
}
message RShift {
RubyTerm left = 1;
RubyTerm right = 2;
}
message ScopeResolution {
repeated RubyTerm scopes = 1;
}
message StrictEqual {
RubyTerm lhs = 1;
RubyTerm rhs = 2;
}
message Subscript {
RubyTerm lhs = 1;
repeated RubyTerm rhs = 2;
}
message Times {
RubyTerm lhs = 1;
RubyTerm rhs = 2;
}
message XOr {
RubyTerm lhs = 1;
RubyTerm rhs = 2;
}
message This { }
message Array {
repeated RubyTerm arrayElements = 1;
}
message Boolean {
bool booleanContent = 1;
}
message Character {
string characterContent = 1;
}
message Complex {
string value = 1;
}
message EscapeSequence {
string value = 1;
}
message Float {
string floatContent = 1;
}
message Hash {
repeated RubyTerm hashElements = 1;
}
message Integer {
string integerContent = 1;
}
message InterpolationElement {
RubyTerm interpolationBody = 1;
}
message KeyValue {
RubyTerm key = 1;
RubyTerm value = 2;
}
message Null { }
message Rational {
string value = 1;
}
message Regex {
string regexContent = 1;
}
message String {
repeated RubyTerm stringElements = 1;
}
message Symbol {
repeated RubyTerm symbolElements = 1;
}
message SymbolElement {
string symbolContent = 1;
}
message TextElement {
string textElementContent = 1;
}
message Class {
RubyTerm classIdentifier = 1;
repeated RubyTerm classSuperClass = 2;
RubyTerm classBody = 3;
}
message Load {
RubyTerm loadPath = 1;
repeated RubyTerm loadWrap = 2;
}
message LowPrecedenceAnd {
RubyTerm lhs = 1;
RubyTerm rhs = 2;
}
message LowPrecedenceOr {
RubyTerm lhs = 1;
RubyTerm rhs = 2;
}
message Module {
RubyTerm moduleIdentifier = 1;
repeated RubyTerm moduleStatements = 2;
}
message Require {
bool requireRelative = 1;
RubyTerm requirePath = 2;
}
message Send {
repeated RubyTerm sendReceiver = 1;
repeated RubyTerm sendSelector = 2;
repeated RubyTerm sendArgs = 3;
repeated RubyTerm sendBlock = 4;
}
message Assignment {
repeated RubyTerm assignmentContext = 1;
RubyTerm assignmentTarget = 2;
RubyTerm assignmentValue = 3;
}
message Break {
RubyTerm value = 1;
}
message Catch {
RubyTerm catchException = 1;
RubyTerm catchBody = 2;
}
message Continue {
RubyTerm value = 1;
}
message Else {
RubyTerm elseCondition = 1;
RubyTerm elseBody = 2;
}
message Finally {
RubyTerm value = 1;
}
message ForEach {
RubyTerm forEachBinding = 1;
RubyTerm forEachSubject = 2;
RubyTerm forEachBody = 3;
}
message If {
RubyTerm ifCondition = 1;
RubyTerm ifThenBody = 2;
RubyTerm ifElseBody = 3;
}
message Match {
RubyTerm matchSubject = 1;
RubyTerm matchPatterns = 2;
}
message Pattern {
RubyTerm value = 1;
RubyTerm patternBody = 2;
}
message Retry {
RubyTerm value = 1;
}
message Return {
RubyTerm value = 1;
}
message ScopeEntry {
repeated RubyTerm terms = 1;
}
message ScopeExit {
repeated RubyTerm terms = 1;
}
message Statements {
repeated RubyTerm statements = 1;
}
message Try {
RubyTerm tryBody = 1;
repeated RubyTerm tryCatch = 2;
}
message While {
RubyTerm whileCondition = 1;
RubyTerm whileBody = 2;
}
message Yield {
RubyTerm value = 1;
}
message RubySyntax { message RubySyntax {
oneof syntax { oneof syntax {
Comment comment = 1; Comment comment = 1;
@ -488,6 +103,346 @@ message RubySyntax {
} }
} }
message Comment {
string commentContent = 1;
}
message Function {
repeated RubyTerm functionContext = 1;
RubyTerm functionName = 2;
repeated RubyTerm functionParameters = 3;
RubyTerm functionBody = 4;
}
message Method {
repeated RubyTerm methodContext = 1;
RubyTerm methodReceiver = 2;
RubyTerm methodName = 3;
repeated RubyTerm methodParameters = 4;
RubyTerm methodBody = 5;
}
message File { }
message Line { }
message Plus {
RubyTerm lhs = 1;
RubyTerm rhs = 2;
}
message Minus {
RubyTerm lhs = 1;
RubyTerm rhs = 2;
}
message Times {
RubyTerm lhs = 1;
RubyTerm rhs = 2;
}
message DividedBy {
RubyTerm lhs = 1;
RubyTerm rhs = 2;
}
message Modulo {
RubyTerm lhs = 1;
RubyTerm rhs = 2;
}
message Power {
RubyTerm lhs = 1;
RubyTerm rhs = 2;
}
message Negate {
RubyTerm value = 1;
}
message FloorDivision {
RubyTerm lhs = 1;
RubyTerm rhs = 2;
}
message BAnd {
RubyTerm left = 1;
RubyTerm right = 2;
}
message BOr {
RubyTerm left = 1;
RubyTerm right = 2;
}
message BXOr {
RubyTerm left = 1;
RubyTerm right = 2;
}
message LShift {
RubyTerm left = 1;
RubyTerm right = 2;
}
message RShift {
RubyTerm left = 1;
RubyTerm right = 2;
}
message Complement {
RubyTerm value = 1;
}
message And {
RubyTerm lhs = 1;
RubyTerm rhs = 2;
}
message Not {
RubyTerm value = 1;
}
message Or {
RubyTerm lhs = 1;
RubyTerm rhs = 2;
}
message XOr {
RubyTerm lhs = 1;
RubyTerm rhs = 2;
}
message Call {
repeated RubyTerm callContext = 1;
RubyTerm callFunction = 2;
repeated RubyTerm callParams = 3;
RubyTerm callBlock = 4;
}
message LessThan {
RubyTerm lhs = 1;
RubyTerm rhs = 2;
}
message LessThanEqual {
RubyTerm lhs = 1;
RubyTerm rhs = 2;
}
message GreaterThan {
RubyTerm lhs = 1;
RubyTerm rhs = 2;
}
message GreaterThanEqual {
RubyTerm lhs = 1;
RubyTerm rhs = 2;
}
message Equal {
RubyTerm lhs = 1;
RubyTerm rhs = 2;
}
message StrictEqual {
RubyTerm lhs = 1;
RubyTerm rhs = 2;
}
message Comparison {
RubyTerm lhs = 1;
RubyTerm rhs = 2;
}
message Enumeration {
RubyTerm enumerationStart = 1;
RubyTerm enumerationEnd = 2;
RubyTerm enumerationStep = 3;
}
message Matches {
RubyTerm lhs = 1;
RubyTerm rhs = 2;
}
message NotMatches {
RubyTerm lhs = 1;
RubyTerm rhs = 2;
}
message MemberAccess {
RubyTerm lhs = 1;
bytes rhs = 2;
}
message ScopeResolution {
repeated RubyTerm scopes = 1;
}
message Subscript {
RubyTerm lhs = 1;
repeated RubyTerm rhs = 2;
}
message Member {
RubyTerm lhs = 1;
RubyTerm rhs = 2;
}
message This { }
message Array {
repeated RubyTerm arrayElements = 1;
}
message Boolean {
bool booleanContent = 1;
}
message Character {
string characterContent = 1;
}
message Complex {
string value = 1;
}
message EscapeSequence {
string value = 1;
}
message Float {
string floatContent = 1;
}
message Hash {
repeated RubyTerm hashElements = 1;
}
message Integer {
string integerContent = 1;
}
message InterpolationElement {
RubyTerm interpolationBody = 1;
}
message KeyValue {
RubyTerm key = 1;
RubyTerm value = 2;
}
message Null { }
message Rational {
string value = 1;
}
message Regex {
string regexContent = 1;
}
message String {
repeated RubyTerm stringElements = 1;
}
message Symbol {
repeated RubyTerm symbolElements = 1;
}
message SymbolElement {
string symbolContent = 1;
}
message TextElement {
string textElementContent = 1;
}
message Assignment {
repeated RubyTerm assignmentContext = 1;
RubyTerm assignmentTarget = 2;
RubyTerm assignmentValue = 3;
}
message Break {
RubyTerm value = 1;
}
message Catch {
RubyTerm catchException = 1;
RubyTerm catchBody = 2;
}
message Continue {
RubyTerm value = 1;
}
message Else {
RubyTerm elseCondition = 1;
RubyTerm elseBody = 2;
}
message Finally {
RubyTerm value = 1;
}
message ForEach {
RubyTerm forEachBinding = 1;
RubyTerm forEachSubject = 2;
RubyTerm forEachBody = 3;
}
message If {
RubyTerm ifCondition = 1;
RubyTerm ifThenBody = 2;
RubyTerm ifElseBody = 3;
}
message Match {
RubyTerm matchSubject = 1;
RubyTerm matchPatterns = 2;
}
message Pattern {
RubyTerm value = 1;
RubyTerm patternBody = 2;
}
message Retry {
RubyTerm value = 1;
}
message Return {
RubyTerm value = 1;
}
message ScopeEntry {
repeated RubyTerm terms = 1;
}
message ScopeExit {
repeated RubyTerm terms = 1;
}
message Statements {
repeated RubyTerm statements = 1;
}
message Try {
RubyTerm tryBody = 1;
repeated RubyTerm tryCatch = 2;
}
message While {
RubyTerm whileCondition = 1;
RubyTerm whileBody = 2;
}
message Yield {
RubyTerm value = 1;
}
message Context { message Context {
repeated RubyTerm contextTerms = 1; repeated RubyTerm contextTerms = 1;
RubyTerm contextSubject = 2; RubyTerm contextSubject = 2;
@ -495,10 +450,55 @@ message Context {
message Empty { } message Empty { }
message Error {
repeated ErrorSite errorCallStack = 1;
repeated string errorExpected = 2;
string errorActual = 3;
repeated RubyTerm errorChildren = 4;
}
message Identifier { message Identifier {
bytes name = 1; bytes name = 1;
} }
message Class {
RubyTerm classIdentifier = 1;
repeated RubyTerm classSuperClass = 2;
RubyTerm classBody = 3;
}
message Load {
RubyTerm loadPath = 1;
repeated RubyTerm loadWrap = 2;
}
message LowPrecedenceAnd {
RubyTerm lhs = 1;
RubyTerm rhs = 2;
}
message LowPrecedenceOr {
RubyTerm lhs = 1;
RubyTerm rhs = 2;
}
message Module {
RubyTerm moduleIdentifier = 1;
repeated RubyTerm moduleStatements = 2;
}
message Require {
bool requireRelative = 1;
RubyTerm requirePath = 2;
}
message Send {
repeated RubyTerm sendReceiver = 1;
repeated RubyTerm sendSelector = 2;
repeated RubyTerm sendArgs = 3;
repeated RubyTerm sendBlock = 4;
}
message List { message List {
repeated RubyTerm listContent = 1; repeated RubyTerm listContent = 1;
} }

View File

@ -30,22 +30,6 @@ message TypeScriptDiff {
} }
} }
message Alias {
bytes aliasValue = 1;
bytes aliasName = 2;
}
message ImportPath {
string unPath = 1;
IsRelative pathIsRelative = 2;
}
enum IsRelative {
Unknown = 0;
Relative = 1;
NonRelative = 2;
}
message TypeScriptSyntax { message TypeScriptSyntax {
oneof syntax { oneof syntax {
Comment comment = 1; Comment comment = 1;
@ -819,10 +803,6 @@ message AbstractClass {
TypeScriptDiff classBody = 4; TypeScriptDiff classBody = 4;
} }
message ExtendsClause {
repeated TypeScriptDiff extendsClauses = 1;
}
message ImplementsClause { message ImplementsClause {
repeated TypeScriptDiff implementsClauseTypes = 1; repeated TypeScriptDiff implementsClauseTypes = 1;
} }
@ -898,6 +878,10 @@ message EnumDeclaration {
repeated TypeScriptDiff enumDeclarationBody = 2; repeated TypeScriptDiff enumDeclarationBody = 2;
} }
message ExtendsClause {
repeated TypeScriptDiff extendsClauses = 1;
}
message AmbientFunction { message AmbientFunction {
repeated TypeScriptDiff ambientFunctionContext = 1; repeated TypeScriptDiff ambientFunctionContext = 1;
TypeScriptDiff ambientFunctionIdentifier = 2; TypeScriptDiff ambientFunctionIdentifier = 2;
@ -980,3 +964,19 @@ message JavaScriptRequire {
message List { message List {
repeated TypeScriptDiff listContent = 1; repeated TypeScriptDiff listContent = 1;
} }
message Alias {
bytes aliasValue = 1;
bytes aliasName = 2;
}
message ImportPath {
string unPath = 1;
IsRelative pathIsRelative = 2;
}
enum IsRelative {
Unknown = 0;
Relative = 1;
NonRelative = 2;
}

View File

@ -12,22 +12,6 @@ message TypeScriptTerm {
TypeScriptSyntax syntax = 1; TypeScriptSyntax syntax = 1;
} }
message Alias {
bytes aliasValue = 1;
bytes aliasName = 2;
}
message ImportPath {
string unPath = 1;
IsRelative pathIsRelative = 2;
}
enum IsRelative {
Unknown = 0;
Relative = 1;
NonRelative = 2;
}
message TypeScriptSyntax { message TypeScriptSyntax {
oneof syntax { oneof syntax {
Comment comment = 1; Comment comment = 1;
@ -801,10 +785,6 @@ message AbstractClass {
TypeScriptTerm classBody = 4; TypeScriptTerm classBody = 4;
} }
message ExtendsClause {
repeated TypeScriptTerm extendsClauses = 1;
}
message ImplementsClause { message ImplementsClause {
repeated TypeScriptTerm implementsClauseTypes = 1; repeated TypeScriptTerm implementsClauseTypes = 1;
} }
@ -880,6 +860,10 @@ message EnumDeclaration {
repeated TypeScriptTerm enumDeclarationBody = 2; repeated TypeScriptTerm enumDeclarationBody = 2;
} }
message ExtendsClause {
repeated TypeScriptTerm extendsClauses = 1;
}
message AmbientFunction { message AmbientFunction {
repeated TypeScriptTerm ambientFunctionContext = 1; repeated TypeScriptTerm ambientFunctionContext = 1;
TypeScriptTerm ambientFunctionIdentifier = 2; TypeScriptTerm ambientFunctionIdentifier = 2;
@ -962,3 +946,19 @@ message JavaScriptRequire {
message List { message List {
repeated TypeScriptTerm listContent = 1; repeated TypeScriptTerm listContent = 1;
} }
message Alias {
bytes aliasValue = 1;
bytes aliasName = 2;
}
message ImportPath {
string unPath = 1;
IsRelative pathIsRelative = 2;
}
enum IsRelative {
Unknown = 0;
Relative = 1;
NonRelative = 2;
}

View File

@ -173,6 +173,7 @@ library
, Semantic.Graph , Semantic.Graph
, Semantic.IO , Semantic.IO
, Semantic.Parse , Semantic.Parse
, Semantic.REPL
, Semantic.Resolution , Semantic.Resolution
, Semantic.Task , Semantic.Task
, Semantic.Telemetry , Semantic.Telemetry
@ -211,6 +212,7 @@ library
, gitrev , gitrev
, Glob , Glob
, hashable , hashable
, haskeline
, hscolour , hscolour
, http-client , http-client
, http-client-tls , http-client-tls
@ -324,12 +326,10 @@ test-suite test
, Test.Hspec.LeanCheck , Test.Hspec.LeanCheck
build-depends: aeson build-depends: aeson
, algebraic-graphs , algebraic-graphs
, array
, async , async
, base , base
, bifunctors , bifunctors
, bytestring , bytestring
, comonad
, containers , containers
, effects , effects
, fastsum , fastsum
@ -382,7 +382,6 @@ test-suite doctests
ghc-options: -dynamic -threaded -j ghc-options: -dynamic -threaded -j
build-depends: base build-depends: base
, doctest , doctest
, QuickCheck
benchmark evaluation benchmark evaluation
hs-source-dirs: bench hs-source-dirs: bench

View File

@ -23,6 +23,7 @@ import Control.Monad.Effect.Reader as X
import Control.Monad.Effect.Resumable as X import Control.Monad.Effect.Resumable as X
import Control.Monad.Effect.State as X import Control.Monad.Effect.State as X
import Control.Monad.Effect.Trace as X import Control.Monad.Effect.Trace as X
import Control.Monad.IO.Class
import Prologue hiding (MonadError(..)) import Prologue hiding (MonadError(..))
-- | An 'Evaluator' is a thin wrapper around 'Eff' with (phantom) type parameters for the address, term, and value types. -- | An 'Evaluator' is a thin wrapper around 'Eff' with (phantom) type parameters for the address, term, and value types.
@ -34,6 +35,7 @@ newtype Evaluator address value effects a = Evaluator { runEvaluator :: Eff effe
deriving (Applicative, Effectful, Functor, Monad) deriving (Applicative, Effectful, Functor, Monad)
deriving instance Member NonDet effects => Alternative (Evaluator address value effects) deriving instance Member NonDet effects => Alternative (Evaluator address value effects)
deriving instance Member (Lift IO) effects => MonadIO (Evaluator address value effects)
-- Effects -- Effects

View File

@ -13,6 +13,7 @@ import Control.Monad.Effect.Reader as X
import Control.Monad.Effect.Resumable as X import Control.Monad.Effect.Resumable as X
import Control.Monad.Effect.State as X import Control.Monad.Effect.State as X
import Control.Monad.Effect.Trace as X import Control.Monad.Effect.Trace as X
import Control.Monad.IO.Class
import Prologue import Prologue
-- | Evaluators specialized to some specific term type. -- | Evaluators specialized to some specific term type.
@ -22,6 +23,7 @@ newtype TermEvaluator term address value effects a = TermEvaluator { runTermEval
deriving (Applicative, Effectful, Functor, Monad) deriving (Applicative, Effectful, Functor, Monad)
deriving instance Member NonDet effects => Alternative (TermEvaluator term address value effects) deriving instance Member NonDet effects => Alternative (TermEvaluator term address value effects)
deriving instance Member (Lift IO) effects => MonadIO (TermEvaluator term address value effects)
raiseHandler :: (Evaluator address value effects a -> Evaluator address value effects' a') -> (TermEvaluator term address value effects a -> TermEvaluator term address value effects' a') raiseHandler :: (Evaluator address value effects a -> Evaluator address value effects' a') -> (TermEvaluator term address value effects a -> TermEvaluator term address value effects' a')

View File

@ -37,7 +37,7 @@ import Prologue
-- | A map of names to values. Represents a single scope level of an environment chain. -- | A map of names to values. Represents a single scope level of an environment chain.
newtype Bindings address = Bindings { unBindings :: Map.Map Name address } newtype Bindings address = Bindings { unBindings :: Map.Map Name address }
deriving (Eq, Ord, Show) deriving (Eq, Ord)
instance Semigroup (Bindings address) where instance Semigroup (Bindings address) where
(<>) (Bindings a) (Bindings b) = Bindings (a <> b) (<>) (Bindings a) (Bindings b) = Bindings (a <> b)
@ -49,6 +49,10 @@ instance Monoid (Bindings address) where
instance Lower (Bindings address) where instance Lower (Bindings address) where
lowerBound = mempty lowerBound = mempty
instance Show address => Show (Bindings address) where
showsPrec d = showsUnaryWith showsPrec "Bindings" d . pairs
-- | A LIFO stack of maps of names to addresses, representing a lexically-scoped evaluation environment. -- | A LIFO stack of maps of names to addresses, representing a lexically-scoped evaluation environment.
-- All behaviors can be assumed to be frontmost-biased: looking up "a" will check the most specific -- All behaviors can be assumed to be frontmost-biased: looking up "a" will check the most specific
-- scope for "a", then the next, and so on. -- scope for "a", then the next, and so on.

View File

@ -2,6 +2,8 @@
module Data.Abstract.Evaluatable module Data.Abstract.Evaluatable
( module X ( module X
, Evaluatable(..) , Evaluatable(..)
, ModuleEffects
, ValueEffects
, evaluate , evaluate
, traceResolve , traceResolve
-- * Preludes -- * Preludes
@ -75,6 +77,19 @@ class (Show1 constr, Foldable constr) => Evaluatable constr where
rvalBox v rvalBox v
type ModuleEffects address value rest
= Exc (LoopControl address)
': Exc (Return address)
': Env address
': Deref value
': Allocator address
': Reader ModuleInfo
': rest
type ValueEffects address value rest
= Function address value
': rest
evaluate :: ( AbstractValue address value valueEffects evaluate :: ( AbstractValue address value valueEffects
, Declarations term , Declarations term
, Effects effects , Effects effects
@ -96,8 +111,8 @@ evaluate :: ( AbstractValue address value valueEffects
, Member Trace effects , Member Trace effects
, Ord address , Ord address
, Recursive term , Recursive term
, moduleEffects ~ (Exc (LoopControl address) ': Exc (Return address) ': Env address ': Deref value ': Allocator address ': Reader ModuleInfo ': effects) , moduleEffects ~ ModuleEffects address value effects
, valueEffects ~ (Function address value ': moduleEffects) , valueEffects ~ ValueEffects address value moduleEffects
) )
=> proxy lang => proxy lang
-> (SubtermAlgebra Module term (TermEvaluator term address value moduleEffects address) -> SubtermAlgebra Module term (TermEvaluator term address value moduleEffects address)) -> (SubtermAlgebra Module term (TermEvaluator term address value moduleEffects address) -> SubtermAlgebra Module term (TermEvaluator term address value moduleEffects address))

View File

@ -52,4 +52,4 @@ instance (Ord address, Ord value) => Reducer (address, value) (Heap address valu
snoc (Heap heap) (addr, a) = Heap (snoc heap (addr, a)) snoc (Heap heap) (addr, a) = Heap (snoc heap (addr, a))
instance (Show address, Show value) => Show (Heap address value) where instance (Show address, Show value) => Show (Heap address value) where
showsPrec d = showsUnaryWith showsPrec "Heap" d . Monoidal.pairs . unHeap showsPrec d = showsUnaryWith showsPrec "Heap" d . map (second toList) . Monoidal.pairs . unHeap

View File

@ -4,15 +4,15 @@ module Data.Error
, formatError , formatError
, makeError , makeError
, showExpectation , showExpectation
, showExcerpt
, withSGRCode , withSGRCode
) where ) where
import Prologue import Prologue
import Data.ByteString (isSuffixOf) import Data.ByteString.Char8 (unpack)
import Data.ByteString.Char8 (pack, unpack)
import Data.Ix (inRange) import Data.Ix (inRange)
import Data.List (intersperse) import Data.List (intersperse, isSuffixOf)
import System.Console.ANSI import System.Console.ANSI
import Data.Blob import Data.Blob
@ -43,20 +43,30 @@ type Colourize = Bool
-- | Format an 'Error', optionally with reference to the source where it occurred. -- | Format an 'Error', optionally with reference to the source where it occurred.
formatError :: IncludeSource -> Colourize -> Blob -> Error String -> String formatError :: IncludeSource -> Colourize -> Blob -> Error String -> String
formatError includeSource colourize Blob{..} Error{..} formatError includeSource colourize blob@Blob{..} Error{..}
= ($ "") = ($ "")
$ withSGRCode colourize [SetConsoleIntensity BoldIntensity] (showSpan path errorSpan . showString ": ") $ withSGRCode colourize [SetConsoleIntensity BoldIntensity] (showSpan path errorSpan . showString ": ")
. withSGRCode colourize [SetColor Foreground Vivid Red] (showString "error") . showString ": " . showExpectation colourize errorExpected errorActual . showChar '\n' . withSGRCode colourize [SetColor Foreground Vivid Red] (showString "error") . showString ": " . showExpectation colourize errorExpected errorActual . showChar '\n'
. (if includeSource . (if includeSource then showExcerpt colourize errorSpan blob else id)
then showString (unpack context) . (if "\n" `isSuffixOf` context then id else showChar '\n')
. showString (replicate (succ (posColumn (spanStart errorSpan) + lineNumberDigits)) ' ') . withSGRCode colourize [SetColor Foreground Vivid Green] (showChar '^' . showChar '\n')
else id)
. showCallStack colourize callStack . showChar '\n' . showCallStack colourize callStack . showChar '\n'
where context = maybe "\n" (sourceBytes . sconcat) (nonEmpty [ fromUTF8 (pack (showLineNumber i)) <> fromUTF8 ": " <> l | (i, l) <- zip [1..] (sourceLines blobSource), inRange (posLine (spanStart errorSpan) - 2, posLine (spanStart errorSpan)) i ]) where
showLineNumber n = let s = show n in replicate (lineNumberDigits - length s) ' ' <> s
lineNumberDigits = succ (floor (logBase 10 (fromIntegral (posLine (spanStart errorSpan)) :: Double)))
path = Just $ if includeSource then blobPath else "<filtered>" path = Just $ if includeSource then blobPath else "<filtered>"
showExcerpt :: Colourize -> Span -> Blob -> ShowS
showExcerpt colourize Span{..} Blob{..}
= showString context . (if "\n" `isSuffixOf` context then id else showChar '\n')
. showString (replicate (caretPaddingWidth + lineNumberDigits) ' ') . withSGRCode colourize [SetColor Foreground Vivid Green] (showString caret) . showChar '\n'
where context = fold contextLines
contextLines = [ showLineNumber i <> ": " <> unpack (sourceBytes l)
| (i, l) <- zip [1..] (sourceLines blobSource)
, inRange (posLine spanStart - 2, posLine spanStart) i
]
showLineNumber n = let s = show n in replicate (lineNumberDigits - length s) ' ' <> s
lineNumberDigits = succ (floor (logBase 10 (fromIntegral (posLine spanStart) :: Double)))
caretPaddingWidth = succ (posColumn spanStart)
caret | posLine spanStart == posLine spanEnd = replicate (max 1 (posColumn spanEnd - posColumn spanStart)) '^'
| otherwise = "^..."
withSGRCode :: Colourize -> [SGR] -> ShowS -> ShowS withSGRCode :: Colourize -> [SGR] -> ShowS -> ShowS
withSGRCode useColour code content = withSGRCode useColour code content =
if useColour then if useColour then

View File

@ -8,6 +8,7 @@ module Semantic.Config
, debugOptions , debugOptions
, lookupStatsAddr , lookupStatsAddr
, withHaystackFromConfig , withHaystackFromConfig
, logOptionsFromConfig
, withLoggerFromConfig , withLoggerFromConfig
, withStatterFromConfig , withStatterFromConfig
, withTelemetry , withTelemetry
@ -93,13 +94,13 @@ withTelemetry config action =
withStatterFromConfig config $ \statter -> withStatterFromConfig config $ \statter ->
action (TelemetryQueues logger statter haystack) action (TelemetryQueues logger statter haystack)
withLoggerFromConfig :: Config -> (LogQueue -> IO c) -> IO c logOptionsFromConfig :: Config -> LogOptions
withLoggerFromConfig Config{..} = withLogger opts configMaxTelemetyQueueSize logOptionsFromConfig Config{..} = LogOptions
where opts = LogOptions { logOptionsLevel = optionsLogLevel configOptions { logOptionsLevel = optionsLogLevel configOptions
, logOptionsFormatter = configLogFormatter , logOptionsFormatter = configLogFormatter
, logOptionsContext = logOptionsContext' configIsTerminal , logOptionsContext = logOptionsContext' configIsTerminal
} }
logOptionsContext' = \case where logOptionsContext' = \case
False -> [ ("app", configAppName) False -> [ ("app", configAppName)
, ("pid", show configProcessID) , ("pid", show configProcessID)
, ("hostname", configHostName) , ("hostname", configHostName)
@ -108,6 +109,10 @@ withLoggerFromConfig Config{..} = withLogger opts configMaxTelemetyQueueSize
_ -> [] _ -> []
withLoggerFromConfig :: Config -> (LogQueue -> IO c) -> IO c
withLoggerFromConfig config = withLogger (logOptionsFromConfig config) (configMaxTelemetyQueueSize config)
withHaystackFromConfig :: Config -> Haystack.ErrorLogger -> (HaystackQueue -> IO c) -> IO c withHaystackFromConfig :: Config -> Haystack.ErrorLogger -> (HaystackQueue -> IO c) -> IO c
withHaystackFromConfig Config{..} errorLogger = withHaystackFromConfig Config{..} errorLogger =
withHaystack configHaystackURL tlsManagerSettings configAppName errorLogger configMaxTelemetyQueueSize withHaystack configHaystackURL tlsManagerSettings configAppName errorLogger configMaxTelemetyQueueSize

View File

@ -8,7 +8,7 @@ module Semantic.Graph
, GraphType(..) , GraphType(..)
, Graph , Graph
, Vertex , Vertex
, ImportGraphEff(..) , ConcreteEff(..)
, style , style
, parsePackage , parsePackage
, withTermSpans , withTermSpans
@ -41,6 +41,7 @@ import Data.Abstract.Package as Package
import Data.Abstract.Value.Abstract as Abstract import Data.Abstract.Value.Abstract as Abstract
import Data.Abstract.Value.Concrete as Concrete (Value, ValueError (..), runFunction, runValueErrorWith) import Data.Abstract.Value.Concrete as Concrete (Value, ValueError (..), runFunction, runValueErrorWith)
import Data.Abstract.Value.Type as Type import Data.Abstract.Value.Type as Type
import Data.Blob
import Data.Coerce import Data.Coerce
import Data.Graph import Data.Graph
import Data.Graph.Vertex (VertexDeclarationStrategy, VertexDeclarationWithStrategy) import Data.Graph.Vertex (VertexDeclarationStrategy, VertexDeclarationWithStrategy)
@ -66,11 +67,11 @@ runGraph :: forall effs. (Member Distribute effs, Member (Exc SomeException) eff
-> Eff effs (Graph Vertex) -> Eff effs (Graph Vertex)
runGraph ImportGraph _ project runGraph ImportGraph _ project
| SomeAnalysisParser parser lang <- someAnalysisParser (Proxy :: Proxy AnalysisClasses) (projectLanguage project) = do | SomeAnalysisParser parser lang <- someAnalysisParser (Proxy :: Proxy AnalysisClasses) (projectLanguage project) = do
package <- parsePackage parser project package <- fmap snd <$> parsePackage parser project
runImportGraphToModuleInfos lang package runImportGraphToModuleInfos lang package
runGraph CallGraph includePackages project runGraph CallGraph includePackages project
| SomeAnalysisParser parser lang <- someAnalysisParser (Proxy :: Proxy AnalysisClasses) (projectLanguage project) = do | SomeAnalysisParser parser lang <- someAnalysisParser (Proxy :: Proxy AnalysisClasses) (projectLanguage project) = do
package <- parsePackage parser project package <- fmap snd <$> parsePackage parser project
modules <- topologicalSort <$> runImportGraphToModules lang package modules <- topologicalSort <$> runImportGraphToModules lang package
runCallGraph lang includePackages modules package runCallGraph lang includePackages modules package
@ -122,8 +123,7 @@ runCallGraph lang includePackages modules package = do
. Hole.runDeref (Located.handleDeref Monovariant.handleDeref) . Hole.runDeref (Located.handleDeref Monovariant.handleDeref)
extractGraph <$> runEvaluator (runGraphAnalysis (evaluate lang analyzeModule analyzeTerm runAddressEffects Abstract.runFunction modules)) extractGraph <$> runEvaluator (runGraphAnalysis (evaluate lang analyzeModule analyzeTerm runAddressEffects Abstract.runFunction modules))
runImportGraphToModuleInfos :: forall effs lang term. runImportGraphToModuleInfos :: ( Declarations term
( Declarations term
, Evaluatable (Base term) , Evaluatable (Base term)
, FreeVariables term , FreeVariables term
, HasPrelude lang , HasPrelude lang
@ -138,8 +138,7 @@ runImportGraphToModuleInfos :: forall effs lang term.
runImportGraphToModuleInfos lang (package :: Package term) = runImportGraph lang package allModuleInfos runImportGraphToModuleInfos lang (package :: Package term) = runImportGraph lang package allModuleInfos
where allModuleInfos info = maybe (vertex (unknownModuleVertex info)) (foldMap (vertex . moduleVertex . moduleInfo)) (ModuleTable.lookup (modulePath info) (packageModules package)) where allModuleInfos info = maybe (vertex (unknownModuleVertex info)) (foldMap (vertex . moduleVertex . moduleInfo)) (ModuleTable.lookup (modulePath info) (packageModules package))
runImportGraphToModules :: forall effs lang term. runImportGraphToModules :: ( Declarations term
( Declarations term
, Evaluatable (Base term) , Evaluatable (Base term)
, FreeVariables term , FreeVariables term
, HasPrelude lang , HasPrelude lang
@ -154,8 +153,7 @@ runImportGraphToModules :: forall effs lang term.
runImportGraphToModules lang (package :: Package term) = runImportGraph lang package resolveOrLowerBound runImportGraphToModules lang (package :: Package term) = runImportGraph lang package resolveOrLowerBound
where resolveOrLowerBound info = maybe lowerBound (foldMap vertex) (ModuleTable.lookup (modulePath info) (packageModules package)) where resolveOrLowerBound info = maybe lowerBound (foldMap vertex) (ModuleTable.lookup (modulePath info) (packageModules package))
runImportGraph :: forall effs lang term vertex. runImportGraph :: ( Declarations term
( Declarations term
, Evaluatable (Base term) , Evaluatable (Base term)
, FreeVariables term , FreeVariables term
, HasPrelude lang , HasPrelude lang
@ -170,9 +168,10 @@ runImportGraph :: forall effs lang term vertex.
-> Eff effs (Graph vertex) -> Eff effs (Graph vertex)
runImportGraph lang (package :: Package term) f = runImportGraph lang (package :: Package term) f =
let analyzeModule = graphingModuleInfo let analyzeModule = graphingModuleInfo
extractGraph (_, (graph, _)) = graph >>= f extractGraph (graph, _) = graph >>= f
runImportGraphAnalysis runImportGraphAnalysis
= runState lowerBound = runState lowerBound
. runState lowerBound
. runFresh 0 . runFresh 0
. resumingLoadError . resumingLoadError
. resumingUnspecialized . resumingUnspecialized
@ -181,10 +180,9 @@ runImportGraph lang (package :: Package term) f =
. resumingResolutionError . resumingResolutionError
. resumingAddressError . resumingAddressError
. resumingValueError . resumingValueError
. runState lowerBound
. runReader lowerBound . runReader lowerBound
. runModules (ModuleTable.modulePaths (packageModules package)) . runModules (ModuleTable.modulePaths (packageModules package))
. runTermEvaluator @_ @_ @(Value (Hole (Maybe Name) Precise) (ImportGraphEff (Hole (Maybe Name) Precise) effs)) . runTermEvaluator @_ @_ @(Value (Hole (Maybe Name) Precise) (ConcreteEff (Hole (Maybe Name) Precise) _))
. runReader (packageInfo package) . runReader (packageInfo package)
. runReader lowerBound . runReader lowerBound
runAddressEffects runAddressEffects
@ -192,30 +190,26 @@ runImportGraph lang (package :: Package term) f =
. Hole.runDeref Precise.handleDeref . Hole.runDeref Precise.handleDeref
in extractGraph <$> runEvaluator (runImportGraphAnalysis (evaluate lang analyzeModule id runAddressEffects (Concrete.runFunction coerce coerce) (ModuleTable.toPairs (packageModules package) >>= toList . snd))) in extractGraph <$> runEvaluator (runImportGraphAnalysis (evaluate lang analyzeModule id runAddressEffects (Concrete.runFunction coerce coerce) (ModuleTable.toPairs (packageModules package) >>= toList . snd)))
newtype ImportGraphEff address outerEffects a = ImportGraphEff type ConcreteEffects address rest
{ runImportGraphEff :: Eff ( Function address (Value address (ImportGraphEff address outerEffects)) = Reader Span
': Exc (LoopControl address)
': Exc (Return address)
': Env address
': Deref (Value address (ImportGraphEff address outerEffects))
': Allocator address
': Reader ModuleInfo
': Reader Span
': Reader PackageInfo ': Reader PackageInfo
': Modules address ': Modules address
': Reader (ModuleTable (NonEmpty (Module (ModuleResult address)))) ': Reader (ModuleTable (NonEmpty (Module (ModuleResult address))))
': State (Graph ModuleInfo) ': Resumable (BaseError (ValueError address (ConcreteEff address rest)))
': Resumable (BaseError (ValueError address (ImportGraphEff address outerEffects))) ': Resumable (BaseError (AddressError address (Value address (ConcreteEff address rest))))
': Resumable (BaseError (AddressError address (Value address (ImportGraphEff address outerEffects))))
': Resumable (BaseError ResolutionError) ': Resumable (BaseError ResolutionError)
': Resumable (BaseError EvalError) ': Resumable (BaseError EvalError)
': Resumable (BaseError (EnvironmentError address)) ': Resumable (BaseError (EnvironmentError address))
': Resumable (BaseError (UnspecializedError (Value address (ImportGraphEff address outerEffects)))) ': Resumable (BaseError (UnspecializedError (Value address (ConcreteEff address rest))))
': Resumable (BaseError (LoadError address)) ': Resumable (BaseError (LoadError address))
': Fresh ': Fresh
': State (Heap address (Value address (ImportGraphEff address outerEffects))) ': State (Heap address (Value address (ConcreteEff address rest)))
': outerEffects ': rest
) a
newtype ConcreteEff address outerEffects a = ConcreteEff
{ runConcreteEff :: Eff (ValueEffects address (Value address (ConcreteEff address outerEffects))
(ModuleEffects address (Value address (ConcreteEff address outerEffects))
(ConcreteEffects address outerEffects))) a
} }
@ -223,8 +217,8 @@ newtype ImportGraphEff address outerEffects a = ImportGraphEff
parsePackage :: (Member Distribute effs, Member (Exc SomeException) effs, Member Resolution effs, Member Task effs, Member Trace effs) parsePackage :: (Member Distribute effs, Member (Exc SomeException) effs, Member Resolution effs, Member Task effs, Member Trace effs)
=> Parser term -- ^ A parser. => Parser term -- ^ A parser.
-> Project -- ^ Project to parse into a package. -> Project -- ^ Project to parse into a package.
-> Eff effs (Package term) -> Eff effs (Package (Blob, term))
parsePackage parser project@Project{..} = do parsePackage parser project = do
p <- parseModules parser project p <- parseModules parser project
resMap <- Task.resolutionMap project resMap <- Task.resolutionMap project
let pkg = Package.fromModules n p resMap let pkg = Package.fromModules n p resMap
@ -233,16 +227,12 @@ parsePackage parser project@Project{..} = do
where where
n = name (projectName project) n = name (projectName project)
-- | Parse all files in a project into 'Module's. parseModules parser p = distributeFor (projectFiles p) (parseModule p parser)
parseModules :: (Member Distribute effs, Member (Exc SomeException) effs, Member Task effs) => Parser term -> Project -> Eff effs [Module term]
parseModules parser p@Project{..} = distributeFor (projectFiles p) (parseModule p parser)
-- | Parse a file into a 'Module'.
parseModule :: (Member (Exc SomeException) effs, Member Task effs) => Project -> Parser term -> File -> Eff effs (Module term)
parseModule proj parser file = do parseModule proj parser file = do
mBlob <- readFile proj file mBlob <- readFile proj file
case mBlob of case mBlob of
Just blob -> moduleForBlob (Just (projectRootDir proj)) blob <$> parse parser blob Just blob -> moduleForBlob (Just (projectRootDir proj)) blob . (,) blob <$> parse parser blob
Nothing -> throwError (SomeException (FileNotFound (filePath file))) Nothing -> throwError (SomeException (FileNotFound (filePath file)))
withTermSpans :: ( HasField fields Span withTermSpans :: ( HasField fields Span

210
src/Semantic/REPL.hs Normal file
View File

@ -0,0 +1,210 @@
{-# LANGUAGE GADTs, KindSignatures, LambdaCase, TypeOperators #-}
{-# OPTIONS_GHC -Wno-missing-signatures #-}
module Semantic.REPL
( rubyREPL
) where
import Control.Abstract hiding (Continue, List, string)
import Control.Monad.IO.Class
import Data.Abstract.Address.Precise as Precise
import Data.Abstract.Environment as Env
import Data.Abstract.Evaluatable hiding (string)
import Data.Abstract.Module
import Data.Abstract.ModuleTable as ModuleTable
import Data.Abstract.Package
import Data.Abstract.Value.Concrete as Concrete
import Data.Blob (Blob(..))
import Data.Coerce
import Data.Error (showExcerpt)
import Data.Graph (topologicalSort)
import Data.Language as Language
import Data.List (uncons)
import Data.Project
import Data.Quieterm
import Data.Span
import qualified Data.Time.Clock.POSIX as Time (getCurrentTime)
import qualified Data.Time.LocalTime as LocalTime
import Numeric (readDec)
import Parsing.Parser (rubyParser)
import Prologue hiding (throwError)
import Semantic.Config (logOptionsFromConfig)
import Semantic.Distribute
import Semantic.Graph
import Semantic.IO as IO
import Semantic.Resolution
import Semantic.Task hiding (Error)
import Semantic.Telemetry
import Semantic.Telemetry.Log (LogOptions, Message(..), writeLogMessage)
import Semantic.Util
import System.Console.Haskeline
import System.Directory (createDirectoryIfMissing, getHomeDirectory)
import System.FilePath
data REPL (m :: * -> *) result where
Prompt :: REPL m (Maybe String)
Output :: String -> REPL m ()
prompt :: (Effectful m, Member REPL effects) => m effects (Maybe String)
prompt = send Prompt
output :: (Effectful m, Member REPL effects) => String -> m effects ()
output s = send (Output s)
data Quit = Quit
deriving Show
instance Exception Quit
instance PureEffect REPL
instance Effect REPL where
handleState state handler (Request Prompt k) = Request Prompt (handler . (<$ state) . k)
handleState state handler (Request (Output s) k) = Request (Output s) (handler . (<$ state) . k)
runREPL :: (Effectful m, MonadIO (m effects), PureEffects effects) => Prefs -> Settings IO -> m (REPL ': effects) a -> m effects a
runREPL prefs settings = interpret $ \case
Prompt -> liftIO (runInputTWithPrefs prefs settings (getInputLine (cyan <> "repl: " <> plain)))
Output s -> liftIO (runInputTWithPrefs prefs settings (outputStrLn s))
rubyREPL = repl (Proxy @'Language.Ruby) rubyParser
repl proxy parser paths = defaultConfig debugOptions >>= \ config -> runM . runDistribute . runError @_ @_ @SomeException . runTelemetryIgnoringStat (logOptionsFromConfig config) . runTraceInTelemetry . runReader config . IO.runFiles . runResolution . runTaskF $ do
blobs <- catMaybes <$> traverse IO.readFile (flip File (Language.reflect proxy) <$> paths)
package <- fmap (fmap quieterm) <$> parsePackage parser (Project (takeDirectory (maybe "/" fst (uncons paths))) blobs (Language.reflect proxy) [])
modules <- topologicalSort <$> runImportGraphToModules proxy (snd <$> package)
homeDir <- liftIO getHomeDirectory
prefs <- liftIO (readPrefs (homeDir <> "/.haskeline"))
let settingsDir = homeDir <> "/.local/semantic"
liftIO $ createDirectoryIfMissing True settingsDir
let settings = Settings
{ complete = noCompletion
, historyFile = Just (settingsDir <> "/repl_history")
, autoAddHistory = True
}
runEvaluator
. runREPL prefs settings
. fmap snd
. runState ([] @Breakpoint)
. runReader Step
. runTermEvaluator @_ @_ @(Value Precise (ConcreteEff Precise _))
. runPrintingTrace
. runState lowerBound
. runFresh 0
. fmap reassociate
. runLoadError
. runUnspecialized
. runEnvironmentError
. runEvalError
. runResolutionError
. runAddressError
. runValueError
. runReader (lowerBound @(ModuleTable (NonEmpty (Module (ModuleResult Precise)))))
. raiseHandler (runModules (ModuleTable.modulePaths (packageModules (snd <$> package))))
. runReader (packageInfo package)
. runReader (lowerBound @Span)
$ evaluate proxy id (withTermSpans . step (fmap (\ (x:|_) -> moduleBody x) <$> ModuleTable.toPairs (packageModules (fst <$> package)))) (Precise.runAllocator . Precise.runDeref) (Concrete.runFunction coerce coerce) modules
-- TODO: REPL for typechecking/abstract semantics
-- TODO: drive the flow from within the REPL instead of from without
runTelemetryIgnoringStat :: (Effectful m, MonadIO (m effects), PureEffects effects) => LogOptions -> m (Telemetry : effects) a -> m effects a
runTelemetryIgnoringStat logOptions = interpret $ \case
WriteStat{} -> pure ()
WriteLog level message pairs -> do
time <- liftIO Time.getCurrentTime
zonedTime <- liftIO (LocalTime.utcToLocalZonedTime time)
writeLogMessage logOptions (Message level message pairs zonedTime)
step :: ( Member (Env address) effects
, Member (Exc SomeException) effects
, Member REPL effects
, Member (Reader ModuleInfo) effects
, Member (Reader Span) effects
, Member (Reader Step) effects
, Member (State [Breakpoint]) effects
, Show address
)
=> [(ModulePath, Blob)]
-> SubtermAlgebra (Base term) term (TermEvaluator term address value effects a)
-> SubtermAlgebra (Base term) term (TermEvaluator term address value effects a)
step blobs recur term = do
break <- shouldBreak
if break then do
list
runCommands (recur term)
else
recur term
where list = do
path <- asks modulePath
span <- ask
maybe (pure ()) (\ blob -> output (showExcerpt True span blob "")) (Prelude.lookup path blobs)
help = do
output "Commands available from the prompt:"
output ""
output " :help, :? display this list of commands"
output " :list show the source code around current breakpoint"
output " :step single-step after stopping at a breakpoint"
output " :continue continue evaluation until the next breakpoint"
output " :show bindings show the current bindings"
output " :quit, :q, :abandon abandon the current evaluation and exit the repl"
showBindings = do
bindings <- Env.head <$> TermEvaluator getEnv
output $ unlines (uncurry showBinding <$> Env.pairs bindings)
showBinding name addr = show name <> " = " <> show addr
runCommand run [":step"] = local (const Step) run
runCommand run [":continue"] = local (const Continue) run
runCommand run [":break", s]
| [(i, "")] <- readDec s = modify' (OnLine i :) >> runCommands run
-- TODO: :show breakpoints
-- TODO: :delete breakpoints
runCommand run [":list"] = list >> runCommands run
runCommand run [":show", "bindings"] = showBindings >> runCommands run
-- TODO: show the value(s) in the heap
-- TODO: can we call functions somehow? Maybe parse expressions with the current parser?
runCommand _ [quit] | quit `elem` [":quit", ":q", ":abandon"] = throwError (SomeException Quit)
runCommand run [":help"] = help >> runCommands run
runCommand run [":?"] = help >> runCommands run
runCommand run [] = runCommands run
runCommand run other = output ("unknown command '" <> unwords other <> "'") >> output "use :? for help" >> runCommands run
runCommands run = do
str <- prompt
maybe (runCommands run) (runCommand run . words) str
newtype Breakpoint
= OnLine Int
deriving Show
-- FIXME: OnLine should take a module, defaulting to the current module
-- TODO: OnPos, taking a column number as well as line number and module
-- TODO: OnSymbol, taking a function/method name? This could be tricky to implement cross-language
data Step
= Step
| Continue
deriving Show
-- TODO: StepLocal/StepModule
shouldBreak :: (Member (State [Breakpoint]) effects, Member (Reader Span) effects, Member (Reader Step) effects) => TermEvaluator term address value effects Bool
shouldBreak = do
step <- ask
case step of
Step -> pure True
Continue -> do
breakpoints <- get
span <- ask
pure (any @[] (matching span) breakpoints)
where matching Span{..} (OnLine n)
| n >= posLine spanStart
, n <= posLine spanEnd = True
| otherwise = False
cyan :: String
cyan = "\ESC[1;36m\STX"
plain :: String
plain = "\ESC[0m\STX"

View File

@ -39,6 +39,8 @@ module Semantic.Task
, runTaskWithOptions , runTaskWithOptions
, withOptions , withOptions
, runTaskWithConfig , runTaskWithConfig
, runTraceInTelemetry
, runTaskF
-- * Re-exports -- * Re-exports
, Distribute , Distribute
, Eff , Eff

View File

@ -42,7 +42,7 @@ module Semantic.Telemetry
, writeLog , writeLog
, writeStat , writeStat
, time , time
, Telemetry , Telemetry(..)
, runTelemetry , runTelemetry
, ignoreTelemetry , ignoreTelemetry
) where ) where

View File

@ -14,7 +14,6 @@ import Control.Exception (displayException)
import Control.Monad.Effect.Trace (runPrintingTrace) import Control.Monad.Effect.Trace (runPrintingTrace)
import Data.Abstract.Address.Monovariant as Monovariant import Data.Abstract.Address.Monovariant as Monovariant
import Data.Abstract.Address.Precise as Precise import Data.Abstract.Address.Precise as Precise
import Data.Abstract.BaseError (BaseError (..))
import Data.Abstract.Evaluatable import Data.Abstract.Evaluatable
import Data.Abstract.Module import Data.Abstract.Module
import qualified Data.Abstract.ModuleTable as ModuleTable import qualified Data.Abstract.ModuleTable as ModuleTable
@ -56,9 +55,9 @@ import Text.Show.Pretty (ppShow)
justEvaluating justEvaluating
= runM = runM
. runPrintingTrace
. runState lowerBound . runState lowerBound
. runFresh 0 . runFresh 0
. runPrintingTrace
. fmap reassociate . fmap reassociate
. runLoadError . runLoadError
. runUnspecialized . runUnspecialized
@ -68,37 +67,11 @@ justEvaluating
. runAddressError . runAddressError
. runValueError . runValueError
newtype UtilEff a = UtilEff
{ runUtilEff :: Eff '[ Function Precise (Value Precise UtilEff)
, Exc (LoopControl Precise)
, Exc (Return Precise)
, Env Precise
, Deref (Value Precise UtilEff)
, Allocator Precise
, Reader ModuleInfo
, Modules Precise
, Reader (ModuleTable (NonEmpty (Module (ModuleResult Precise))))
, Reader Span
, Reader PackageInfo
, Resumable (BaseError (ValueError Precise UtilEff))
, Resumable (BaseError (AddressError Precise (Value Precise UtilEff)))
, Resumable (BaseError ResolutionError)
, Resumable (BaseError EvalError)
, Resumable (BaseError (EnvironmentError Precise))
, Resumable (BaseError (UnspecializedError (Value Precise UtilEff)))
, Resumable (BaseError (LoadError Precise))
, Trace
, Fresh
, State (Heap Precise (Value Precise UtilEff))
, Lift IO
] a
}
checking checking
= runM @_ @IO = runM @_ @IO
. runPrintingTrace
. runState (lowerBound @(Heap Monovariant Type)) . runState (lowerBound @(Heap Monovariant Type))
. runFresh 0 . runFresh 0
. runPrintingTrace
. runTermEvaluator @_ @Monovariant @Type . runTermEvaluator @_ @Monovariant @Type
. caching . caching
. providingLiveSet . providingLiveSet
@ -112,7 +85,7 @@ checking
. runTypes . runTypes
evalGoProject = justEvaluating <=< evaluateProject (Proxy :: Proxy 'Language.Go) goParser evalGoProject = justEvaluating <=< evaluateProject (Proxy :: Proxy 'Language.Go) goParser
evalRubyProject = justEvaluating <=< evaluateProject (Proxy :: Proxy 'Language.Ruby) rubyParser evalRubyProject = justEvaluating <=< evaluateProject (Proxy @'Language.Ruby) rubyParser
evalPHPProject = justEvaluating <=< evaluateProject (Proxy :: Proxy 'Language.PHP) phpParser evalPHPProject = justEvaluating <=< evaluateProject (Proxy :: Proxy 'Language.PHP) phpParser
evalPythonProject = justEvaluating <=< evaluateProject (Proxy :: Proxy 'Language.Python) pythonParser evalPythonProject = justEvaluating <=< evaluateProject (Proxy :: Proxy 'Language.Python) pythonParser
evalJavaScriptProject = justEvaluating <=< evaluateProject (Proxy :: Proxy 'Language.JavaScript) typescriptParser evalJavaScriptProject = justEvaluating <=< evaluateProject (Proxy :: Proxy 'Language.JavaScript) typescriptParser
@ -123,7 +96,7 @@ typecheckRubyFile = checking <=< evaluateProjectWithCaching (Proxy :: Proxy 'Lan
callGraphProject parser proxy opts paths = runTaskWithOptions opts $ do callGraphProject parser proxy opts paths = runTaskWithOptions opts $ do
blobs <- catMaybes <$> traverse readFile (flip File (Language.reflect proxy) <$> paths) blobs <- catMaybes <$> traverse readFile (flip File (Language.reflect proxy) <$> paths)
package <- parsePackage parser (Project (takeDirectory (maybe "/" fst (uncons paths))) blobs (Language.reflect proxy) []) package <- fmap snd <$> parsePackage parser (Project (takeDirectory (maybe "/" fst (uncons paths))) blobs (Language.reflect proxy) [])
modules <- topologicalSort <$> runImportGraphToModules proxy package modules <- topologicalSort <$> runImportGraphToModules proxy package
x <- runCallGraph proxy False modules package x <- runCallGraph proxy False modules package
pure (x, (() <$) <$> modules) pure (x, (() <$) <$> modules)
@ -139,20 +112,20 @@ data TaskConfig = TaskConfig Config LogQueue StatQueue
evaluateProject' (TaskConfig config logger statter) proxy parser paths = either (die . displayException) pure <=< runTaskWithConfig config logger statter $ do evaluateProject' (TaskConfig config logger statter) proxy parser paths = either (die . displayException) pure <=< runTaskWithConfig config logger statter $ do
blobs <- catMaybes <$> traverse readFile (flip File (Language.reflect proxy) <$> paths) blobs <- catMaybes <$> traverse readFile (flip File (Language.reflect proxy) <$> paths)
package <- fmap quieterm <$> parsePackage parser (Project (takeDirectory (maybe "/" fst (uncons paths))) blobs (Language.reflect proxy) []) package <- fmap (quieterm . snd) <$> parsePackage parser (Project (takeDirectory (maybe "/" fst (uncons paths))) blobs (Language.reflect proxy) [])
modules <- topologicalSort <$> runImportGraphToModules proxy package modules <- topologicalSort <$> runImportGraphToModules proxy package
trace $ "evaluating with load order: " <> show (map (modulePath . moduleInfo) modules) trace $ "evaluating with load order: " <> show (map (modulePath . moduleInfo) modules)
pure (runTermEvaluator @_ @_ @(Value Precise UtilEff) pure (runTermEvaluator @_ @_ @(Value Precise (ConcreteEff Precise _))
(runReader (packageInfo package)
(runReader (lowerBound @Span)
(runReader (lowerBound @(ModuleTable (NonEmpty (Module (ModuleResult Precise))))) (runReader (lowerBound @(ModuleTable (NonEmpty (Module (ModuleResult Precise)))))
(raiseHandler (runModules (ModuleTable.modulePaths (packageModules package))) (raiseHandler (runModules (ModuleTable.modulePaths (packageModules package)))
(runReader (packageInfo package)
(runReader (lowerBound @Span)
(evaluate proxy id withTermSpans (Precise.runAllocator . Precise.runDeref) (Concrete.runFunction coerce coerce) modules)))))) (evaluate proxy id withTermSpans (Precise.runAllocator . Precise.runDeref) (Concrete.runFunction coerce coerce) modules))))))
evaluateProjectWithCaching proxy parser path = runTaskWithOptions debugOptions $ do evaluateProjectWithCaching proxy parser path = runTaskWithOptions debugOptions $ do
project <- readProject Nothing path (Language.reflect proxy) [] project <- readProject Nothing path (Language.reflect proxy) []
package <- fmap quieterm <$> parsePackage parser project package <- fmap (quieterm . snd) <$> parsePackage parser project
modules <- topologicalSort <$> runImportGraphToModules proxy package modules <- topologicalSort <$> runImportGraphToModules proxy package
pure (runReader (packageInfo package) pure (runReader (packageInfo package)
(runReader (lowerBound @Span) (runReader (lowerBound @Span)

View File

@ -1,7 +1,6 @@
{-# LANGUAGE TypeOperators #-} {-# LANGUAGE TypeOperators #-}
module Control.Abstract.Evaluator.Spec module Control.Abstract.Evaluator.Spec
( spec ( spec
, SpecEff(..)
) where ) where
import Control.Abstract import Control.Abstract

View File

@ -11,18 +11,7 @@ module Data.Functor.Listable
, cons5 , cons5
, cons6 , cons6
, (\/) , (\/)
, Tier
, Listable1(..)
, tiers1
, Listable2(..)
, tiers2
, liftCons1
, liftCons2
, liftCons3
, liftCons4
, liftCons5
, ListableF(..) , ListableF(..)
, ListableF2(..)
, addWeight , addWeight
, ofWeight , ofWeight
, ListableSyntax , ListableSyntax

View File

@ -22,7 +22,7 @@ callGraphPythonProject paths = runTaskWithOptions defaultOptions $ do
let proxy = Proxy @'Language.Python let proxy = Proxy @'Language.Python
let lang = Language.Python let lang = Language.Python
blobs <- catMaybes <$> traverse readFile (flip File lang <$> paths) blobs <- catMaybes <$> traverse readFile (flip File lang <$> paths)
package <- parsePackage pythonParser (Project (takeDirectory (maybe "/" fst (uncons paths))) blobs lang []) package <- fmap snd <$> parsePackage pythonParser (Project (takeDirectory (maybe "/" fst (uncons paths))) blobs lang [])
modules <- topologicalSort <$> runImportGraphToModules proxy package modules <- topologicalSort <$> runImportGraphToModules proxy package
runCallGraph proxy False modules package runCallGraph proxy False modules package

View File

@ -73,6 +73,7 @@ import qualified Data.ByteString as B
import qualified Data.Set as Set import qualified Data.Set as Set
import qualified Semantic.IO as IO import qualified Semantic.IO as IO
import Semantic.Config (Config) import Semantic.Config (Config)
import Semantic.Graph (ConcreteEff)
import Semantic.Telemetry (LogQueue, StatQueue) import Semantic.Telemetry (LogQueue, StatQueue)
import System.Exit (die) import System.Exit (die)
import Control.Exception (displayException) import Control.Exception (displayException)
@ -97,19 +98,19 @@ readFilePair :: Both FilePath -> IO BlobPair
readFilePair paths = let paths' = fmap file paths in readFilePair paths = let paths' = fmap file paths in
runBothWith IO.readFilePair paths' runBothWith IO.readFilePair paths'
type TestEvaluatingEffects = '[ Resumable (BaseError (ValueError Precise UtilEff)) type TestEvaluatingEffects = '[ Resumable (BaseError (ValueError Precise (ConcreteEff Precise '[Trace, Lift IO])))
, Resumable (BaseError (AddressError Precise Val)) , Resumable (BaseError (AddressError Precise Val))
, Resumable (BaseError ResolutionError) , Resumable (BaseError ResolutionError)
, Resumable (BaseError EvalError) , Resumable (BaseError EvalError)
, Resumable (BaseError (EnvironmentError Precise)) , Resumable (BaseError (EnvironmentError Precise))
, Resumable (BaseError (UnspecializedError Val)) , Resumable (BaseError (UnspecializedError Val))
, Resumable (BaseError (LoadError Precise)) , Resumable (BaseError (LoadError Precise))
, Trace
, Fresh , Fresh
, State (Heap Precise Val) , State (Heap Precise Val)
, Trace
, Lift IO , Lift IO
] ]
type TestEvaluatingErrors = '[ BaseError (ValueError Precise UtilEff) type TestEvaluatingErrors = '[ BaseError (ValueError Precise (ConcreteEff Precise '[Trace, Lift IO]))
, BaseError (AddressError Precise Val) , BaseError (AddressError Precise Val)
, BaseError ResolutionError , BaseError ResolutionError
, BaseError EvalError , BaseError EvalError
@ -127,10 +128,9 @@ testEvaluating :: Evaluator Precise Val TestEvaluatingEffects (ModuleTable (NonE
) )
testEvaluating testEvaluating
= runM = runM
. fmap (\ (heap, (traces, res)) -> (traces, (heap, res))) . runReturningTrace
. runState lowerBound . runState lowerBound
. runFresh 0 . runFresh 0
. runReturningTrace
. fmap reassociate . fmap reassociate
. runLoadError . runLoadError
. runUnspecialized . runUnspecialized
@ -138,9 +138,9 @@ testEvaluating
. runEvalError . runEvalError
. runResolutionError . runResolutionError
. runAddressError . runAddressError
. runValueError @_ @Precise @UtilEff . runValueError @_ @Precise @(ConcreteEff Precise _)
type Val = Value Precise UtilEff type Val = Value Precise (ConcreteEff Precise '[Trace, Lift IO])
deNamespace :: Heap Precise (Value Precise term) deNamespace :: Heap Precise (Value Precise term)