Skip to content

Commit

Permalink
frege-repl-16 Fix Frege/frege-repl#16 issue with infix operators
Browse files Browse the repository at this point in the history
  • Loading branch information
mmhelloworld committed Dec 12, 2014
1 parent ef03dc4 commit edaacc7
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -290,11 +290,9 @@ symbolClass symbol g = g.unpack symbol.name.getpack
* until one of them returns an error
-}
run src predefs steps = do
g <- getST
let scriptType = findScriptType src
let scriptType = findSourceType src predefs
varName = findUnusedVariableName (predefs ++ src)
source = buildScript src scriptType predefs "Console" varName
changeST $ const g
changeST Global.{gen <- GenSt.{printer=IO.stdout}} -- just to have no undefined value there
foreach (steps source) runpass
g <- getST
Expand All @@ -306,6 +304,35 @@ run src predefs steps = do
sym = fst $ StG.run (resolveSymbol varName) g
else return Nothing

findSourceType :: String -> String -> SourceType
findSourceType src predefs =
case calcSourceType src of
Just ModuleSource -> SourceType.ModuleSource
Just ExpressionSource -> SourceType.ExpressionSource
otherwise -> case calcSourceType (buildScript src SourceType.DefinitionsSource predefs "T" "") of
Just ModuleSource -> SourceType.DefinitionsSource
_ -> SourceType.ExpressionSource
where
calcSourceType src = fst $ StG.run (calculateSourceTypeST src) env
env = interpreterCompilerEnv InterpreterClassLoader.default

calculateSourceTypeST :: String -> StG (Maybe SourceType)
calculateSourceTypeST src = do
g <- getST
pw <- doio $ StringWriter.new () >>= StringWriter.printer
changeST Global.{sub <- SubSt.{stderr=pw}}
runpass (lexPass src, "lexical analysis ", postTrue)
g <- getST
if g.errors != 0
then return Nothing
else do
let tokens = filter noDocComment g.sub.toks.toList
result <- Parse.pass tokens
case result of
Nothing -> return Nothing
Just (GUtil.Program.Module _) -> return (Just SourceType.ModuleSource)
_ -> return (Just SourceType.ExpressionSource)

{-
Compiler state with interpreter options
There is no IO; The classes are loaded in memory.
Expand Down Expand Up @@ -371,27 +398,6 @@ instance Show SourceInfo where
show (Expression _) = "Expression"
show (Definitions _) = "Definitions"

findScriptType :: String -> SourceType
findScriptType src = fst $ StG.run f (interpreterCompilerEnv InterpreterClassLoader.default) where
f = do
runpass (lexPass src, "lexical analysis ", postTrue)
g <- getST
if g.errors == 0
then scriptTypePass src
else return SourceType.ModuleSource

scriptTypePass src = do
g <- getST
let tokens = filter noDocComment g.sub.toks.toList
case tokens of
[] -> return SourceType.ModuleSource
(Token{tokid=PACKAGE}) : _ -> return SourceType.ModuleSource
_ -> do
isDef <- isDefinition src
if isDef
then return SourceType.DefinitionsSource
else return SourceType.ExpressionSource

noDocComment Token{tokid} = tokid != COMMENT && tokid != DOCUMENTATION

moduleDeclScript moduleName = "module " ++ moduleName ++ " where"
Expand Down Expand Up @@ -571,23 +577,6 @@ iparsePass f = do
indent n src = (unlines . map (spaces ++) . lines $ src) where
spaces = concat $ replicate n " "

isDefinition :: String -> StG Bool
isDefinition src = do
g <- getST
sw <- doio $ StringWriter.new ()
pw <- doio $ sw.printer
let modDecl = intercalate newLine ["module T where", src]
changeST Global.{sub <- SubSt.{stderr=pw}}
runpass (lexPass modDecl, "lexical analysis ", postTrue)
g <- getST
if g.errors != 0
then return false
else do
let tokens = filter noDocComment g.sub.toks.toList
result <- Parse.pass tokens
g <- getST
return $ g.errors == 0

lexPass src = do
changeST Global.{sub <- SubSt.{toks = arrayFromList []}
. SubSt.{definitions = []}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@
import javax.script.ScriptException;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestRule;
import org.junit.rules.TestWatcher;
import org.junit.runner.Description;

import java.math.BigInteger;

Expand Down Expand Up @@ -93,4 +97,29 @@ public void testUnpackagedModule() throws ScriptException {
final Object expected = "I am bar";
assertEquals(expected, actual);
}

@Test
public void testOperators() throws ScriptException {
frege.eval("infix 1 `³`");
frege.eval("(x³) = x^3");
final Object expected = frege.eval("(2³)");
final Object actual = 8;
assertEquals(expected, actual);
}

@Test
public void testImportOperators() throws ScriptException {
frege.eval("import Data.Monoid");
frege.eval("import frege.data.wrapper.Num");
final Object expected = frege.eval("Sum.unwrap $ Sum 1 <> Sum 0");
final Object actual = 1;
assertEquals(expected, actual);
}

@Test
public void testTypeAnnotation() throws ScriptException {
final Object expected = frege.eval("(one :: Int)");
final Object actual = 1;
assertEquals(expected, actual);
}
}
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
Expand Down

0 comments on commit edaacc7

Please sign in to comment.